- "package/boot/arm-trusted-firmware-bcm63xx/**"
"target/bmips":
- "target/linux/bmips/**"
+ - "package/boot/uboot-bmips/**"
"target/d1":
- "target/linux/d1/**"
- "package/boot/uboot-d1/**"
default y
config GRUB_EFI_IMAGES
- bool "Build GRUB EFI images (Linux x86 or x86_64 host only)"
- depends on TARGET_x86 || TARGET_armsr
+ bool "Build GRUB EFI images"
+ depends on TARGET_x86 || TARGET_armsr || TARGET_loongarch64
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
select PACKAGE_grub2 if TARGET_x86
select PACKAGE_grub2-efi if TARGET_x86
select PACKAGE_grub2-bios-setup if TARGET_x86
select PACKAGE_grub2-efi-arm if TARGET_armsr
+ select PACKAGE_grub2-efi-loongarch64 if TARGET_loongarch64
select PACKAGE_kmod-fs-vfat
default y
config TARGET_SERIAL
string "Serial port device"
- depends on TARGET_x86 || TARGET_armsr
+ depends on TARGET_x86 || TARGET_armsr || TARGET_loongarch64
default "ttyS0"
config TARGET_IMAGES_GZIP
bool "GZip images"
- depends on TARGET_ROOTFS_EXT4FS || TARGET_x86 || TARGET_armsr || TARGET_malta
+ depends on TARGET_ROOTFS_EXT4FS || TARGET_x86 || TARGET_armsr || TARGET_malta || TARGET_loongarch64
default y
comment "Image Options"
config TARGET_ROOTFS_PARTSIZE
int "Root filesystem partition size (in MiB)"
depends on USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS
+ default 232 if TARGET_loongarch64
+ default 448 if TARGET_mediatek
default 104
help
Select the root filesystem partition size.
default y if TARGET_armsr_armv8
depends on (arm || aarch64)
+config KERNEL_ARM_PMUV3
+ bool
+ default y if TARGET_armsr_armv8
+ depends on (arm_v7 || aarch64) && LINUX_6_6
+
config KERNEL_RISCV_PMU
bool
select KERNEL_RISCV_PMU_SBI
config KERNEL_PERF_EVENTS
bool "Compile the kernel with performance events and counters"
select KERNEL_ARM_PMU if (arm || aarch64)
+ select KERNEL_ARM_PMUV3 if (arm_v7 || aarch64) && LINUX_6_6
select KERNEL_RISCV_PMU if riscv64
config KERNEL_PROFILING
BPF_HEADERS_DIR:=$(STAGING_DIR)/bpf-headers
BPF_KERNEL_INCLUDE := \
- -nostdinc -isystem $(TOOLCHAIN_INC_DIRS) \
+ -nostdinc $(patsubst %,-isystem %,$(TOOLCHAIN_INC_DIRS)) \
-I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include \
-I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/asm/mach-generic \
-I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/generated \
-I$(DTS_DIR) \
-I$(DTS_DIR)/include \
-I$(LINUX_DIR)/include/ \
+ -I$(LINUX_DIR)/scripts/dtc/include-prefixes \
-undef -D__DTS__ $(3) \
-o $(2).tmp $(1)
$(LINUX_DIR)/scripts/dtc/dtc -O dtb \
define Image/Manifest
$(call opkg,$(TARGET_DIR_ORIG)) list-installed > \
$(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED)).manifest
-ifndef IB
- $(if $(CONFIG_JSON_CYCLONEDX_SBOM), \
- $(SCRIPT_DIR)/package-metadata.pl imgcyclonedxsbom \
- $(TMP_DIR)/.packageinfo \
+ifneq ($(CONFIG_JSON_CYCLONEDX_SBOM),)
+ $(SCRIPT_DIR)/package-metadata.pl imgcyclonedxsbom \
+ $(if $(IB),$(TOPDIR)/.packageinfo, $(TMP_DIR)/.packageinfo) \
$(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED)).manifest > \
- $(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED)).bom.cdx.json)
+ $(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED)).bom.cdx.json
endif
endef
-LINUX_VERSION-5.15 = .155
-LINUX_KERNEL_HASH-5.15.155 = c85859b86d2e6d1fc91ca1be8b44f24a9b5bb9f86869b04a8665a3a6559126e4
+LINUX_VERSION-5.15 = .158
+LINUX_KERNEL_HASH-5.15.158 = f9071c83a4fd8b80af026b48cfc1869bfa25883f9148b92b5dc1e1e1e26dd5c6
-LINUX_VERSION-6.1 = .86
-LINUX_KERNEL_HASH-6.1.86 = d3d3c8c44f0f0a870a95bd2823f9d91979d1aa6f266da5d8cccd0c4b15e3115b
+LINUX_VERSION-6.1 = .89
+LINUX_KERNEL_HASH-6.1.89 = 12bab8e092618d1d4eeaf4201e6e70054c94896198956bd84ff0e908b0264719
-LINUX_VERSION-6.6 = .29
-LINUX_KERNEL_HASH-6.6.29 = 7f26f74c08082c86b1daf866e4d49c5d8276cc1906a89d0e367e457ec167cbd0
+LINUX_VERSION-6.6 = .30
+LINUX_KERNEL_HASH-6.6.30 = b66a5b863b0f8669448b74ca83bd641a856f164b29956e539bbcb5fdeeab9cc6
LINUX_KARCH := arc
else ifneq (,$(findstring $(ARCH) , armeb ))
LINUX_KARCH := arm
+else ifneq (,$(findstring $(ARCH) , loongarch64 ))
+ LINUX_KARCH := loongarch
else ifneq (,$(findstring $(ARCH) , mipsel mips64 mips64el ))
LINUX_KARCH := mips
else ifneq (,$(findstring $(ARCH) , powerpc64 ))
)$(if $(BUILDONLY),Build-Only: $(BUILDONLY)
)$(if $(HIDDEN),Hidden: $(HIDDEN)
)Description: $(if $(Package/$(1)/description),$(Package/$(1)/description),$(TITLE))
-$(MAINTAINER)
@@
$(if $(Package/$(1)/config),Config:
$(Package/$(1)/config)
--- /dev/null
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=yes}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=8
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=8
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=8
+ac_cv_sizeof_ssize_t=8
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=8
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=8
CPU_TYPE ?= riscv64
CPU_CFLAGS_riscv64:=-mabi=lp64d -march=rv64imafdc
endif
+ ifeq ($(ARCH),loongarch64)
+ CPU_TYPE ?= generic
+ CPU_CFLAGS := -O2 -pipe
+ CPU_CFLAGS_generic:=-march=loongarch64
+ endif
ifneq ($(CPU_TYPE),)
ifndef CPU_CFLAGS_$(CPU_TYPE)
$(warning CPU_TYPE "$(CPU_TYPE)" doesn't correspond to a known type)
URL:=https://www.trustedfirmware.org/projects/tf-a/
endef
- define Package/trusted-firmware-a-$(1)/install
+ ifndef Package/trusted-firmware-a-$(1)/install
+ define Package/trusted-firmware-a-$(1)/install
$$(Package/trusted-firmware-a/install)
- endef
+ endef
+ endif
endef
define Build/Configure/Trusted-Firmware-A
return
fi
gids=$(cut -d: -f3 ${IPKG_INSTROOT}/etc/group)
- gid=65536
+ gid=32768
while echo "$gids" | grep -q "^$gid$"; do
gid=$((gid + 1))
done
local rc
[ -z "$uid" ] && {
uids=$(cut -d: -f3 ${IPKG_INSTROOT}/etc/passwd)
- uid=65536
+ uid=32768
while echo "$uids" | grep -q "^$uid$"; do
uid=$((uid + 1))
done
NAND_TYPE:=
BOARD_QFN:=
DRAM_USE_COMB:=
+ RAM_BOOT_UART_DL:=
USE_UBI:=
endef
DDR3_FLYBY:=1
endef
+define Trusted-Firmware-A/mt7981-ram-ddr4
+ NAME:=MediaTek MT7981 (RAM, DDR4)
+ BOOT_DEVICE:=ram
+ BUILD_SUBTARGET:=filogic
+ PLAT:=mt7981
+ DDR_TYPE:=ddr4
+ RAM_BOOT_UART_DL:=1
+ HIDDEN:=
+ DEFAULT:=TARGET_mediatek_filogic
+endef
+
define Trusted-Firmware-A/mt7981-emmc-ddr4
NAME:=MediaTek MT7981 (eMMC, DDR4)
BOOT_DEVICE:=emmc
DDR_TYPE:=ddr3
endef
+define Trusted-Firmware-A/mt7981-ram-ddr3
+ NAME:=MediaTek MT7981 (RAM, DDR3)
+ BOOT_DEVICE:=ram
+ BUILD_SUBTARGET:=filogic
+ PLAT:=mt7981
+ DDR_TYPE:=ddr3
+ RAM_BOOT_UART_DL:=1
+ HIDDEN:=
+ DEFAULT:=TARGET_mediatek_filogic
+endef
+
define Trusted-Firmware-A/mt7981-emmc-ddr3
NAME:=MediaTek MT7981 (eMMC, DDR3)
BOOT_DEVICE:=emmc
DDR_TYPE:=ddr3
endef
+define Trusted-Firmware-A/mt7986-ram-ddr4
+ NAME:=MediaTek MT7986 (RAM, DDR4)
+ BOOT_DEVICE:=ram
+ BUILD_SUBTARGET:=filogic
+ PLAT:=mt7986
+ DDR_TYPE:=ddr4
+ RAM_BOOT_UART_DL:=1
+ HIDDEN:=
+ DEFAULT:=TARGET_mediatek_filogic
+endef
+
define Trusted-Firmware-A/mt7986-nor-ddr4
NAME:=MediaTek MT7986 (SPI-NOR, DDR4)
BOOT_DEVICE:=nor
NAND_TYPE:=spim:4k+256
endef
+define Trusted-Firmware-A/mt7986-ram-ddr3
+ NAME:=MediaTek MT7986 (RAM, DDR3)
+ BOOT_DEVICE:=ram
+ BUILD_SUBTARGET:=filogic
+ PLAT:=mt7986
+ DDR_TYPE:=ddr3
+ RAM_BOOT_UART_DL:=1
+ HIDDEN:=
+ DEFAULT:=TARGET_mediatek_filogic
+endef
+
define Trusted-Firmware-A/mt7986-nor-ddr3
NAME:=MediaTek MT7986 (SPI-NOR, DDR3)
BOOT_DEVICE:=nor
DDR_TYPE:=ddr4
endef
+define Trusted-Firmware-A/mt7988-ram-comb
+ NAME:=MediaTek MT7988 (RAM)
+ BOOT_DEVICE:=ram
+ BUILD_SUBTARGET:=filogic
+ PLAT:=mt7988
+ DRAM_USE_COMB:=1
+ RAM_BOOT_UART_DL:=1
+ HIDDEN:=
+ DEFAULT:=TARGET_mediatek_filogic
+endef
+
define Trusted-Firmware-A/mt7988-nor-comb
NAME:=MediaTek MT7988 (SPI-NOR)
BOOT_DEVICE:=nor
mt7622-emmc-2ddr \
mt7622-sdmmc-1ddr \
mt7622-sdmmc-2ddr \
+ mt7981-ram-ddr3 \
mt7981-emmc-ddr3 \
mt7981-nor-ddr3 \
mt7981-sdmmc-ddr3 \
mt7981-snand-ddr3 \
mt7981-spim-nand-ddr3 \
+ mt7981-ram-ddr4 \
mt7981-emmc-ddr4 \
mt7981-spim-nand-ddr4 \
+ mt7986-ram-ddr3 \
mt7986-emmc-ddr3 \
mt7986-nor-ddr3 \
mt7986-sdmmc-ddr3 \
mt7986-snand-ddr3 \
mt7986-spim-nand-ddr3 \
+ mt7986-ram-ddr4 \
mt7986-emmc-ddr4 \
mt7986-nor-ddr4 \
mt7986-sdmmc-ddr4 \
mt7988-sdmmc-ddr4 \
mt7988-snand-ddr4 \
mt7988-spim-nand-ddr4 \
+ mt7988-ram-comb \
mt7988-emmc-comb \
mt7988-nor-comb \
mt7988-sdmmc-comb \
HAVE_DRAM_OBJ_FILE=yes \
$(if $(DDR3_FLYBY),DDR3_FLYBY=1) \
$(if $(DRAM_USE_COMB),DRAM_USE_COMB=1) \
+ $(if $(RAM_BOOT_UART_DL),RAM_BOOT_UART_DL=1) \
$(if $(USE_UBI),UBI=1 $(if $(findstring mt7622,$(PLAT)),OVERRIDE_UBI_START_ADDR=0x80000)) \
all
+define Package/trusted-firmware-a-ram/install
+ $(INSTALL_DIR) $(STAGING_DIR_IMAGE)
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/build/$(PLAT)/release/bl2.bin $(BIN_DIR)/$(BUILD_VARIANT)-bl2.bin
+endef
+Package/trusted-firmware-a-mt7981-ram-ddr3/install = $(Package/trusted-firmware-a-ram/install)
+Package/trusted-firmware-a-mt7981-ram-ddr4/install = $(Package/trusted-firmware-a-ram/install)
+Package/trusted-firmware-a-mt7986-ram-ddr3/install = $(Package/trusted-firmware-a-ram/install)
+Package/trusted-firmware-a-mt7986-ram-ddr4/install = $(Package/trusted-firmware-a-ram/install)
+Package/trusted-firmware-a-mt7988-ram-comb/install = $(Package/trusted-firmware-a-ram/install)
+
define Package/trusted-firmware-a/install
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
$(INSTALL_DATA) $(PKG_BUILD_DIR)/build/$(PLAT)/release/bl2.img $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-bl2.img
PROTO:=git
URL:=https://github.com/weidai11/cryptopp.git
SOURCE_VERSION:=4d0cad5401d1a2c998b314bc89288c9620d3021d
- MIRROR_HASH:=74ec9e48ee04b9f2d9a1d8c4f2392ed0ab52780d7af0f70405d7bbb23d1504fa
+ MIRROR_HASH:=6c53c8b4dfa07df0c5915a90c20f70c64d150b652cf5ac52e2eae08c5a9cc7cd
SUBDIR:=$(CRYPTOPP_NAME)
endef
Package/grub2=$(call Package/grub2/Default,x86,pc)
Package/grub2-efi=$(call Package/grub2/Default,x86,efi)
Package/grub2-efi-arm=$(call Package/grub2/Default,armsr,efi)
+Package/grub2-efi-loongarch64=$(call Package/grub2/Default,loongarch64,efi)
define Package/grub2-editenv
CATEGORY:=Utilities
reboot serial test efi_gop
endef
+define Package/grub2-efi-loongarch64/install
+ $(INSTALL_DIR) $(STAGING_DIR_IMAGE)/grub2
+ cp ./files/grub-early-gpt.cfg $(PKG_BUILD_DIR)/grub-early.cfg
+ $(STAGING_DIR_HOST)/bin/grub-mkimage \
+ -d $(PKG_BUILD_DIR)/grub-core \
+ -p /boot/grub \
+ -O loongarch64-efi \
+ -c $(PKG_BUILD_DIR)/grub-early.cfg \
+ -o $(STAGING_DIR_IMAGE)/grub2/bootloongarch64.efi \
+ boot chain configfile fat linux ls lsefi minicmd part_gpt part_msdos reboot search \
+ search_fs_uuid search_label serial efi_gop all_video gfxterm ext2
+endef
+
define Package/grub2-editenv/install
$(INSTALL_DIR) $(1)/usr/sbin
$(eval $(call BuildPackage,grub2))
$(eval $(call BuildPackage,grub2-efi))
$(eval $(call BuildPackage,grub2-efi-arm))
+$(eval $(call BuildPackage,grub2-efi-loongarch64))
$(eval $(call BuildPackage,grub2-editenv))
$(eval $(call BuildPackage,grub2-bios-setup))
include $(TOPDIR)/rules.mk
PKG_NAME:=opensbi
-PKG_RELEASE:=1.2
+PKG_RELEASE:=1.4
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/riscv/opensbi
-PKG_SOURCE_DATE:=2022-12-24
-PKG_SOURCE_VERSION:=6b5188ca14e59ce7bf71afe4e7d3d557c3d31bf8
-PKG_MIRROR_HASH:=5939a3225cb37c1dde0b5b9f28f9980c0712533676774ae244d6d84bb09a1439
+PKG_SOURCE_DATE:=2023-12-24
+PKG_SOURCE_VERSION:=a2b255b88918715173942f2c5e1f97ac9e90c877
+PKG_MIRROR_HASH:=a81d7b3622feba80b2a45fe0d38600be73cfbee64a0426be82a71545c10c54d3
PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_VERSION:=2024.04
+PKG_HASH:=18a853fe39fad7ad03a90cc2d4275aeaed6da69735defac3492b80508843dd4a
+PKG_RELEASE:=$(AUTORELEASE)
+
+include $(INCLUDE_DIR)/u-boot.mk
+include $(INCLUDE_DIR)/package.mk
+
+define U-Boot/Default
+ BUILD_TARGET:=bmips
+ BUILD_SUBTARGET:=bcm6328
+ UBOOT_CONFIG:=inteno_xg6846_ram
+ UBOOT_BOARD:=$(1)
+endef
+
+define U-Boot/xg6846
+ NAME:=Inteno XG6846
+ BUILD_DEVICES:=inteno_xg6846
+endef
+
+UBOOT_TARGETS := xg6846
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(STAGING_DIR_IMAGE)
+ $(CP) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-u-boot.bin
+endef
+
+define Package/u-boot/install/default
+endef
+
+$(eval $(call BuildPackage/U-Boot))
alfa-network,pi-wifi4|\
alfa-network,r36a|\
alfa-network,tube-2hq|\
-allnet,all-wap02860ac|\
araknis,an-300-ap-i-n|\
-araknis,an-500-ap-i-ac|\
-araknis,an-700-ap-i-ac|\
arduino,yun|\
asus,rt-ac59u|\
asus,rt-ac59u-v2|\
asus,zenwifi-cd6r|\
buffalo,bhr-4grv2|\
devolo,magic-2-wifi|\
-engenius,eap1200h|\
-engenius,eap1750h|\
engenius,eap300-v2|\
engenius,eap350-v1|\
engenius,eap600|\
engenius,ecb600|\
engenius,enh202-v1|\
engenius,ens202ext-v1|\
-engenius,enstationac-v1|\
-engenius,ews660ap|\
etactica,eg200|\
glinet,gl-ar750s-nor|\
glinet,gl-ar750s-nor-nand|\
ubnt,rocket-m|\
watchguard,ap100|\
watchguard,ap200|\
-watchguard,ap300|\
yuncore,a770|\
yuncore,a782|\
yuncore,a930|\
linksys,whw01)
ubootenv_add_uci_config "/dev/mtd6" "0x0" "0x40000" "0x10000"
;;
+linksys,whw03)
+ ubootenv_add_uci_config "/dev/mmcblk0p11" "0x0" "0x100000"
+ ;;
linksys,whw03v2)
ubootenv_add_uci_config "/dev/mtd6" "0x0" "0x80000" "0x20000"
;;
;;
bananapi,bpi-r3|\
bananapi,bpi-r3-mini|\
-bananapi,bpi-r4)
+bananapi,bpi-r4|\
+bananapi,bpi-r4-poe|\
+jdcloud,re-cp-03)
. /lib/upgrade/common.sh
bootdev="$(fitblk_get_bootdev)"
glinet,gl-mt3000)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x80000" "0x20000"
;;
-jdcloud,re-cp-03)
- local envdev=$(find_mmc_part "ubootenv" "mmcblk0")
- ubootenv_add_uci_config "$envdev" "0x0" "0x40000" "0x40000" "1"
- ubootenv_add_uci_config "$envdev" "0x40000" "0x40000" "0x40000" "1"
- ;;
mercusys,mr90x-v1|\
routerich,ax3000)
local envdev=/dev/mtd$(find_mtd_index "u-boot-env")
ubnt,unifi-6-lr-v3-ubootmod)
ubootenv_add_uci_config "/dev/mtd$(find_mtd_index "u-boot-env")" "0x0" "0x4000" "0x1000"
;;
+ubnt,unifi-6-lr-v2)
+ ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x1000" "0x1000" "1"
+ ;;
xiaomi,redmi-router-ax6s)
ubootenv_add_uci_config "/dev/mtd3" "0x0" "0x10000" "0x40000"
;;
DEPENDS:=+trusted-firmware-a-mt7988-spim-nand-ubi-comb
endef
+define U-Boot/mt7988_bananapi_bpi-r4-poe-emmc
+ NAME:=BananaPi BPi-R4 2.5GE
+ BUILD_SUBTARGET:=filogic
+ BUILD_DEVICES:=bananapi_bpi-r4-poe
+ UBOOT_CONFIG:=mt7988a_bananapi_bpi-r4-poe-emmc
+ UBOOT_IMAGE:=u-boot.fip
+ BL2_BOOTDEV:=emmc
+ BL2_SOC:=mt7988
+ BL2_DDRTYPE:=comb
+ DEPENDS:=+trusted-firmware-a-mt7988-emmc-comb
+endef
+
+define U-Boot/mt7988_bananapi_bpi-r4-poe-sdmmc
+ NAME:=BananaPi BPi-R4 2.5GE
+ BUILD_SUBTARGET:=filogic
+ BUILD_DEVICES:=bananapi_bpi-r4-poe
+ UBOOT_CONFIG:=mt7988a_bananapi_bpi-r4-poe-sdmmc
+ UBOOT_IMAGE:=u-boot.fip
+ BL2_BOOTDEV:=sdmmc
+ BL2_SOC:=mt7988
+ BL2_DDRTYPE:=comb
+ DEPENDS:=+trusted-firmware-a-mt7988-sdmmc-comb
+endef
+
+define U-Boot/mt7988_bananapi_bpi-r4-poe-snand
+ NAME:=BananaPi BPi-R4 2.5GE
+ BUILD_SUBTARGET:=filogic
+ BUILD_DEVICES:=bananapi_bpi-r4-poe
+ UBOOT_CONFIG:=mt7988a_bananapi_bpi-r4-poe-snand
+ UBOOT_IMAGE:=u-boot.fip
+ BL2_BOOTDEV:=spim-nand-ubi
+ BL2_SOC:=mt7988
+ BL2_DDRTYPE:=comb
+ DEPENDS:=+trusted-firmware-a-mt7988-spim-nand-ubi-comb
+endef
+
define U-Boot/mt7988_rfb-spim-nand
NAME:=MT7988 Reference Board
BUILD_SUBTARGET:=filogic
mt7988_bananapi_bpi-r4-emmc \
mt7988_bananapi_bpi-r4-sdmmc \
mt7988_bananapi_bpi-r4-snand \
+ mt7988_bananapi_bpi-r4-poe-emmc \
+ mt7988_bananapi_bpi-r4-poe-sdmmc \
+ mt7988_bananapi_bpi-r4-poe-snand \
mt7988_rfb-spim-nand \
mt7988_rfb-snand \
mt7988_rfb-nor \
+reset_factory=eraseenv && reset
+_init_env=setenv _init_env ; saveenv ; saveenv
+_firstboot=setenv _firstboot ; run _switch_to_menu _update_bootdev _init_env boot_first
-+_update_bootdev=setenv _update_bootdev ; setenv bootargs "$console root=/dev/mmcblk0p65"
++_update_bootdev=setenv _update_bootdev ; setenv bootargs "$console root=/dev/fit0 rootwait"
+_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title
+_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title \e[33m$ver\e[0m"
--- a/arch/arm/dts/mt7623a-unielec-u7623-02-emmc.dts
+serverip=192.168.1.254
+loadaddr=0x46000000
+console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0
-+bootargs=root=/dev/mmcblk0p65
++bootargs=root=/dev/fit0 rootwait
+bootcmd=if pstore check ; then run boot_recovery ; else run boot_emmc ; fi
+bootconf=config-1
+bootdelay=0
+ non-removable;
+ status = "okay";
+};
+--- /dev/null
++++ b/configs/mt7988a_bananapi_bpi-r4-poe-emmc_defconfig
+@@ -0,0 +1,180 @@
++CONFIG_ARM=y
++CONFIG_SYS_HAS_NONCACHED_MEMORY=y
++CONFIG_POSITION_INDEPENDENT=y
++CONFIG_ARCH_MEDIATEK=y
++CONFIG_TEXT_BASE=0x41e00000
++CONFIG_SYS_MALLOC_F_LEN=0x4000
++CONFIG_NR_DRAM_BANKS=1
++CONFIG_SYS_PROMPT="MT7988> "
++CONFIG_TARGET_MT7988=y
++CONFIG_DEBUG_UART_BASE=0x11000000
++CONFIG_DEBUG_UART_CLOCK=40000000
++CONFIG_SYS_LOAD_ADDR=0x50000000
++CONFIG_DEBUG_UART=y
++CONFIG_SYS_CBSIZE=512
++CONFIG_SYS_PBSIZE=1049
++CONFIG_DEFAULT_DEVICE_TREE="mt7988a-bananapi-bpi-r4-emmc"
++CONFIG_DEFAULT_ENV_FILE="bananapi_bpi-r4-poe_emmc_env"
++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7988a-bpi-r4-emmc.dtb"
++CONFIG_OF_LIBFDT_OVERLAY=y
++CONFIG_OF_SYSTEM_SETUP=y
++CONFIG_SMBIOS_PRODUCT_NAME=""
++CONFIG_AUTOBOOT_KEYED=y
++CONFIG_BOOTDELAY=30
++CONFIG_AUTOBOOT_MENU_SHOW=y
++CONFIG_CFB_CONSOLE_ANSI=y
++CONFIG_BOARD_LATE_INIT=y
++CONFIG_BUTTON=y
++CONFIG_BUTTON_GPIO=y
++CONFIG_GPIO_HOG=y
++CONFIG_CMD_ENV_FLAGS=y
++CONFIG_FIT=y
++CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
++CONFIG_LED=y
++CONFIG_LED_BLINK=y
++CONFIG_LED_GPIO=y
++CONFIG_LOGLEVEL=7
++CONFIG_LOG=y
++CONFIG_CMD_BOOTMENU=y
++CONFIG_CMD_BOOTP=y
++CONFIG_CMD_BUTTON=y
++CONFIG_CMD_CACHE=y
++CONFIG_CMD_CDP=y
++CONFIG_CMD_CPU=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_DM=y
++CONFIG_CMD_DNS=y
++CONFIG_CMD_ECHO=y
++CONFIG_CMD_ENV_READMEM=y
++CONFIG_CMD_ERASEENV=y
++CONFIG_CMD_EXT4=y
++CONFIG_CMD_FAT=y
++CONFIG_CMD_FDT=y
++CONFIG_CMD_FS_GENERIC=y
++CONFIG_CMD_FS_UUID=y
++CONFIG_CMD_GPIO=y
++CONFIG_CMD_GPT=y
++CONFIG_CMD_HASH=y
++CONFIG_CMD_ITEST=y
++CONFIG_CMD_LED=y
++CONFIG_CMD_LICENSE=y
++CONFIG_CMD_LINK_LOCAL=y
++# CONFIG_CMD_MBR is not set
++CONFIG_CMD_MMC=y
++CONFIG_CMD_MTD=y
++CONFIG_CMD_PCI=y
++CONFIG_CMD_PSTORE=y
++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000
++CONFIG_CMD_SF_TEST=y
++CONFIG_CMD_PING=y
++CONFIG_CMD_PXE=y
++CONFIG_CMD_PWM=y
++CONFIG_CMD_SMC=y
++CONFIG_CMD_TFTPBOOT=y
++CONFIG_CMD_TFTPSRV=y
++CONFIG_CMD_UBI=y
++CONFIG_CMD_UBI_RENAME=y
++CONFIG_CMD_UBIFS=y
++CONFIG_CMD_ASKENV=y
++CONFIG_CMD_PART=y
++CONFIG_CMD_RARP=y
++CONFIG_CMD_SETEXPR=y
++CONFIG_CMD_SLEEP=y
++CONFIG_CMD_SNTP=y
++CONFIG_CMD_SOURCE=y
++CONFIG_CMD_STRINGS=y
++CONFIG_CMD_USB=y
++CONFIG_CMD_UUID=y
++CONFIG_DISPLAY_CPUINFO=y
++CONFIG_DM_MMC=y
++CONFIG_DM_MTD=y
++CONFIG_DM_REGULATOR=y
++CONFIG_DM_REGULATOR_FIXED=y
++CONFIG_DM_REGULATOR_GPIO=y
++CONFIG_DM_USB=y
++CONFIG_DM_PWM=y
++CONFIG_PWM_MTK=y
++CONFIG_HUSH_PARSER=y
++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
++CONFIG_SYS_RELOC_GD_ENV_ADDR=y
++CONFIG_VERSION_VARIABLE=y
++CONFIG_PARTITION_UUIDS=y
++CONFIG_NETCONSOLE=y
++CONFIG_DM_GPIO=y
++CONFIG_DM_SCSI=y
++CONFIG_AHCI=y
++CONFIG_AHCI_PCI=y
++CONFIG_SCSI_AHCI=y
++CONFIG_SCSI=y
++CONFIG_CMD_SCSI=y
++CONFIG_PHY=y
++CONFIG_PHY_MTK_TPHY=y
++CONFIG_MTK_AHCI=y
++CONFIG_PCI=y
++CONFIG_MTD=y
++CONFIG_MTD_UBI_FASTMAP=y
++CONFIG_DM_PCI=y
++CONFIG_PCIE_MEDIATEK=y
++CONFIG_PRE_CONSOLE_BUFFER=y
++CONFIG_PRE_CON_BUF_ADDR=0x4007EF00
++CONFIG_RAM=y
++CONFIG_DM_SERIAL=y
++CONFIG_MTK_SERIAL=y
++CONFIG_MMC=y
++CONFIG_MMC_DEFAULT_DEV=1
++CONFIG_MMC_SUPPORTS_TUNING=y
++CONFIG_SPI=y
++CONFIG_DM_SPI=y
++CONFIG_MTK_SPI_NAND=y
++CONFIG_MTK_SPI_NAND_MTD=y
++CONFIG_SYSRESET_WATCHDOG=y
++CONFIG_WDT_MTK=y
++CONFIG_LZO=y
++CONFIG_ZSTD=y
++CONFIG_HEXDUMP=y
++CONFIG_RANDOM_UUID=y
++CONFIG_REGEX=y
++CONFIG_USB=y
++CONFIG_USB_HOST=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_XHCI_MTK=y
++CONFIG_USB_STORAGE=y
++CONFIG_OF_EMBED=y
++CONFIG_ENV_OVERWRITE=y
++CONFIG_ENV_IS_IN_MMC=y
++CONFIG_ENV_OFFSET=0x400000
++CONFIG_ENV_OFFSET_REDUND=0x440000
++CONFIG_ENV_SIZE=0x40000
++CONFIG_ENV_SIZE_REDUND=0x40000
++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
++CONFIG_NET_RANDOM_ETHADDR=y
++CONFIG_REGMAP=y
++CONFIG_SYSCON=y
++CONFIG_CLK=y
++CONFIG_SUPPORT_EMMC_BOOT=y
++CONFIG_MMC_HS200_SUPPORT=y
++CONFIG_MMC_MTK=y
++CONFIG_PHY_FIXED=y
++CONFIG_DM_ETH=y
++CONFIG_MEDIATEK_ETH=y
++CONFIG_PINCTRL=y
++CONFIG_PINCONF=y
++CONFIG_PINCTRL_MT7988=y
++CONFIG_POWER_DOMAIN=y
++CONFIG_MTK_POWER_DOMAIN=y
++CONFIG_USE_DEFAULT_ENV_FILE=y
++CONFIG_MTD_SPI_NAND=y
++CONFIG_MTK_SPIM=y
++#CONFIG_MTK_SNOR=y
++CONFIG_DM_SPI_FLASH=y
++CONFIG_SPI_FLASH_MTD=y
++CONFIG_SPI_FLASH_WINBOND=y
++# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
++CONFIG_CMD_SF=y
++CONFIG_CMD_NAND=y
++CONFIG_CMD_NAND_TRIMFFS=y
++CONFIG_LMB_MAX_REGIONS=64
++CONFIG_USE_IPADDR=y
++CONFIG_IPADDR="192.168.1.1"
++CONFIG_USE_SERVERIP=y
++CONFIG_SERVERIP="192.168.1.254"
+--- /dev/null
++++ b/configs/mt7988a_bananapi_bpi-r4-poe-sdmmc_defconfig
+@@ -0,0 +1,180 @@
++CONFIG_ARM=y
++CONFIG_SYS_HAS_NONCACHED_MEMORY=y
++CONFIG_POSITION_INDEPENDENT=y
++CONFIG_ARCH_MEDIATEK=y
++CONFIG_TEXT_BASE=0x41e00000
++CONFIG_SYS_MALLOC_F_LEN=0x4000
++CONFIG_NR_DRAM_BANKS=1
++CONFIG_SYS_PROMPT="MT7988> "
++CONFIG_TARGET_MT7988=y
++CONFIG_DEBUG_UART_BASE=0x11000000
++CONFIG_DEBUG_UART_CLOCK=40000000
++CONFIG_SYS_LOAD_ADDR=0x50000000
++CONFIG_DEBUG_UART=y
++CONFIG_SYS_CBSIZE=512
++CONFIG_SYS_PBSIZE=1049
++CONFIG_DEFAULT_DEVICE_TREE="mt7988a-bananapi-bpi-r4-sd"
++CONFIG_DEFAULT_ENV_FILE="bananapi_bpi-r4-poe_sdmmc_env"
++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7988a-bpi-r4-sd.dtb"
++CONFIG_OF_LIBFDT_OVERLAY=y
++CONFIG_OF_SYSTEM_SETUP=y
++CONFIG_SMBIOS_PRODUCT_NAME=""
++CONFIG_AUTOBOOT_KEYED=y
++CONFIG_BOOTDELAY=30
++CONFIG_AUTOBOOT_MENU_SHOW=y
++CONFIG_CFB_CONSOLE_ANSI=y
++CONFIG_BOARD_LATE_INIT=y
++CONFIG_BUTTON=y
++CONFIG_BUTTON_GPIO=y
++CONFIG_GPIO_HOG=y
++CONFIG_CMD_ENV_FLAGS=y
++CONFIG_FIT=y
++CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
++CONFIG_LED=y
++CONFIG_LED_BLINK=y
++CONFIG_LED_GPIO=y
++CONFIG_LOGLEVEL=7
++CONFIG_LOG=y
++CONFIG_CMD_BOOTMENU=y
++CONFIG_CMD_BOOTP=y
++CONFIG_CMD_BUTTON=y
++CONFIG_CMD_CACHE=y
++CONFIG_CMD_CDP=y
++CONFIG_CMD_CPU=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_DM=y
++CONFIG_CMD_DNS=y
++CONFIG_CMD_ECHO=y
++CONFIG_CMD_ENV_READMEM=y
++CONFIG_CMD_ERASEENV=y
++CONFIG_CMD_EXT4=y
++CONFIG_CMD_FAT=y
++CONFIG_CMD_FDT=y
++CONFIG_CMD_FS_GENERIC=y
++CONFIG_CMD_FS_UUID=y
++CONFIG_CMD_GPIO=y
++CONFIG_CMD_GPT=y
++CONFIG_CMD_HASH=y
++CONFIG_CMD_ITEST=y
++CONFIG_CMD_LED=y
++CONFIG_CMD_LICENSE=y
++CONFIG_CMD_LINK_LOCAL=y
++# CONFIG_CMD_MBR is not set
++CONFIG_CMD_MMC=y
++CONFIG_CMD_MTD=y
++CONFIG_CMD_PCI=y
++CONFIG_CMD_PSTORE=y
++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000
++CONFIG_CMD_SF_TEST=y
++CONFIG_CMD_PING=y
++CONFIG_CMD_PXE=y
++CONFIG_CMD_PWM=y
++CONFIG_CMD_SMC=y
++CONFIG_CMD_TFTPBOOT=y
++CONFIG_CMD_TFTPSRV=y
++CONFIG_CMD_UBI=y
++CONFIG_CMD_UBI_RENAME=y
++CONFIG_CMD_UBIFS=y
++CONFIG_CMD_ASKENV=y
++CONFIG_CMD_PART=y
++CONFIG_CMD_RARP=y
++CONFIG_CMD_SETEXPR=y
++CONFIG_CMD_SLEEP=y
++CONFIG_CMD_SNTP=y
++CONFIG_CMD_SOURCE=y
++CONFIG_CMD_STRINGS=y
++CONFIG_CMD_USB=y
++CONFIG_CMD_UUID=y
++CONFIG_DISPLAY_CPUINFO=y
++CONFIG_DM_MMC=y
++CONFIG_DM_MTD=y
++CONFIG_DM_REGULATOR=y
++CONFIG_DM_REGULATOR_FIXED=y
++CONFIG_DM_REGULATOR_GPIO=y
++CONFIG_DM_USB=y
++CONFIG_DM_PWM=y
++CONFIG_PWM_MTK=y
++CONFIG_HUSH_PARSER=y
++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
++CONFIG_SYS_RELOC_GD_ENV_ADDR=y
++CONFIG_VERSION_VARIABLE=y
++CONFIG_PARTITION_UUIDS=y
++CONFIG_NETCONSOLE=y
++CONFIG_DM_GPIO=y
++CONFIG_DM_SCSI=y
++CONFIG_AHCI=y
++CONFIG_AHCI_PCI=y
++CONFIG_SCSI_AHCI=y
++CONFIG_SCSI=y
++CONFIG_CMD_SCSI=y
++CONFIG_PHY=y
++CONFIG_PHY_MTK_TPHY=y
++CONFIG_MTK_AHCI=y
++CONFIG_PCI=y
++CONFIG_MTD=y
++CONFIG_MTD_UBI_FASTMAP=y
++CONFIG_DM_PCI=y
++CONFIG_PCIE_MEDIATEK=y
++CONFIG_PRE_CONSOLE_BUFFER=y
++CONFIG_PRE_CON_BUF_ADDR=0x4007EF00
++CONFIG_RAM=y
++CONFIG_DM_SERIAL=y
++CONFIG_MTK_SERIAL=y
++CONFIG_MMC=y
++CONFIG_MMC_DEFAULT_DEV=1
++CONFIG_MMC_SUPPORTS_TUNING=y
++CONFIG_SPI=y
++CONFIG_DM_SPI=y
++CONFIG_MTK_SPI_NAND=y
++CONFIG_MTK_SPI_NAND_MTD=y
++CONFIG_SYSRESET_WATCHDOG=y
++CONFIG_WDT_MTK=y
++CONFIG_LZO=y
++CONFIG_ZSTD=y
++CONFIG_HEXDUMP=y
++CONFIG_RANDOM_UUID=y
++CONFIG_REGEX=y
++CONFIG_USB=y
++CONFIG_USB_HOST=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_XHCI_MTK=y
++CONFIG_USB_STORAGE=y
++CONFIG_OF_EMBED=y
++CONFIG_ENV_OVERWRITE=y
++CONFIG_ENV_IS_IN_MMC=y
++CONFIG_ENV_OFFSET=0x400000
++CONFIG_ENV_OFFSET_REDUND=0x440000
++CONFIG_ENV_SIZE=0x40000
++CONFIG_ENV_SIZE_REDUND=0x40000
++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
++CONFIG_NET_RANDOM_ETHADDR=y
++CONFIG_REGMAP=y
++CONFIG_SYSCON=y
++CONFIG_CLK=y
++CONFIG_SUPPORT_EMMC_BOOT=y
++CONFIG_MMC_HS200_SUPPORT=y
++CONFIG_MMC_MTK=y
++CONFIG_PHY_FIXED=y
++CONFIG_DM_ETH=y
++CONFIG_MEDIATEK_ETH=y
++CONFIG_PINCTRL=y
++CONFIG_PINCONF=y
++CONFIG_PINCTRL_MT7988=y
++CONFIG_POWER_DOMAIN=y
++CONFIG_MTK_POWER_DOMAIN=y
++CONFIG_USE_DEFAULT_ENV_FILE=y
++CONFIG_MTD_SPI_NAND=y
++CONFIG_MTK_SPIM=y
++#CONFIG_MTK_SNOR=y
++CONFIG_DM_SPI_FLASH=y
++CONFIG_SPI_FLASH_MTD=y
++CONFIG_SPI_FLASH_WINBOND=y
++# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
++CONFIG_CMD_SF=y
++CONFIG_CMD_NAND=y
++CONFIG_CMD_NAND_TRIMFFS=y
++CONFIG_LMB_MAX_REGIONS=64
++CONFIG_USE_IPADDR=y
++CONFIG_IPADDR="192.168.1.1"
++CONFIG_USE_SERVERIP=y
++CONFIG_SERVERIP="192.168.1.254"
+--- /dev/null
++++ b/configs/mt7988a_bananapi_bpi-r4-poe-snand_defconfig
+@@ -0,0 +1,182 @@
++CONFIG_ARM=y
++CONFIG_SYS_HAS_NONCACHED_MEMORY=y
++CONFIG_POSITION_INDEPENDENT=y
++CONFIG_ARCH_MEDIATEK=y
++CONFIG_TEXT_BASE=0x41e00000
++CONFIG_SYS_MALLOC_F_LEN=0x4000
++CONFIG_NR_DRAM_BANKS=1
++CONFIG_SYS_PROMPT="MT7988> "
++CONFIG_TARGET_MT7988=y
++CONFIG_DEBUG_UART_BASE=0x11000000
++CONFIG_DEBUG_UART_CLOCK=40000000
++CONFIG_SYS_LOAD_ADDR=0x50000000
++CONFIG_DEBUG_UART=y
++CONFIG_SYS_CBSIZE=512
++CONFIG_SYS_PBSIZE=1049
++CONFIG_DEFAULT_DEVICE_TREE="mt7988a-bananapi-bpi-r4-emmc"
++CONFIG_DEFAULT_ENV_FILE="bananapi_bpi-r4-poe_snand_env"
++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7988a-bpi-r4-emmc.dtb"
++CONFIG_OF_LIBFDT_OVERLAY=y
++CONFIG_OF_SYSTEM_SETUP=y
++CONFIG_SMBIOS_PRODUCT_NAME=""
++CONFIG_AUTOBOOT_KEYED=y
++CONFIG_BOOTDELAY=30
++CONFIG_AUTOBOOT_MENU_SHOW=y
++CONFIG_CFB_CONSOLE_ANSI=y
++CONFIG_BOARD_LATE_INIT=y
++CONFIG_BUTTON=y
++CONFIG_BUTTON_GPIO=y
++CONFIG_GPIO_HOG=y
++CONFIG_CMD_ENV_FLAGS=y
++CONFIG_FIT=y
++CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
++CONFIG_LED=y
++CONFIG_LED_BLINK=y
++CONFIG_LED_GPIO=y
++CONFIG_LOGLEVEL=7
++CONFIG_LOG=y
++CONFIG_CMD_BOOTMENU=y
++CONFIG_CMD_BOOTP=y
++CONFIG_CMD_BUTTON=y
++CONFIG_CMD_CACHE=y
++CONFIG_CMD_CDP=y
++CONFIG_CMD_CPU=y
++CONFIG_CMD_DHCP=y
++CONFIG_CMD_DM=y
++CONFIG_CMD_DNS=y
++CONFIG_CMD_ECHO=y
++CONFIG_CMD_ENV_READMEM=y
++CONFIG_CMD_ERASEENV=y
++CONFIG_CMD_EXT4=y
++CONFIG_CMD_FAT=y
++CONFIG_CMD_FDT=y
++CONFIG_CMD_FS_GENERIC=y
++CONFIG_CMD_FS_UUID=y
++CONFIG_CMD_GPIO=y
++CONFIG_CMD_GPT=y
++CONFIG_CMD_HASH=y
++CONFIG_CMD_ITEST=y
++CONFIG_CMD_LED=y
++CONFIG_CMD_LICENSE=y
++CONFIG_CMD_LINK_LOCAL=y
++# CONFIG_CMD_MBR is not set
++CONFIG_CMD_MMC=y
++CONFIG_CMD_MTD=y
++CONFIG_CMD_PCI=y
++CONFIG_CMD_PSTORE=y
++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000
++CONFIG_CMD_SF_TEST=y
++CONFIG_CMD_PING=y
++CONFIG_CMD_PXE=y
++CONFIG_CMD_PWM=y
++CONFIG_CMD_SMC=y
++CONFIG_CMD_TFTPBOOT=y
++CONFIG_CMD_TFTPSRV=y
++CONFIG_CMD_UBI=y
++CONFIG_CMD_UBI_RENAME=y
++CONFIG_CMD_UBIFS=y
++CONFIG_CMD_ASKENV=y
++CONFIG_CMD_PART=y
++CONFIG_CMD_RARP=y
++CONFIG_CMD_SETEXPR=y
++CONFIG_CMD_SLEEP=y
++CONFIG_CMD_SNTP=y
++CONFIG_CMD_SOURCE=y
++CONFIG_CMD_STRINGS=y
++CONFIG_CMD_USB=y
++CONFIG_CMD_UUID=y
++CONFIG_DISPLAY_CPUINFO=y
++CONFIG_DM_MMC=y
++CONFIG_DM_MTD=y
++CONFIG_DM_REGULATOR=y
++CONFIG_DM_REGULATOR_FIXED=y
++CONFIG_DM_REGULATOR_GPIO=y
++CONFIG_DM_USB=y
++CONFIG_DM_PWM=y
++CONFIG_PWM_MTK=y
++CONFIG_HUSH_PARSER=y
++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
++CONFIG_SYS_RELOC_GD_ENV_ADDR=y
++CONFIG_VERSION_VARIABLE=y
++CONFIG_PARTITION_UUIDS=y
++CONFIG_NETCONSOLE=y
++CONFIG_DM_GPIO=y
++CONFIG_DM_SCSI=y
++CONFIG_AHCI=y
++CONFIG_AHCI_PCI=y
++CONFIG_SCSI_AHCI=y
++CONFIG_SCSI=y
++CONFIG_CMD_SCSI=y
++CONFIG_PHY=y
++CONFIG_PHY_MTK_TPHY=y
++CONFIG_MTK_AHCI=y
++CONFIG_PCI=y
++CONFIG_MTD=y
++CONFIG_MTD_UBI_FASTMAP=y
++CONFIG_DM_PCI=y
++CONFIG_PCIE_MEDIATEK=y
++CONFIG_PINCTRL_MT7988=y
++CONFIG_PRE_CONSOLE_BUFFER=y
++CONFIG_PRE_CON_BUF_ADDR=0x4007EF00
++CONFIG_RAM=y
++CONFIG_DM_SERIAL=y
++CONFIG_MTK_SERIAL=y
++CONFIG_MMC=y
++CONFIG_MMC_DEFAULT_DEV=1
++CONFIG_MMC_SUPPORTS_TUNING=y
++CONFIG_SPI=y
++CONFIG_DM_SPI=y
++CONFIG_MTK_SPI_NAND=y
++CONFIG_MTK_SPI_NAND_MTD=y
++CONFIG_SYSRESET_WATCHDOG=y
++CONFIG_WDT_MTK=y
++CONFIG_LZO=y
++CONFIG_ZSTD=y
++CONFIG_HEXDUMP=y
++CONFIG_RANDOM_UUID=y
++CONFIG_REGEX=y
++CONFIG_USB=y
++CONFIG_USB_HOST=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_XHCI_MTK=y
++CONFIG_USB_STORAGE=y
++CONFIG_OF_EMBED=y
++CONFIG_ENV_OVERWRITE=y
++CONFIG_ENV_IS_IN_UBI=y
++CONFIG_ENV_UBI_PART="ubi"
++CONFIG_ENV_SIZE=0x1f000
++CONFIG_ENV_SIZE_REDUND=0x1f000
++CONFIG_ENV_UBI_VOLUME="ubootenv"
++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
++CONFIG_NET_RANDOM_ETHADDR=y
++CONFIG_REGMAP=y
++CONFIG_SYSCON=y
++CONFIG_CLK=y
++CONFIG_SUPPORT_EMMC_BOOT=y
++CONFIG_MMC_HS200_SUPPORT=y
++CONFIG_MMC_MTK=y
++CONFIG_PHY_FIXED=y
++CONFIG_DM_ETH=y
++CONFIG_MEDIATEK_ETH=y
++CONFIG_PINCTRL=y
++CONFIG_PINCONF=y
++CONFIG_PINCTRL_MT7988=y
++CONFIG_POWER_DOMAIN=y
++CONFIG_MTK_POWER_DOMAIN=y
++CONFIG_USE_DEFAULT_ENV_FILE=y
++CONFIG_MTD_SPI_NAND=y
++CONFIG_MTK_SPIM=y
++#CONFIG_MTK_SNOR=y
++CONFIG_DM_SPI_FLASH=y
++CONFIG_SPI_FLASH_MTD=y
++CONFIG_SPI_FLASH_WINBOND=y
++# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
++CONFIG_CMD_SF=y
++CONFIG_CMD_NAND=y
++CONFIG_CMD_NAND_TRIMFFS=y
++CONFIG_LMB_MAX_REGIONS=64
++CONFIG_USE_IPADDR=y
++CONFIG_IPADDR="192.168.1.1"
++CONFIG_USE_SERVERIP=y
++CONFIG_SERVERIP="192.168.1.254"
+--- /dev/null
++++ b/bananapi_bpi-r4-poe_emmc_env
+@@ -0,0 +1,57 @@
++ipaddr=192.168.1.1
++serverip=192.168.1.254
++loadaddr=0x50000000
++bootargs=console=ttyS0,115200n1 pci=pcie_bus_perf root=/dev/fit0 rootwait
++bootcmd=if pstore check ; then run boot_recovery ; else run boot_emmc ; fi
++bootconf=config-mt7988a-bananapi-bpi-r4-poe
++bootconf_base=config-mt7988a-bananapi-bpi-r4-poe
++bootconf_emmc=mt7988a-bananapi-bpi-r4-emmc
++bootconf_extra=
++bootdelay=0
++bootfile=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-initramfs-recovery.itb
++bootfile_bl2=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-emmc-preloader.bin
++bootfile_fip=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-emmc-bl31-uboot.fip
++bootfile_upg=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-squashfs-sysupgrade.itb
++bootled_pwr=green:status
++bootled_rec=blue:status
++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60
++bootmenu_default=0
++bootmenu_delay=0
++bootmenu_title= \e[0;34m( ( ( \e[1;39mOpenWrt\e[0;34m ) ) ) \e[0;36m[eMMC]\e[0m
++bootmenu_0=Initialize environment.=run _firstboot
++bootmenu_0d=Run default boot command.=run boot_default
++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return
++bootmenu_2=Boot production system from eMMC.=run boot_production ; run bootmenu_confirm_return
++bootmenu_3=Boot recovery system from eMMC.=run boot_recovery ; run bootmenu_confirm_return
++bootmenu_4=Load production system via TFTP then write to eMMC.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
++bootmenu_5=Load recovery system via TFTP then write to eMMC.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
++bootmenu_6=\e[31mLoad BL31+U-Boot FIP via TFTP then write to eMMC.\e[0m=run boot_tftp_write_fip ; run bootmenu_confirm_return
++bootmenu_7=\e[31mLoad BL2 preloader via TFTP then write to eMMC.\e[0m=run boot_tftp_write_bl2 ; run bootmenu_confirm_return
++bootmenu_8=Reboot.=reset
++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset
++boot_first=if button reset ; then led $bootled_rec on ; run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu
++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever
++boot_production=led $bootled_pwr on ; run emmc_read_production && bootm $loadaddr#$bootconf#$bootconf_emmc#$bootconf_extra ; led $bootled_pwr off
++boot_recovery=led $bootled_rec on ; run emmc_read_recovery && bootm $loadaddr#$bootconf#$bootconf_emmc#$bootconf_extra ; led $bootled_rec off
++boot_emmc=run boot_production ; run boot_recovery
++boot_tftp_forever=led $bootled_rec on ; while true ; do run boot_tftp_recovery ; sleep 1 ; done
++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run emmc_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf#$bootconf_emmc#$bootconf_extra ; fi
++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run emmc_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf#$bootconf_emmc ; fi
++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run emmc_write_fip
++boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run emmc_write_bl2
++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf
++mmc_write_vol=imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc erase 0x$part_addr 0x$image_size && mmc write $loadaddr 0x$part_addr 0x$image_size
++mmc_read_vol=mmc read $loadaddr $part_addr 0x100 && imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc read $loadaddr 0x$part_addr 0x$image_size && setexpr filesize $image_size * 0x200
++part_default=production
++part_recovery=recovery
++reset_factory=eraseenv && reset
++emmc_read_production=part start mmc 0 $part_default part_addr && part size mmc 0 $part_default part_size && run mmc_read_vol
++emmc_read_recovery=part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_read_vol
++emmc_write_bl2=mmc partconf 0 1 1 1 && mmc erase 0x0 0x400 && mmc write $fileaddr 0x0 0x400 ; mmc partconf 0 1 1 0
++emmc_write_fip=mmc erase 0x3400 0x2000 && mmc write $fileaddr 0x3400 0x2000 && mmc erase 0x2000 0x800
++emmc_write_production=part start mmc 0 $part_default part_addr && part size mmc 0 $part_default part_size && run mmc_write_vol
++emmc_write_recovery=part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_write_vol
++_init_env=setenv _init_env ; setenv _create_env ; saveenv ; saveenv
++_firstboot=setenv _firstboot ; run _switch_to_menu ; run _init_env ; run boot_first
++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title
++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title \e[33m$ver\e[0m"
+--- /dev/null
++++ b/bananapi_bpi-r4-poe_sdmmc_env
+@@ -0,0 +1,66 @@
++ipaddr=192.168.1.1
++serverip=192.168.1.254
++loadaddr=0x50000000
++bootargs=console=ttyS0,115200n1 pci=pcie_bus_perf root=/dev/fit0 rootwait
++bootcmd=if pstore check ; then run boot_recovery ; else run boot_sdmmc ; fi
++bootconf=config-mt7988a-bananapi-bpi-r4-poe
++bootconf_sd=mt7988a-bananapi-bpi-r4-sd
++bootconf_emmc=mt7988a-bananapi-bpi-r4-emmc
++bootconf_extra=
++bootdelay=0
++bootfile=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-initramfs-recovery.itb
++bootfile_upg=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-squashfs-sysupgrade.itb
++bootled_pwr=green:status
++bootled_rec=blue:status
++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60
++bootmenu_default=0
++bootmenu_delay=0
++bootmenu_title= \e[0;34m( ( ( \e[1;39mOpenWrt\e[0;34m ) ) ) \e[0;36m[SD card]\e[0m
++bootmenu_0=Initialize environment.=run _firstboot
++bootmenu_0d=Run default boot command.=run boot_default
++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return
++bootmenu_2=Boot production system from SD card.=run boot_production ; run bootmenu_confirm_return
++bootmenu_3=Boot recovery system from SD card.=run boot_recovery ; run bootmenu_confirm_return
++bootmenu_4=Load production system via TFTP then write to SD card.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
++bootmenu_5=Load recovery system via TFTP then write to SD card.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
++bootmenu_6=\e[31mInstall bootloader, recovery and production to NAND.\e[0m=if nand info ; then run ubi_init ; else echo "NAND not detected" ; fi ; run bootmenu_confirm_return
++bootmenu_7=Reboot.=reset
++bootmenu_8=Reset all settings to factory defaults.=run reset_factory ; reset
++boot_first=if button reset ; then led $bootled_rec on ; run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu
++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever
++boot_production=led $bootled_pwr on ; run sdmmc_read_production && bootm $loadaddr#$bootconf#$bootconf_sd#$bootconf_extra ; led $bootled_pwr off
++boot_recovery=led $bootled_rec on ; run sdmmc_read_recovery && bootm $loadaddr#$bootconf#$bootconf_emmc ; led $bootled_rec off
++boot_sdmmc=run boot_production ; run boot_recovery
++boot_tftp_forever=led $bootled_rec on ; while true ; do run boot_tftp_recovery ; sleep 1 ; done
++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run sdmmc_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf#$bootconf_sd#$bootconf_extra ; fi
++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run sdmmc_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf#$bootconf_sd ; fi
++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf#$bootconf_sd
++mmc_write_vol=imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc erase 0x$part_addr 0x$image_size && mmc write $loadaddr 0x$part_addr 0x$image_size
++mmc_read_vol=mmc read $loadaddr $part_addr 0x100 && imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc read $loadaddr 0x$part_addr 0x$image_size && setexpr filesize $image_size * 0x200
++part_default=production
++part_recovery=recovery
++reset_factory=eraseenv && reset
++sdmmc_read_production=part start mmc 0 $part_default part_addr && part size mmc 0 $part_default part_size && run mmc_read_vol
++sdmmc_read_recovery=part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_read_vol
++sdmmc_read_snand_bl2=part start mmc 0 install part_addr && mmc read $loadaddr $part_addr 0x400
++sdmmc_read_snand_fip=part start mmc 0 install part_addr && setexpr offset $part_addr + 0x800 && mmc read $loadaddr $offset 0x1000
++sdmmc_read_emmc_install=part start mmc 0 install part_addr && setexpr offset $part_addr + 0x3800 && mmc read $loadaddr $offset 0x4000
++sdmmc_write_production=part start mmc 0 $part_default part_addr && part size mmc 0 $part_default part_size && run mmc_write_vol
++sdmmc_write_recovery=part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_write_vol
++snand_write_bl2=mtd erase bl2 && mtd write bl2 $loadaddr 0x0 0x80000 && mtd write bl2 $loadaddr 0x80000 0x80000 && mtd write bl2 $loadaddr 0x100000 0x80000 && mtd write bl2 $loadaddr 0x180000 0x80000
++ubi_create_env=ubi create ubootenv 0x100000 dynamic 1 ; ubi create ubootenv2 0x100000 dynamic 2
++ubi_format=ubi detach ; mtd erase ubi && ubi part ubi
++ubi_init=run ubi_format && run ubi_init_bl && run ubi_create_env && run ubi_init_openwrt && run ubi_init_emmc_install
++ubi_init_openwrt=run sdmmc_read_recovery && iminfo $loadaddr && run ubi_write_recovery ; run sdmmc_read_production && iminfo $loadaddr && run ubi_write_production
++ubi_init_bl=run sdmmc_read_snand_bl2 && run snand_write_bl2 && run sdmmc_read_snand_fip && run ubi_write_fip
++ubi_init_emmc_install=run sdmmc_read_emmc_install && run ubi_write_emmc_install
++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi
++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data
++ubi_write_fip=run ubi_remove_rootfs ; ubi check fip && ubi remove fip ; ubi create fip 0x200000 static ; ubi write $loadaddr fip 0x200000
++ubi_write_emmc_install=ubi check emmc_install && ubi remove emmc_install ; ubi create emmc_install 0x800000 dynamic ; ubi write $loadaddr emmc_install 0x800000
++ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize
++ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize
++_init_env=setenv _init_env ; setenv _create_env ; saveenv ; saveenv
++_firstboot=setenv _firstboot ; run _switch_to_menu ; run _init_env ; run boot_first
++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title
++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title \e[33m$ver\e[0m"
+--- /dev/null
++++ b/bananapi_bpi-r4-poe_snand_env
+@@ -0,0 +1,67 @@
++ipaddr=192.168.1.1
++serverip=192.168.1.254
++loadaddr=0x50000000
++bootargs=console=ttyS0,115200n1 pci=pcie_bus_perf root=/dev/fit0 rootwait ubi.block=0,fit
++bootconf=config-mt7988a-bananapi-bpi-r4-poe
++bootconf_extra=mt7988a-bananapi-bpi-r4-emmc
++bootcmd=if pstore check ; then run boot_recovery ; else run boot_ubi ; fi
++bootdelay=0
++bootfile=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-initramfs-recovery.itb
++bootfile_bl2=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-snand-preloader.bin
++bootfile_fip=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-snand-bl31-uboot.fip
++bootfile_upg=openwrt-mediatek-filogic-bananapi_bpi-r4-poe-squashfs-sysupgrade.itb
++bootled_pwr=green:status
++bootled_rec=blue:status
++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60
++bootmenu_default=0
++bootmenu_delay=0
++bootmenu_title= \e[0;34m( ( ( \e[1;39mOpenWrt\e[0;34m ) ) ) \e[0;36m[SPI-NAND]\e[0m
++bootmenu_0=Initialize environment.=run _firstboot
++bootmenu_0d=Run default boot command.=run boot_default
++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return
++bootmenu_2=Boot production system from NAND.=run boot_production ; run bootmenu_confirm_return
++bootmenu_3=Boot recovery system from NAND.=run boot_recovery ; run bootmenu_confirm_return
++bootmenu_4=Load production system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_production ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
++bootmenu_5=Load recovery system via TFTP then write to NAND.=setenv noboot 1 ; setenv replacevol 1 ; run boot_tftp_recovery ; setenv noboot ; setenv replacevol ; run bootmenu_confirm_return
++bootmenu_6=\e[31mLoad BL31+U-Boot FIP via TFTP then write to NAND.\e[0m=run boot_tftp_write_fip ; run bootmenu_confirm_return
++bootmenu_7=\e[31mLoad BL2 preloader via TFTP then write to NAND.\e[0m=run boot_tftp_write_bl2 ; run bootmenu_confirm_return
++bootmenu_8=\e[31mInstall bootloader, recovery and production to eMMC.\e[0m=if mmc partconf 0 ; then run emmc_init ; else echo "eMMC not detected" ; fi ; run bootmenu_confirm_return
++bootmenu_9=Reboot.=reset
++bootmenu_10=Reset all settings to factory defaults.=run reset_factory ; reset
++boot_first=if button reset ; then led $bootled_rec on ; run boot_tftp_recovery ; setenv flag_recover 1 ; run boot_default ; fi ; bootmenu
++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; setenv replacevol 1 ; run boot_tftp_forever
++boot_production=led $bootled_pwr on ; run ubi_read_production && bootm $loadaddr#$bootconf#$bootconf_extra ; led $bootled_pwr off
++boot_recovery=led $bootled_rec on ; run ubi_read_recovery && bootm $loadaddr#$bootconf ; led $bootled_rec off
++boot_ubi=run boot_production ; run boot_recovery
++boot_tftp_forever=led $bootled_rec on ; while true ; do run boot_tftp_recovery ; sleep 1 ; done
++boot_tftp_production=tftpboot $loadaddr $bootfile_upg && env exists replacevol && iminfo $loadaddr && run ubi_write_production ; if env exists noboot ; then else bootm $loadaddr#$bootconf#$bootconf_extra ; fi
++boot_tftp_recovery=tftpboot $loadaddr $bootfile && env exists replacevol && iminfo $loadaddr && run ubi_write_recovery ; if env exists noboot ; then else bootm $loadaddr#$bootconf ; fi
++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf
++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run ubi_write_fip && run reset_factory
++boot_tftp_write_bl2=tftpboot $loadaddr $bootfile_bl2 && run snand_write_bl2
++part_default=production
++part_recovery=recovery
++reset_factory=ubi part ubi ; mw $loadaddr 0x0 0x800 ; ubi write $loadaddr ubootenv 0x800 ; ubi write $loadaddr ubootenv2 0x800
++snand_write_bl2=mtd erase bl2 && mtd write bl2 $loadaddr 0x0 0x80000 && mtd write bl2 $loadaddr 0x80000 0x80000 && mtd write bl2 $loadaddr 0x100000 0x80000 && mtd write bl2 $loadaddr 0x180000 0x80000
++ubi_create_env=ubi check ubootenv || ubi create ubootenv 0x100000 dynamic 1 ; ubi check ubootenv2 || ubi create ubootenv2 0x100000 dynamic 2
++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi
++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs
++ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery
++ubi_read_emmc_install=ubi check emmc_install && ubi read $loadaddr emmc_install
++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data
++ubi_write_fip=run ubi_remove_rootfs ; ubi check fip && ubi remove fip ; ubi create fip 0x200000 static ; ubi write $loadaddr fip 0x200000
++ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize
++ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize
++mmc_write_vol=imszb $loadaddr image_size && test 0x$image_size -le 0x$part_size && mmc erase 0x$part_addr 0x$image_size && mmc write $loadaddr 0x$part_addr 0x$image_size
++emmc_init=mmc dev 0 && mmc bootbus 0 0 0 0 && run emmc_init_bl && run emmc_init_openwrt ; env default bootcmd ; saveenv ; saveenv
++emmc_init_bl=run ubi_read_emmc_install && setenv fileaddr $loadaddr && run emmc_write_bl2 && setexpr fileaddr $loadaddr + 0x100000 && run emmc_write_fip && setexpr fileaddr $loadaddr + 0x500000 && run emmc_write_hdr
++emmc_init_openwrt=run ubi_read_recovery && iminfo $loadaddr && run emmc_write_recovery ; run ubi_read_production && iminfo $loadaddr && run emmc_write_production
++emmc_write_bl2=mmc partconf 0 1 1 1 && mmc erase 0x0 0x400 && mmc write $fileaddr 0x0 0x400 ; mmc partconf 0 1 1 0
++emmc_write_fip=mmc erase 0x3400 0x2000 && mmc write $fileaddr 0x3400 0x2000 && mmc erase 0x2000 0x800
++emmc_write_hdr=mmc erase 0x0 0x40 && mmc write $fileaddr 0x0 0x40
++emmc_write_production=part start mmc 0 $part_default part_addr && part size mmc 0 $part_default part_size && run mmc_write_vol
++emmc_write_recovery=part start mmc 0 $part_recovery part_addr && part size mmc 0 $part_recovery part_size && run mmc_write_vol
++_init_env=setenv _init_env ; run ubi_create_env ; saveenv ; saveenv
++_firstboot=setenv _firstboot ; run _switch_to_menu ; run _init_env ; run boot_first
++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title
++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title \e[33m$ver\e[0m"
TPL:=rk3568_ddr_1560MHz_v1.21.bin
endef
+define U-Boot/bpi-r2-pro-rk3568
+ $(U-Boot/rk3568/Default)
+ NAME:=Bananapi-R2 Pro
+ BUILD_DEVICES:= \
+ sinovoip_bpi-r2-pro
+endef
+
define U-Boot/nanopi-r5c-rk3568
$(U-Boot/rk3568/Default)
NAME:=NanoPi R5C
rock64-rk3328 \
rock-pi-e-rk3328 \
radxa-cm3-io-rk3566 \
+ bpi-r2-pro-rk3568 \
nanopi-r5c-rk3568 \
nanopi-r5s-rk3568 \
radxa-e25-rk3568
BUILD_DEVICES:=linksprite_a10-pcduino
endef
+define U-Boot/LicheePi_Zero
+ BUILD_SUBTARGET:=cortexa7
+ NAME:=Lichee Pi Zero V3s
+ BUILD_DEVICES:=licheepi_licheepi-zero-dock
+endef
+
define U-Boot/Linksprite_pcDuino3
BUILD_SUBTARGET:=cortexa7
NAME:=Linksprite pcDuino3
Marsboard_A10 \
Mele_M9 \
OLIMEX_A13_SOM \
+ LicheePi_Zero \
Linksprite_pcDuino \
Linksprite_pcDuino3 \
Linksprite_pcDuino3_Nano \
HOST_CPPFLAGS:=-I$(HOST_BUILD_DIR)/lib -I$(HOST_BUILD_DIR)/src $(HOST_CPPFLAGS)
TARGET_CPPFLAGS:=-I$(PKG_BUILD_DIR)/lib -I$(PKG_BUILD_DIR)/src $(TARGET_CPPFLAGS)
+HOST_CXXFLAGS += -std=c++11
+
define Package/gperf
SECTION:=devel
CATEGORY:=Development
PKG_RELEASE:=1
PKG_MAINTAINER:=Tony Ambardar <itugrok@yahoo.com>
-PKG_BUILD_FLAGS:=gc-sections lto
+PKG_BUILD_FLAGS:=no-lto
PKG_BUILD_PARALLEL:=1
PKG_FLAGS:=nonshared
define Package/kselftests-bpf
SECTION:=devel
CATEGORY:=Development
- DEPENDS:= +libelf +zlib +libpthread +librt @!IN_SDK \
- @KERNEL_DEBUG_FS @KERNEL_DEBUG_INFO_BTF @KERNEL_BPF_EVENTS
+ DEPENDS:= \
+ +libelf +zlib +libpthread +librt @!IN_SDK \
+ @KERNEL_DEBUG_FS @KERNEL_DEBUG_INFO_BTF @KERNEL_BPF_EVENTS
TITLE:=Linux Kernel Selftests (BPF)
URL:=http://www.kernel.org
endef
kselftests-bpf is the Linux kernel BPF test suite
endef
-TEST_TARGET = test_verifier
+EXE_TARGETS = test_verifier
+
+MOD_TARGETS = $(if $(call kernel_patchver_ge,6.4),bpf_testmod.ko)
MAKE_PATH:=tools/testing/selftests/bpf
MAKE_VARS = \
ARCH="$(LINUX_KARCH)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
- SAN_CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
+ EXTRA_CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
LDLIBS="$(TARGET_LDFLAGS)" \
TOOLCHAIN_INCLUDE="$(TOOLCHAIN_INC_DIRS)" \
- VMLINUX_BTF="$(LINUX_DIR)/vmlinux"
+ KBUILD_OUTPUT="$(LINUX_DIR)"
MAKE_FLAGS = \
$(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='') \
- O=$(PKG_BUILD_DIR)
+ OUTPUT=$(PKG_BUILD_DIR)
define Build/Compile
+$(MAKE_VARS) \
$(MAKE) $(PKG_JOBS) -C $(LINUX_DIR)/$(MAKE_PATH) \
- $(MAKE_FLAGS) $(TEST_TARGET) ;
+ $(MAKE_FLAGS) $(EXE_TARGETS) $(MOD_TARGETS) ;
endef
define Package/kselftests-bpf/install
- $(INSTALL_DIR) $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(TEST_TARGET) $(1)/usr/bin/
+ $(INSTALL_DIR) $(1)/usr/libexec/$(PKG_NAME)
+ $(foreach tgt,$(MOD_TARGETS), \
+ $(INSTALL_DATA) \
+ $(PKG_BUILD_DIR)/$(tgt) $(1)/usr/libexec/$(PKG_NAME); \
+ )
+ $(foreach tgt,$(EXE_TARGETS), \
+ $(INSTALL_BIN) \
+ $(PKG_BUILD_DIR)/$(tgt) $(1)/usr/libexec/$(PKG_NAME); \
+)
endef
$(eval $(call BuildPackage,kselftests-bpf))
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=bcm27xx-gpu-fw
-PKG_VERSION:=2024-01-11
-PKG_RELEASE:=0968de28716a9b1f106b8492646d0ed0a2800152
+PKG_VERSION:=2024-04-24
+PKG_RELEASE:=969420b4121b522ab33c5001074cc4c2547dafaf
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)/rpi-firmware-$(PKG_RELEASE)
FILE:=$(RPI_FIRMWARE_FILE)-fixup.dat
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=fixup.dat
- HASH:=c28ea955e672e374016dca61d63afa026490f0473a98115908586ab48e324aeb
+ HASH:=94ae3ff8363a6a2832f173241597b6500cf67044d34155a1251fe58671dd6ce7
endef
$(eval $(call Download,fixup_dat))
FILE:=$(RPI_FIRMWARE_FILE)-fixup_cd.dat
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=fixup_cd.dat
- HASH:=3cf1aef5f596ca106203ed5dac9ad45e85929ec55ce44c813588645e174442ec
+ HASH:=2d7c19e46780ef29867f8ed200a94bb77a7982f5bc41219afe864d2303ba3084
endef
$(eval $(call Download,fixup_cd_dat))
FILE:=$(RPI_FIRMWARE_FILE)-fixup_x.dat
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=fixup_x.dat
- HASH:=56525c8feabde1ab86f36bb09bc55171659b2993f94132cf81ffc4293d62269d
+ HASH:=692393562d0650f7d1891ba0143ad0500ccf07129947d386d56350e7ca204d16
endef
$(eval $(call Download,fixup_x_dat))
FILE:=$(RPI_FIRMWARE_FILE)-fixup4.dat
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=fixup4.dat
- HASH:=615f8595801bf52373039f73ad5ad9513f83400d355eb1b2c075c7ae907e927c
+ HASH:=63a4a8f356e2b8ed2850d68b9adf21008ef1dfa7743b22ddc26987e4d3171302
endef
$(eval $(call Download,fixup4_dat))
FILE:=$(RPI_FIRMWARE_FILE)-fixup4cd.dat
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=fixup4cd.dat
- HASH:=3cf1aef5f596ca106203ed5dac9ad45e85929ec55ce44c813588645e174442ec
+ HASH:=2d7c19e46780ef29867f8ed200a94bb77a7982f5bc41219afe864d2303ba3084
endef
$(eval $(call Download,fixup4cd_dat))
FILE:=$(RPI_FIRMWARE_FILE)-fixup4x.dat
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=fixup4x.dat
- HASH:=6d27a4b8ecb78cef9e1f03751b4aaec5ce8749d36988f381145a8a41dbf164ae
+ HASH:=41328f6587c0cd47ae7fa7edab4bf62730dda54caf52ffaa3bfb24ff93b8348b
endef
$(eval $(call Download,fixup4x_dat))
FILE:=$(RPI_FIRMWARE_FILE)-start.elf
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=start.elf
- HASH:=e8348e88522e7a1d0e2b0944ab66d7d8f4f30da98f326e2b3c123522e45f71b2
+ HASH:=8637fb847ff62f69fbb8b98b1beff685b47cf4095580e830724f6a27fb20fee0
endef
$(eval $(call Download,start_elf))
FILE:=$(RPI_FIRMWARE_FILE)-start_cd.elf
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=start_cd.elf
- HASH:=c9b4de3f12bec7808868b898c49f656b5378ddc315f12ccab83d6519bad51680
+ HASH:=6832f57236f6c453cd72eac1f0ab53e265037fb75fc41301448fedb8d505f2b3
endef
$(eval $(call Download,start_cd_elf))
FILE:=$(RPI_FIRMWARE_FILE)-start_x.elf
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=start_x.elf
- HASH:=0b5c06c109984361eeed0ab14d146f686d8aa8da2025689b887e9cb098636db9
+ HASH:=6f72a3fda8cbdacb340676e18a8468b9edd89458173b5ecf3c12b00c147dce40
endef
$(eval $(call Download,start_x_elf))
FILE:=$(RPI_FIRMWARE_FILE)-start4.elf
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=start4.elf
- HASH:=fedc4ecd72c9d21018e210240dcd2e41a8bb5f936fb5674c3351f2a447a22203
+ HASH:=badf4cd8822d1b85ad56ddb9e32e9b4220c88099c8cc0c3e70ae77190571c8ef
endef
$(eval $(call Download,start4_elf))
FILE:=$(RPI_FIRMWARE_FILE)-start4cd.elf
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=start4cd.elf
- HASH:=ea22282a77666801378137a651e7e0b17cc186f63cdbdc8b9bb98749cd12b256
+ HASH:=7d3f13c8412c6b0efdbd3b53439776f3552621cc28ee887caaac539fb063ad8a
endef
$(eval $(call Download,start4cd_elf))
FILE:=$(RPI_FIRMWARE_FILE)-start4x.elf
URL:=$(RPI_FIRMWARE_URL)
URL_FILE:=start4x.elf
- HASH:=c509e73a9cba7af3223dea885f58294bd04845e822aa3d6278500fa4dcdb112f
+ HASH:=c30fbdfedad7180245ff567ccdea953fc1816d0da3ff4701b15071c6f8b47a89
endef
$(eval $(call Download,start4x_elf))
--- /dev/null
+From 7ed95633bff19950069c348b94c9c13164a57a2a Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Wed, 18 Jan 2023 20:20:39 +0100
+Subject: [PATCH] linux/netlink: drop NL_SET_ERR_MSG for kernel modules
+
+We don't need NL_SET_ERR_MSG_MOD for bpf modules and we can drop it to
+solve missing KBUILD_MODNAME define.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ include/linux/netlink.h | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/include/linux/netlink.h b/include/linux/netlink.h
+index 61b1c7f..93561fb 100644
+--- a/include/linux/netlink.h
++++ b/include/linux/netlink.h
+@@ -98,9 +98,6 @@ struct netlink_ext_ack {
+ __extack->_msg = __msg; \
+ } while (0)
+
+-#define NL_SET_ERR_MSG_MOD(extack, msg) \
+- NL_SET_ERR_MSG((extack), KBUILD_MODNAME ": " msg)
+-
+ #define NL_SET_BAD_ATTR_POLICY(extack, attr, pol) do { \
+ if ((extack)) { \
+ (extack)->bad_attr = (attr); \
+--
+2.38.1
+
--- /dev/null
+From 6e7cd9c0abffea55e39a4160949bc6fba972d161 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Thu, 19 Jan 2023 13:37:46 +0100
+Subject: [PATCH] net/flow_offload: use NL_SET_ERR_MSG instead of
+ NL_SET_ERR_MSG_MOD
+
+Use NL_SET_ERR_MSG instead of NL_SET_ERR_MSG_MOD for bpf modules as
+kernel modules are not supported.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ include/net/flow_offload.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
+index 7a2b022..f17c485 100644
+--- a/include/net/flow_offload.h
++++ b/include/net/flow_offload.h
+@@ -321,7 +321,7 @@ flow_action_mixed_hw_stats_check(const struct flow_action *action,
+
+ flow_action_for_each(i, action_entry, action) {
+ if (i && action_entry->hw_stats != last_hw_stats) {
+- NL_SET_ERR_MSG_MOD(extack, "Mixing HW stats types for actions is not supported");
++ NL_SET_ERR_MSG(extack, "Mixing HW stats types for actions is not supported");
+ return false;
+ }
+ last_hw_stats = action_entry->hw_stats;
+@@ -356,11 +356,11 @@ __flow_action_hw_stats_check(const struct flow_action *action,
+
+ if (!check_allow_bit &&
+ ~action_entry->hw_stats & FLOW_ACTION_HW_STATS_ANY) {
+- NL_SET_ERR_MSG_MOD(extack, "Driver supports only default HW stats type \"any\"");
++ NL_SET_ERR_MSG(extack, "Driver supports only default HW stats type \"any\"");
+ return false;
+ } else if (check_allow_bit &&
+ !(action_entry->hw_stats & BIT(allow_bit))) {
+- NL_SET_ERR_MSG_MOD(extack, "Driver does not support selected HW stats type");
++ NL_SET_ERR_MSG(extack, "Driver does not support selected HW stats type");
+ return false;
+ }
+ return true;
+--
+2.38.1
+
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/version.h>
#include <linux/dmi.h>
#include <linux/string.h>
#define IFXMIPS_FUSE_BASE_ADDR IFX_FUSE_BASE_ADDR
#define IFXMIPS_ICU_IM0_IER IFX_ICU_IM0_IER
#define IFXMIPS_ICU_IM2_IER IFX_ICU_IM2_IER
-#define LTQ_MEI_INT IFX_MEI_INT
-#define LTQ_MEI_DYING_GASP_INT IFX_MEI_DYING_GASP_INT
#define LTQ_MEI_BASE_ADDR IFX_MEI_SPACE_ACCESS
#define IFXMIPS_PMU_PWDCR IFX_PMU_PWDCR
#define IFXMIPS_MPS_CHIPID IFX_MPS_CHIPID
#define LTQ_PMU_BASE_ADDR 0x1F102000
-#ifdef CONFIG_DANUBE
-# define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
-# define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
-# define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
-#endif
-
-#ifdef CONFIG_AMAZON_SE
-# define LTQ_MEI_INT (INT_NUM_IM2_IRL0 + 9)
-# define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM2_IRL0 + 11)
-# define LTQ_USB_OC_INT (INT_NUM_IM2_IRL0 + 20)
-#endif
-
-#ifdef CONFIG_AR9
-# define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
-# define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
-# define LTQ_USB_OC_INT (INT_NUM_IM1_IRL0 + 28)
-#endif
-
-#ifndef LTQ_MEI_INT
-#error "Unknown Lantiq ARCH!"
-#endif
-
#define LTQ_RCU_RST_REQ_DFE (1 << 7)
#define LTQ_RCU_RST_REQ_AFE (1 << 11)
im2_register = (*LTQ_ICU_IM2_IER) & (1 << 20);
/* Turn off irq */
- disable_irq (LTQ_USB_OC_INT);
+ disable_irq (pDev->nIrq[IFX_USB_OC]);
disable_irq (pDev->nIrq[IFX_DYING_GASP]);
IFX_MEI_RunArc (pDev);
MEI_WAIT_EVENT_TIMEOUT (DSL_DEV_PRIVATE(pDev)->wait_queue_modemready, 1000);
- MEI_MASK_AND_ACK_IRQ (LTQ_USB_OC_INT);
+ MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_USB_OC]);
MEI_MASK_AND_ACK_IRQ (pDev->nIrq[IFX_DYING_GASP]);
/* Re-enable irq */
sizeof (smmu_mem_info_t) * MAX_BAR_REGISTERS);
if (num == 0) {
- pDev->nIrq[IFX_DFEIR] = LTQ_MEI_INT;
- pDev->nIrq[IFX_DYING_GASP] = LTQ_MEI_DYING_GASP_INT;
pDev->base_address = KSEG1 + LTQ_MEI_BASE_ADDR;
/* Power up MEI */
{
int i = 0;
static struct class *dsl_class;
+ DSL_DEV_Device_t *pDev;
pr_info("IFX MEI Version %ld.%02ld.%02ld\n", bsp_mei_version.major, bsp_mei_version.minor, bsp_mei_version.revision);
for (i = 0; i < BSP_MAX_DEVICES; i++) {
+ pDev = &dsl_devices[i];
+
+ pDev->nIrq[IFX_DFEIR] = platform_get_irq(pdev, 0);
+ if (pDev->nIrq[IFX_DFEIR] < 0) {
+ IFX_MEI_EMSG("Failed to get DFEIR irq!\n");
+ return pDev->nIrq[IFX_DFEIR];
+ }
+
+ pDev->nIrq[IFX_DYING_GASP] = platform_get_irq(pdev, 1);
+ if (pDev->nIrq[IFX_DYING_GASP] < 0) {
+ IFX_MEI_EMSG("Failed to get DYING_GASP irq!\n");
+ return pDev->nIrq[IFX_DYING_GASP];
+ }
+
+ pDev->nIrq[IFX_USB_OC] = platform_get_irq(pdev, 2);
+ if (pDev->nIrq[IFX_USB_OC] < 0) {
+ IFX_MEI_EMSG("Failed to get USB_OC irq!\n");
+ return pDev->nIrq[IFX_USB_OC];
+ }
+
if (IFX_MEI_InitDevice (i) != 0) {
IFX_MEI_EMSG("Init device fail!\n");
return -EIO;
DSL_int_t nInUse; /* modem state, update by bsp driver, */
DSL_void_t *pPriv;
DSL_uint32_t base_address; /* mei base address */
- DSL_int_t nIrq[2]; /* irq number */
+ DSL_int_t nIrq[3]; /* irq number */
#define IFX_DFEIR 0
#define IFX_DYING_GASP 1
+#define IFX_USB_OC 2
DSL_DEV_MeiDebug_t lop_debugwr; /* dying gasp */
struct module *owner;
} DSL_DEV_Device_t; /* ifx_adsl_device_t */
nErrCode = DSL_DRV_PM_HistoryDelete(pContext, EpData.pHistShowtime );
--- a/src/device/drv_dsl_cpe_device_danube.c
+++ b/src/device/drv_dsl_cpe_device_danube.c
-@@ -3193,7 +3193,7 @@ DSL_Error_t DSL_DRV_DEV_AutobootHandleTraining(
+@@ -3193,7 +3193,7 @@ DSL_Error_t DSL_DRV_DEV_AutobootHandleTr
DSL_DEV_NUM(pContext)));
}
#endif /* INCLUDE_DSL_DELT*/
--- a/src/g997/drv_dsl_cpe_api_g997_danube.c
+++ b/src/g997/drv_dsl_cpe_api_g997_danube.c
-@@ -1984,41 +1984,53 @@ DSL_Error_t DSL_DRV_DEV_G997_DeltHlogGet(
+@@ -1984,41 +1984,53 @@ DSL_Error_t DSL_DRV_DEV_G997_DeltHlogGet
{
if (nDirection == DSL_DOWNSTREAM)
{
--- a/src/g997/drv_dsl_cpe_api_g997_danube.c
+++ b/src/g997/drv_dsl_cpe_api_g997_danube.c
-@@ -2512,6 +2524,7 @@ DSL_Error_t DSL_DRV_DEV_G997_PowerManagementStateForcedTrigger(
+@@ -2524,6 +2524,7 @@ DSL_Error_t DSL_DRV_DEV_G997_PowerManage
else
{
/* read L3 request failure reason */
nErrCode = DSL_DRV_DANUBE_CmvRead(pContext, DSL_CMV_GROUP_STAT,
DSL_CMV_ADDRESS_STAT_L3_FAILURE_REASON, 0, 1, &nVal);
DSL_DEBUG(DSL_DBG_MSG,
-@@ -2525,11 +2538,13 @@ DSL_Error_t DSL_DRV_DEV_G997_PowerManagementStateForcedTrigger(
+@@ -2537,11 +2538,13 @@ DSL_Error_t DSL_DRV_DEV_G997_PowerManage
nErrCode = DSL_ERR_MSG_EXCHANGE;
break;
}
--- /dev/null
+--- a/src/common/drv_dsl_cpe_os_linux.c
++++ b/src/common/drv_dsl_cpe_os_linux.c
+@@ -556,7 +556,11 @@ static int DSL_DRV_KernelThreadStartup(v
+ retVal = pThrCntrl->pThrFct(&pThrCntrl->thrParams);
+ pThrCntrl->thrParams.bRunning = 0;
+
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0))
+ complete_and_exit(&pThrCntrl->thrCompletion, (long)retVal);
++#else
++ kthread_complete_and_exit(&pThrCntrl->thrCompletion, (long)retVal);
++#endif
+
+ DSL_DEBUG( DSL_DBG_MSG,
+ (DSL_NULL, "EXIT - Kernel Thread Startup <%s>" DSL_DRV_CRLF,
#define IFXMIPS_ATM_CORE_H
-#define INT_NUM_IM2_IRL24 (INT_NUM_IM2_IRL0 + 24)
-#define INT_NUM_IM2_IRL13 (INT_NUM_IM2_IRL0 + 13)
#define CONFIG_IFXMIPS_DSL_CPE_MEI
#define IFX_REG_W32(_v, _r) __raw_writel((_v), (volatile unsigned int *)(_r))
#define IFX_REG_R32(_r) __raw_readl((volatile unsigned int *)(_r))
void *oam_buf_base;
void *tx_desc_base;
void *tx_skb_base;
+
+ int irq;
};
#include "ifxmips_atm_ppe_common.h"
#define EMA_ALIGNMENT 4
-/*
- * Mailbox IGU1 Interrupt
- */
-#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL13
-
#endif // IFXMIPS_ATM_PPE_AMAZON_SE_H
#define EMA_ALIGNMENT 4
-/*
- * Mailbox IGU1 Interrupt
- */
-#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
-
#endif // IFXMIPS_ATM_PPE_AR9_H
#define EMA_ALIGNMENT 4
-/*
- * Mailbox IGU1 Interrupt
- */
-#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
-
#endif // IFXMIPS_ATM_PPE_DANUBE_H
#define PDMA_ALIGNMENT 4
#define EMA_ALIGNMENT PDMA_ALIGNMENT
-/*
- * Mailbox IGU1 Interrupt
- */
-#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
-
#endif // IFXMIPS_ATM_PPE_VR9_H
*MBOX_IGU1_ISRC = (1 << RX_DMA_CH_AAL) | (1 << RX_DMA_CH_OAM);
*MBOX_IGU1_IER = (1 << RX_DMA_CH_AAL) | (1 << RX_DMA_CH_OAM);
- enable_irq(PPE_MAILBOX_IGU1_INT);
+ enable_irq(g_atm_priv_data.irq);
}
/* set port */
/* disable irq */
if ( g_atm_priv_data.conn_table == 0 )
- disable_irq(PPE_MAILBOX_IGU1_INT);
+ disable_irq(g_atm_priv_data.irq);
/* release bandwidth */
switch ( vcc->qos.txtp.traffic_class )
else if (*MBOX_IGU1_ISR >> (FIRST_QSB_QID + 16)) /* TX queue */
tasklet_schedule(&g_dma_tasklet);
else
- enable_irq(PPE_MAILBOX_IGU1_INT);
+ enable_irq(g_atm_priv_data.irq);
}
static irqreturn_t mailbox_irq_handler(int irq, void *dev_id)
if ( !*MBOX_IGU1_ISR )
return IRQ_HANDLED;
- disable_irq_nosync(PPE_MAILBOX_IGU1_INT);
+ disable_irq_nosync(g_atm_priv_data.irq);
tasklet_schedule(&g_dma_tasklet);
return IRQ_HANDLED;
}
}
+ g_atm_priv_data.irq = platform_get_irq(pdev, 0);
+ if (g_atm_priv_data.irq < 0) {
+ pr_err("platform_get_irq fail");
+ goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
+ }
+
/* register interrupt handler */
- ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, 0, "atm_mailbox_isr", &g_atm_priv_data);
+ ret = request_irq(g_atm_priv_data.irq, mailbox_irq_handler, 0, "atm_mailbox_isr", &g_atm_priv_data);
if ( ret ) {
if ( ret == -EBUSY ) {
pr_err("IRQ may be occupied by other driver, please reconfig to disable it.\n");
} else {
- pr_err("request_irq fail irq:%d\n", PPE_MAILBOX_IGU1_INT);
+ pr_err("request_irq fail irq:%d\n", g_atm_priv_data.irq);
}
goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
}
- disable_irq(PPE_MAILBOX_IGU1_INT);
+ disable_irq(g_atm_priv_data.irq);
ret = ops->start(0);
return 0;
PP32_START_FAIL:
- free_irq(PPE_MAILBOX_IGU1_INT, &g_atm_priv_data);
+ free_irq(g_atm_priv_data.irq, &g_atm_priv_data);
REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL:
ATM_DEV_REGISTER_FAIL:
while ( port_num-- > 0 )
ops->stop(0);
- free_irq(PPE_MAILBOX_IGU1_INT, &g_atm_priv_data);
+ free_irq(g_atm_priv_data.irq, &g_atm_priv_data);
for ( port_num = 0; port_num < ATM_PORT_NUMBER; port_num++ )
atm_dev_deregister(g_atm_priv_data.port[port_num].dev);
--- a/ifxmips_ptm_adsl.c
+++ b/ifxmips_ptm_adsl.c
-@@ -180,7 +180,7 @@ static int proc_read_version(char *, char **, off_t, int, int *, void *);
+@@ -180,7 +180,7 @@ static int proc_read_version(char *, cha
static int proc_read_wanmib(char *, char **, off_t, int, int *, void *);
static int proc_write_wanmib(struct file *, const char *, unsigned long, void *);
#endif
static int proc_read_genconf(char *, char **, off_t, int, int *, void *);
#endif
#if defined(ENABLE_DBG_PROC) && ENABLE_DBG_PROC
-@@ -191,8 +191,8 @@ static int proc_write_wanmib(struct file *, const char *, unsigned long, void *)
+@@ -191,8 +191,8 @@ static int proc_write_wanmib(struct file
/*
* Proc Help Functions
*/
static INLINE int strincmp(const char *, const char *, int);
#endif
static INLINE int ifx_ptm_version(char *);
-@@ -1159,8 +1159,6 @@ static int proc_write_dbg(struct file *file, const char *buf, unsigned long coun
+@@ -1159,8 +1159,6 @@ static int proc_write_dbg(struct file *f
return count;
}
static INLINE int stricmp(const char *p1, const char *p2)
{
int c1, c2;
-@@ -1178,7 +1176,6 @@ static INLINE int stricmp(const char *p1, const char *p2)
+@@ -1178,7 +1176,6 @@ static INLINE int stricmp(const char *p1
return *p1 - *p2;
}
static void ptm_setup(struct net_device *dev, int ndev)
{
+ u8 addr[ETH_ALEN];
+
#if defined(CONFIG_IFXMIPS_DSL_CPE_MEI) || defined(CONFIG_IFXMIPS_DSL_CPE_MEI_MODULE)
netif_carrier_off(dev);
#endif
dev->netdev_ops = &g_ptm_netdev_ops;
/* Allow up to 1508 bytes, for RFC4638 */
dev->max_mtu = ETH_DATA_LEN + 8;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0))
netif_napi_add(dev, &g_ptm_priv_data.itf[ndev].napi, ptm_napi_poll, 25);
+#else
+ netif_napi_add_weight(dev, &g_ptm_priv_data.itf[ndev].napi, ptm_napi_poll, 25);
+#endif
dev->watchdog_timeo = ETH_WATCHDOG_TIMEOUT;
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x20;
- dev->dev_addr[2] = 0xda;
- dev->dev_addr[3] = 0x86;
- dev->dev_addr[4] = 0x23;
- dev->dev_addr[5] = 0x75 + ndev;
+ addr[0] = 0x00;
+ addr[1] = 0x20;
+ addr[2] = 0xda;
+ addr[3] = 0x86;
+ addr[4] = 0x23;
+ addr[5] = 0x75 + ndev;
+ eth_hw_addr_set(dev, addr);
}
static struct net_device_stats *ptm_get_stats(struct net_device *dev)
goto REGISTER_NETDEV_FAIL;
}
+ g_ptm_priv_data.irq = platform_get_irq(pdev, 0);
+ if (g_ptm_priv_data.irq < 0) {
+ err("platform_get_irq fail");
+ goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
+ }
+
/* register interrupt handler */
- ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, 0, "ptm_mailbox_isr", &g_ptm_priv_data);
+ ret = request_irq(g_ptm_priv_data.irq, mailbox_irq_handler, 0, "ptm_mailbox_isr", &g_ptm_priv_data);
if ( ret ) {
if ( ret == -EBUSY ) {
err("IRQ may be occupied by other driver, please reconfig to disable it.");
}
goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
}
- disable_irq(PPE_MAILBOX_IGU1_INT);
+ disable_irq(g_ptm_priv_data.irq);
ret = ifx_pp32_start(0);
if ( ret ) {
IFX_REG_W32(0, MBOX_IGU1_IER);
IFX_REG_W32(~0, MBOX_IGU1_ISRC);
- enable_irq(PPE_MAILBOX_IGU1_INT);
+ enable_irq(g_ptm_priv_data.irq);
proc_file_create();
return 0;
PP32_START_FAIL:
- free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
+ free_irq(g_ptm_priv_data.irq, &g_ptm_priv_data);
REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL:
i = ARRAY_SIZE(g_net_dev);
REGISTER_NETDEV_FAIL:
ifx_pp32_stop(0);
- free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
+ free_irq(g_ptm_priv_data.irq, &g_ptm_priv_data);
for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ )
unregister_netdev(g_net_dev[i]);
#include "ifxmips_ptm_fw_regs_adsl.h"
#define CONFIG_IFXMIPS_DSL_CPE_MEI
-#define INT_NUM_IM2_IRL24 (INT_NUM_IM2_IRL0 + 24)
#define IFX_REG_W32(_v, _r) __raw_writel((_v), (volatile unsigned int *)(_r))
#define IFX_REG_R32(_r) __raw_readl((volatile unsigned int *)(_r))
struct ptm_priv_data {
struct ptm_itf itf[MAX_ITF_NUMBER];
+ int irq;
void *rx_desc_base;
void *tx_desc_base;
#define EMA_ALIGNMENT 4
-/*
- * Mailbox IGU1 Interrupt
- */
-#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL13
-
#endif // IFXMIPS_PTM_PPE_AMAZON_SE_H
#define SW_P2_CTL SW_REG(0x00C)
-/*
- * Mailbox IGU1 Interrupt
- */
-#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
-
-
#endif // IFXMIPS_PTM_PPE_AR9_H
#define EMA_ALIGNMENT 4
-/*
- * Mailbox IGU1 Interrupt
- */
-#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
-
#endif // IFXMIPS_PTM_PPE_DANUBE_H
#define PDMA_ALIGNMENT 32 // same as Central DMA because of descriptor swap
#define EMA_ALIGNMENT PDMA_ALIGNMENT
-/*
- * Mailbox IGU1 Interrupt
- */
-#define PPE_MAILBOX_IGU1_INT INT_NUM_IM2_IRL24
-
#endif // IFXMIPS_PTM_PPE_VR9_H
dev->netdev_ops = &g_ptm_netdev_ops;
/* Allow up to 1508 bytes, for RFC4638 */
dev->max_mtu = ETH_DATA_LEN + 8;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0))
netif_napi_add(dev, &g_ptm_priv_data.itf[ndev].napi, ptm_napi_poll, 16);
+#else
+ netif_napi_add_weight(dev, &g_ptm_priv_data.itf[ndev].napi, ptm_napi_poll, 16);
+#endif
dev->watchdog_timeo = ETH_WATCHDOG_TIMEOUT;
addr[0] = 0x00;
goto REGISTER_NETDEV_FAIL;
}
+ g_ptm_priv_data.irq = platform_get_irq(pdev, 0);
+ if (g_ptm_priv_data.irq < 0) {
+ err("platform_get_irq fail");
+ goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
+ }
+
/* register interrupt handler */
- ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, 0, "ptm_mailbox_isr", &g_ptm_priv_data);
+ ret = request_irq(g_ptm_priv_data.irq, mailbox_irq_handler, 0, "ptm_mailbox_isr", &g_ptm_priv_data);
if ( ret ) {
if ( ret == -EBUSY ) {
err("IRQ may be occupied by other driver, please reconfig to disable it.");
}
goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
}
- disable_irq(PPE_MAILBOX_IGU1_INT);
+ disable_irq(g_ptm_priv_data.irq);
ret = ifx_pp32_start(0);
if ( ret ) {
IFX_REG_W32(1 << 16, MBOX_IGU1_IER); // enable SWAP interrupt
IFX_REG_W32(~0, MBOX_IGU1_ISRC);
- enable_irq(PPE_MAILBOX_IGU1_INT);
+ enable_irq(g_ptm_priv_data.irq);
ifx_mei_atm_showtime_check(&g_showtime, &port_cell, &g_xdata_addr);
if ( g_showtime ) {
return 0;
PP32_START_FAIL:
- free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
+ free_irq(g_ptm_priv_data.irq, &g_ptm_priv_data);
REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL:
i = ARRAY_SIZE(g_net_dev);
REGISTER_NETDEV_FAIL:
ifx_pp32_stop(0);
- free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
+ free_irq(g_ptm_priv_data.irq, &g_ptm_priv_data);
for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ )
unregister_netdev(g_net_dev[i]);
#include "ifxmips_ptm_ppe_common.h"
#include "ifxmips_ptm_fw_regs_vdsl.h"
-#define INT_NUM_IM2_IRL24 (INT_NUM_IM2_IRL0 + 24)
-
#define IFX_REG_W32(_v, _r) __raw_writel((_v), (volatile unsigned int *)(_r))
#define IFX_REG_R32(_r) __raw_readl((volatile unsigned int *)(_r))
#define IFX_REG_W32_MASK(_clr, _set, _r) IFX_REG_W32((IFX_REG_R32((_r)) & ~(_clr)) | (_set), (_r))
struct ptm_priv_data {
struct ptm_itf itf[MAX_ITF_NUMBER];
+ int irq;
};
#endif
/* add MEI CPE debug/printout part */
-@@ -1718,8 +1718,8 @@ static void MEI_MeminfoProcPerDevGet(struct seq_file *s)
+@@ -1718,8 +1718,8 @@ static void MEI_MeminfoProcPerDevGet(str
", CRC = 0x%08X"
#endif
MEI_DRV_CRLF,
#if (MEI_SUPPORT_OPTIMIZED_FW_DL == 1)
--- a/src/drv_mei_cpe_download_vrx.c
+++ b/src/drv_mei_cpe_download_vrx.c
-@@ -3139,9 +3139,9 @@ IFX_int32_t MEI_DEV_IoctlFirmwareDownload(
+@@ -3139,9 +3139,9 @@ IFX_int32_t MEI_DEV_IoctlFirmwareDownloa
{
IFX_int32_t ret = 0;
MEI_DEV_T *pMeiDev = pMeiDynCntrl->pMeiDev;
--- /dev/null
+--- a/src/drv_mei_cpe_linux.c
++++ b/src/drv_mei_cpe_linux.c
+@@ -1873,7 +1873,11 @@ static int mei_seq_single_show(struct se
+
+ static int mei_proc_single_open(struct inode *inode, struct file *file)
+ {
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0))
+ return single_open(file, mei_seq_single_show, PDE_DATA(inode));
++#else
++ return single_open(file, mei_seq_single_show, pde_data(inode));
++#endif
+ }
+
+ static void mei_proc_entry_create(struct proc_dir_entry *parent_node,
+--- a/src/drv_mei_cpe_linux_proc_config.c
++++ b/src/drv_mei_cpe_linux_proc_config.c
+@@ -1036,7 +1036,11 @@ static int mei_seq_single_show(struct se
+
+ static int mei_proc_single_open(struct inode *inode, struct file *file)
+ {
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,17,0))
+ return single_open(file, mei_seq_single_show, PDE_DATA(inode));
++#else
++ return single_open(file, mei_seq_single_show, pde_data(inode));
++#endif
+ }
+
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0))
--- /dev/null
+--- a/src/drv_mei_cpe_msg_process.c
++++ b/src/drv_mei_cpe_msg_process.c
+@@ -3524,7 +3524,12 @@ IFX_int32_t MEI_IoctlCmdMsgWrite(
+ {
+ if (bInternCall)
+ {
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0))
+ memcpy(pDestPtr, pUserMsg->pPayload, pUserMsg->paylSize_byte);
++#else
++ unsafe_memcpy(pDestPtr, pUserMsg->pPayload, pUserMsg->paylSize_byte,
++ /* field-spanning writing is used here intentionally */);
++#endif
+ }
+ else
+ {
--- /dev/null
+--- a/src/drv_vmmc_api.h
++++ b/src/drv_vmmc_api.h
+@@ -149,17 +149,6 @@ DECLARE_TRACE_GROUP(VMMC);
+ return code; \
+ }while(0)
+
+-/*******************************************************************************
+-Description:
+- always returns the absolute value of argument given
+-Arguments:
+- x - argument
+-Return:
+- absolute value of x
+-*******************************************************************************/
+-/* define ABS */
+-#define ABS(x) (((x) < 0) ? -(x) : (x))
+-
+ /* regular format macros */
+ /*******************************************************************************
+ Description:
--- /dev/null
+--- a/src/drv_vmmc_init.c
++++ b/src/drv_vmmc_init.c
+@@ -202,11 +202,20 @@ IFX_int32_t VMMC_GetDevice (IFX_uint16_t
+ /**
+ Wrapper for the voice buffer get function that sets the FW as owner.
+ */
+-static IFX_void_t* vmmc_WrapperVoiceBufferGet (IFX_void_t)
++static IFX_void_t* vmmc_WrapperVoiceBufferGet (IFX_size_t size,
++ IFX_int32_t priority)
+ {
+ return IFX_TAPI_VoiceBufferGetWithOwnerId (IFX_TAPI_BUFFER_OWNER_FW);
+ }
+
++/**
++ Wrapper for the voice buffer get function that sets the FW as owner.
++*/
++static IFX_void_t vmmc_WrapperVoiceBufferPut (const IFX_void_t *ptr)
++{
++ IFX_TAPI_VoiceBufferPut ((IFX_void_t *)ptr);
++}
++
+
+ /**
+ Wrapper for the voice buffer free all function freeing all buffers that
+@@ -263,10 +272,8 @@ IFX_int32_t VMMC_ChipAccessInit(VMMC_DEV
+
+ /* Register the buffer handler. */
+ #ifdef USE_BUFFERPOOL
+- ifx_mps_bufman_register((IFX_void_t* (*)(IFX_size_t, IFX_int32_t))
+- vmmc_WrapperVoiceBufferGet,
+- (IFX_void_t (*)(const IFX_void_t*))
+- IFX_TAPI_VoiceBufferPut,
++ ifx_mps_bufman_register(vmmc_WrapperVoiceBufferGet,
++ vmmc_WrapperVoiceBufferPut,
+ sizeof(PACKET), POBX_BUFFER_THRESHOLD);
+ ifx_mps_register_bufman_freeall_callback (vmmc_WrapperVoiceBufferFreeAll);
+ #else
--- /dev/null
+--- a/src/drv_vmmc_fw_commands.h
++++ b/src/drv_vmmc_fw_commands.h
+@@ -4628,26 +4628,28 @@ struct RES_DTMFATG_COEF
+ struct CDM_RES_DTMFATG_DATA
+ {
+ CMD_HEAD_BE;
+- /** Frequency 1 1st Tone or Dual Tone Control Word 1 */
+- IFX_uint16_t FREQ11_DTC1;
+- /** Frequency 2 1st Tone or Dual Tone Control Word 2 */
+- IFX_uint16_t FREQ21_DTC2;
+- /** Frequency 1 2nd Tone */
+- IFX_uint16_t FREQ12_DTC3;
+- /** Frequency 2 2nd Tone */
+- IFX_uint16_t FREQ22_DTC4;
+- /** Frequency 1 3rd Tone */
+- IFX_uint16_t FREQ13_DTC5;
+- /** Frequency 2 3nd Tone */
+- IFX_uint16_t FREQ23_DTC6;
+- /** Frequency 1 4th Tone */
+- IFX_uint16_t FREQ14_DTC7;
+- /** Frequency 2 4th Tone */
+- IFX_uint16_t FREQ24_DTC8;
+- /** Frequency 1 5th Tone */
+- IFX_uint16_t FREQ15_DTC9;
+- /** Frequency 2 5th Tone */
+- IFX_uint16_t FREQ25_DTC10;
++ struct_group(FREQS,
++ /** Frequency 1 1st Tone or Dual Tone Control Word 1 */
++ IFX_uint16_t FREQ11_DTC1;
++ /** Frequency 2 1st Tone or Dual Tone Control Word 2 */
++ IFX_uint16_t FREQ21_DTC2;
++ /** Frequency 1 2nd Tone */
++ IFX_uint16_t FREQ12_DTC3;
++ /** Frequency 2 2nd Tone */
++ IFX_uint16_t FREQ22_DTC4;
++ /** Frequency 1 3rd Tone */
++ IFX_uint16_t FREQ13_DTC5;
++ /** Frequency 2 3nd Tone */
++ IFX_uint16_t FREQ23_DTC6;
++ /** Frequency 1 4th Tone */
++ IFX_uint16_t FREQ14_DTC7;
++ /** Frequency 2 4th Tone */
++ IFX_uint16_t FREQ24_DTC8;
++ /** Frequency 1 5th Tone */
++ IFX_uint16_t FREQ15_DTC9;
++ /** Frequency 2 5th Tone */
++ IFX_uint16_t FREQ25_DTC10;
++ );
+ } __PACKED__ ;
+
+
+--- a/src/drv_vmmc_sig_dtmfg.c
++++ b/src/drv_vmmc_sig_dtmfg.c
+@@ -742,10 +742,8 @@ IFX_int32_t irq_VMMC_SIG_DtmfOnRequest(V
+ /* Get a pointer to the data area which is behind the header of the cmd */
+ pAtgCmd = &pDtmfAtgData->FREQ11_DTC1;
+
+- /* Wipe the data area in the command. The size of this area is
+- command size - header size. */
+- /*lint -e(419) */
+- memset (pAtgCmd, 0x00, sizeof(CDM_RES_DTMFATG_DATA_t) - CMD_HDR_CNT);
++ /* Wipe the data area in the command. */
++ memset (&pDtmfAtgData->FREQS, 0x00, sizeof(pDtmfAtgData->FREQS));
+
+ /* Fill the data area */
+ if (pDtmf->bByteMode == IFX_TRUE)
--- /dev/null
+--- a/src/mps/drv_mps_vmmc_linux.c
++++ b/src/mps/drv_mps_vmmc_linux.c
+@@ -104,6 +104,10 @@ extern irqreturn_t ifx_mps_vc_irq (IFX_i
+ extern IFX_void_t ifx_mps_shutdown (IFX_void_t);
+ extern IFX_int32_t ifx_mps_event_activation_poll (mps_devices type,
+ MbxEventRegs_s * act);
++extern unsigned int ltq_get_mps_ad0_irq(void);
++extern unsigned int ltq_get_mps_ad1_irq(void);
++extern unsigned int ltq_get_mps_vc_irq(int idx);
++
+ mps_mbx_dev *ifx_mps_get_device (mps_devices type);
+
+ #ifdef CONFIG_PROC_FS
+@@ -2260,7 +2264,7 @@ IFX_int32_t __init ifx_mps_init_module (
+ /* reset the device before initializing the device driver */
+ ifx_mps_reset ();
+
+- result = request_irq (INT_NUM_IM4_IRL18,
++ result = request_irq (ltq_get_mps_ad0_irq(),
+ #ifdef LINUX_2_6
+ ifx_mps_ad0_irq, 0x0
+ #else /* */
+@@ -2270,7 +2274,7 @@ IFX_int32_t __init ifx_mps_init_module (
+ , "mps_mbx ad0", &ifx_mps_dev);
+ if (result)
+ return result;
+- result = request_irq (INT_NUM_IM4_IRL19,
++ result = request_irq (ltq_get_mps_ad1_irq(),
+ #ifdef LINUX_2_6
+ ifx_mps_ad1_irq, 0x0
+ #else /* */
+@@ -2285,7 +2289,7 @@ IFX_int32_t __init ifx_mps_init_module (
+ for (i = 0; i < 4; ++i)
+ {
+ sprintf (&voice_channel_int_name[i][0], "mps_mbx vc%d", i);
+- result = request_irq (INT_NUM_IM4_IRL14 + i,
++ result = request_irq (ltq_get_mps_vc_irq(i),
+ #ifdef LINUX_2_6
+ ifx_mps_vc_irq, 0x0
+ #else /* */
+@@ -2446,13 +2450,13 @@ ifx_mps_cleanup_module (IFX_void_t)
+ ifx_mps_release_structures (&ifx_mps_dev);
+
+ /* release all interrupts at the system */
+- free_irq (INT_NUM_IM4_IRL18, &ifx_mps_dev);
+- free_irq (INT_NUM_IM4_IRL19, &ifx_mps_dev);
++ free_irq (ltq_get_mps_ad0_irq(), &ifx_mps_dev);
++ free_irq (ltq_get_mps_ad1_irq(), &ifx_mps_dev);
+
+ /* register status interrupts for voice channels */
+ for (i = 0; i < 4; ++i)
+ {
+- free_irq (INT_NUM_IM4_IRL14 + i, &ifx_mps_dev);
++ free_irq (ltq_get_mps_vc_irq(i), &ifx_mps_dev);
+ }
+ #ifdef CONFIG_PROC_FS
+ #if CONFIG_MPS_HISTORY_SIZE > 0
+--- a/src/mps/drv_mps_vmmc_common.c
++++ b/src/mps/drv_mps_vmmc_common.c
+@@ -134,6 +134,8 @@ extern IFX_void_t mask_and_ack_danube_ir
+
+ #endif /* */
+
++extern unsigned int ltq_get_mps_vc_irq(int idx);
++
+ extern void sys_hw_setup (void);
+
+ extern IFXOS_event_t fw_ready_evt;
+@@ -2979,7 +2981,7 @@ irqreturn_t ifx_mps_ad1_irq (IFX_int32_t
+ */
+ irqreturn_t ifx_mps_vc_irq (IFX_int32_t irq, mps_comm_dev * pDev)
+ {
+- IFX_uint32_t chan = irq - INT_NUM_IM4_IRL14;
++ IFX_uint32_t chan = irq - ltq_get_mps_vc_irq(0);
+ mps_mbx_dev *mbx_dev = (mps_mbx_dev *) & (pMPSDev->voice_mb[chan]);
+ MPS_VCStatReg_u MPS_VCStatusReg;
+ MbxEventRegs_s events;
+--- a/src/mps/drv_mps_vmmc_device.h
++++ b/src/mps/drv_mps_vmmc_device.h
+@@ -69,9 +69,6 @@
+ # define IFX_MPS_CVC3SR IFXMIPS_MPS_CVC3SR
+ # define IFX_MPS_SAD0SR IFXMIPS_MPS_SAD0SR
+ /* interrupt vectors */
+-# define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14)
+-# define INT_NUM_IM4_IRL18 (INT_NUM_IM4_IRL0 + 18)
+-# define INT_NUM_IM4_IRL19 (INT_NUM_IM4_IRL0 + 19)
+ # define IFX_ICU_IM4_IER IFXMIPS_ICU_IM4_IER
+
+ /* ============================= */
$(eval $(call KernelPackage,ata-artop))
+define KernelPackage/ata-ahci-dwc
+ TITLE:=Synopsys DWC AHCI SATA
+ KCONFIG:= \
+ CONFIG_AHCI_DWC \
+ CONFIG_SATA_HOST=y
+ FILES:=$(LINUX_DIR)/drivers/ata/ahci_dwc.ko
+ DEPENDS:=+kmod-ata-ahci-platform
+ AUTOLOAD:=$(call AutoLoad,41,ahci_dwc,1)
+ $(call AddDepends/ata,@TARGET_rockchip)
+endef
+
+$(eval $(call KernelPackage,ata-ahci-dwc))
define KernelPackage/ata-nvidia-sata
TITLE:=Nvidia Serial ATA support
define KernelPackage/mdio-devres
SUBMENU:=$(NETWORK_DEVICES_MENU)
TITLE:=Supports MDIO device registration
- DEPENDS:=+kmod-libphy +(TARGET_armsr||TARGET_bcm27xx_bcm2708||TARGET_malta||TARGET_tegra):kmod-of-mdio
+ DEPENDS:=+kmod-libphy +(TARGET_armsr||TARGET_bcm27xx_bcm2708||TARGET_loongarch64||TARGET_malta||TARGET_tegra):kmod-of-mdio
KCONFIG:=CONFIG_MDIO_DEVRES
HIDDEN:=1
FILES:=$(LINUX_DIR)/drivers/net/phy/mdio_devres.ko
define KernelPackage/mdio-gpio
SUBMENU:=$(NETWORK_DEVICES_MENU)
TITLE:= Supports GPIO lib-based MDIO busses
- DEPENDS:=+kmod-libphy @GPIO_SUPPORT +(TARGET_armsr||TARGET_bcm27xx_bcm2708||TARGET_malta||TARGET_tegra):kmod-of-mdio
+ DEPENDS:=+kmod-libphy @GPIO_SUPPORT +(TARGET_armsr||TARGET_bcm27xx_bcm2708||TARGET_loongarch64||TARGET_malta||TARGET_tegra):kmod-of-mdio
KCONFIG:= \
CONFIG_MDIO_BITBANG \
CONFIG_MDIO_GPIO
define KernelPackage/switch-rtl8366-smi
SUBMENU:=$(NETWORK_DEVICES_MENU)
TITLE:=Realtek RTL8366 SMI switch interface support
- DEPENDS:=@GPIO_SUPPORT +kmod-swconfig +(TARGET_armsr||TARGET_bcm27xx_bcm2708||TARGET_malta||TARGET_tegra):kmod-of-mdio
+ DEPENDS:=@GPIO_SUPPORT +kmod-swconfig +(TARGET_armsr||TARGET_bcm27xx_bcm2708||TARGET_loongarch64||TARGET_malta||TARGET_tegra):kmod-of-mdio
KCONFIG:=CONFIG_RTL8366_SMI
FILES:=$(LINUX_DIR)/drivers/net/phy/rtl8366_smi.ko
AUTOLOAD:=$(call AutoLoad,42,rtl8366_smi,1)
define KernelPackage/acpi-video
SUBMENU:=$(VIDEO_MENU)
TITLE:=ACPI Extensions For Display Adapters
- DEPENDS:=@TARGET_x86 +kmod-backlight
+ DEPENDS:=@TARGET_x86||TARGET_loongarch64 +kmod-backlight
HIDDEN:=1
- KCONFIG:=CONFIG_ACPI_VIDEO \
- CONFIG_ACPI_WMI
- FILES:=$(LINUX_DIR)/drivers/acpi/video.ko \
- $(LINUX_DIR)/drivers/platform/x86/wmi.ko
- AUTOLOAD:=$(call AutoProbe,wmi video)
+ KCONFIG:=CONFIG_ACPI_VIDEO
+ FILES:=$(LINUX_DIR)/drivers/acpi/video.ko
+ AUTOLOAD:=$(call AutoProbe,video)
endef
define KernelPackage/acpi-video/description
Kernel support for integrated graphics devices.
endef
+define KernelPackage/acpi-video/x86
+ KCONFIG+=CONFIG_ACPI_WMI
+ FILES+=$(LINUX_DIR)/drivers/platform/x86/wmi.ko
+ AUTOLOAD:=$(call AutoProbe,wmi video)
+endef
+
$(eval $(call KernelPackage,acpi-video))
define KernelPackage/backlight
define KernelPackage/drm-amdgpu
SUBMENU:=$(VIDEO_MENU)
TITLE:=AMDGPU DRM support
- DEPENDS:=@TARGET_x86 @DISPLAY_SUPPORT +kmod-backlight +kmod-drm-ttm \
+ DEPENDS:=@TARGET_x86||TARGET_loongarch64 @DISPLAY_SUPPORT +kmod-backlight +kmod-drm-ttm \
+kmod-drm-ttm-helper +kmod-drm-kms-helper +kmod-i2c-algo-bit +amdgpu-firmware \
+kmod-drm-display-helper +kmod-drm-buddy +kmod-acpi-video \
+LINUX_6_6:kmod-drm-exec +LINUX_6_6:kmod-drm-suballoc-helper
Direct Rendering Manager (DRM) support for AMDGPU Cards
endef
+define KernelPackage/drm-amdgpu/loongarch64
+ KCONFIG+=CONFIG_DRM_AMDGPU_USERPTR=y \
+ CONFIG_DRM_AMD_DC=y \
+ CONFIG_DRM_AMD_DC_FP=y \
+ CONFIG_DRM_AMD_DC_SI=y
+endef
+
$(eval $(call KernelPackage,drm-amdgpu))
include $(TOPDIR)/rules.mk
PKG_NAME:=qca-nss-dp
-PKG_RELEASE:=3
+PKG_RELEASE:=1
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/nss-dp.git
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_DATE:=2023-06-06
-PKG_SOURCE_VERSION:=fa67464466f69f00967cc373d1bdd6025f57eb89
-PKG_MIRROR_HASH:=39329770042c85b32780cd12eef2aad2c5df79f34d1b7081e5ba1e1cc0b1b161
+PKG_SOURCE_DATE:=2024-04-16
+PKG_SOURCE_VERSION:=5bf8b91e9fc209f175f9a58723b03055ace3d581
+PKG_MIRROR_HASH:=e86b04ea674c18fb69cd09a45ccab50317b85117e40d76c8457052c2e55d7c18
PKG_BUILD_PARALLEL:=1
PKG_FLAGS:=nonshared
--- a/include/nss_dp_dev.h
+++ b/include/nss_dp_dev.h
-@@ -202,13 +202,10 @@ struct nss_dp_dev {
+@@ -225,13 +225,10 @@ struct nss_dp_dev {
unsigned long drv_flags; /* Driver specific feature flags */
/* Phy related stuff */
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
-@@ -418,7 +418,7 @@ static int nss_dp_open(struct net_device
+@@ -436,7 +436,7 @@ static int nss_dp_open(struct net_device
netif_start_queue(netdev);
/* Notify data plane link is up */
if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 1)) {
netdev_dbg(netdev, "Data plane set link failed\n");
-@@ -615,6 +615,12 @@ static int32_t nss_dp_of_get_pdata(struc
+@@ -633,6 +633,12 @@ static int32_t nss_dp_of_get_pdata(struc
return -EFAULT;
}
if (of_property_read_u32(np, "qcom,mactype", &hal_pdata->mactype)) {
pr_err("%s: error reading mactype\n", np->name);
return -EFAULT;
-@@ -635,18 +641,6 @@ static int32_t nss_dp_of_get_pdata(struc
+@@ -653,18 +659,6 @@ static int32_t nss_dp_of_get_pdata(struc
return -EFAULT;
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
maddr = (uint8_t *)of_get_mac_address(np);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 4, 0))
-@@ -695,56 +689,6 @@ static int32_t nss_dp_of_get_pdata(struc
+@@ -753,56 +747,6 @@ static int32_t nss_dp_of_get_pdata(struc
return 0;
}
#ifdef CONFIG_NET_SWITCHDEV
/*
* nss_dp_is_phy_dev()
-@@ -803,7 +747,6 @@ static int32_t nss_dp_probe(struct platf
+@@ -861,7 +805,6 @@ static int32_t nss_dp_probe(struct platf
struct device_node *np = pdev->dev.of_node;
struct nss_gmac_hal_platform_data gmac_hal_pdata;
int32_t ret = 0;
#if defined(NSS_DP_PPE_SUPPORT)
uint32_t vsi_id;
fal_port_t port_id;
-@@ -880,22 +823,14 @@ static int32_t nss_dp_probe(struct platf
+@@ -940,22 +883,15 @@ static int32_t nss_dp_probe(struct platf
dp_priv->drv_flags |= NSS_DP_PRIV_FLAG(INIT_DONE);
- }
- snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT,
- dp_priv->miibus->id, dp_priv->phy_mdio_addr);
--
+ if (dp_priv->phy_node) {
- SET_NETDEV_DEV(netdev, &pdev->dev);
- dp_priv->phydev = phy_connect(netdev, phy_id,
- &nss_dp_adjust_link,
- dp_priv->phy_mii_type);
- if (IS_ERR(dp_priv->phydev)) {
- netdev_dbg(netdev, "failed to connect to phy device\n");
+- goto phy_setup_fail;
+- }
+ dp_priv->phydev = of_phy_connect(netdev, dp_priv->phy_node,
-+ &nss_dp_adjust_link, 0,
-+ dp_priv->phy_mii_type);
++ &nss_dp_adjust_link, 0,
++ dp_priv->phy_mii_type);
+ if (!(dp_priv->phydev)) {
+ netdev_err(netdev, "failed to connect to phy device\n");
- goto phy_setup_fail;
- }
++ goto phy_setup_fail;
++ }
}
+
+ #if defined(NSS_DP_PPE_SUPPORT)
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
-@@ -746,18 +746,29 @@ static int32_t nss_dp_probe(struct platf
+@@ -804,18 +804,29 @@ static int32_t nss_dp_probe(struct platf
struct nss_dp_dev *dp_priv;
struct device_node *np = pdev->dev.of_node;
struct nss_gmac_hal_platform_data gmac_hal_pdata;
#define NSS_DP_SWITCH_ID 0
#define NSS_DP_SW_ETHTYPE_PID 0 /* PPE ethtype profile ID for slow protocols */
-@@ -521,7 +523,76 @@ static struct notifier_block *nss_dp_sw_
+@@ -534,7 +536,76 @@ static struct notifier_block *nss_dp_sw_
#else
+++ /dev/null
-From 01ec275bd0942ddc6b80e1d3671cdc66be670f57 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Fri, 1 Sep 2023 12:23:58 +0200
-Subject: [PATCH] nss-dp: include <net/netdev_rx_queue.h>
-
-Since 6.5 netdev_rx_queue was moved out of netdevice.h so include the new
-header since that is where it lives now.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
----
- nss_dp_main.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/nss_dp_main.c
-+++ b/nss_dp_main.c
-@@ -34,6 +34,9 @@
- #if defined(NSS_DP_MAC_POLL_SUPPORT)
- #include <init/ssdk_init.h>
- #endif
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0))
-+#include <net/netdev_rx_queue.h>
-+#endif
-
- #include "nss_dp_hal.h"
-
--- a/include/nss_dp_dev.h
+++ b/include/nss_dp_dev.h
-@@ -312,6 +312,7 @@ void nss_dp_set_ethtool_ops(struct net_d
+@@ -349,6 +349,7 @@ void nss_dp_set_ethtool_ops(struct net_d
*/
#ifdef CONFIG_NET_SWITCHDEV
void nss_dp_switchdev_setup(struct net_device *dev);
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
-@@ -913,6 +913,10 @@ static int nss_dp_remove(struct platform
+@@ -972,6 +972,10 @@ static int nss_dp_remove(struct platform
if (!dp_priv)
continue;
--- a/nss_dp_switchdev.c
+++ b/nss_dp_switchdev.c
-@@ -635,4 +635,17 @@ void nss_dp_switchdev_setup(struct net_d
+@@ -648,4 +648,17 @@ void nss_dp_switchdev_setup(struct net_d
switch_init_done = true;
}
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
-@@ -1082,6 +1082,8 @@ int __init nss_dp_init(void)
+@@ -1163,6 +1163,8 @@ int __init nss_dp_init(void)
*/
void __exit nss_dp_exit(void)
{
/*
* TODO Move this to soc_ops
*/
-@@ -1089,8 +1091,6 @@ void __exit nss_dp_exit(void)
+@@ -1170,8 +1172,6 @@ void __exit nss_dp_exit(void)
nss_dp_hal_cleanup();
dp_global_ctx.common_init_done = false;
}
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
-@@ -920,6 +920,9 @@ static int nss_dp_remove(struct platform
+@@ -979,6 +979,9 @@ static int nss_dp_remove(struct platform
dp_ops = dp_priv->data_plane_ops;
hal_ops = dp_priv->gmac_hal_ops;
if (dp_priv->phydev)
phy_disconnect(dp_priv->phydev);
-@@ -931,7 +934,6 @@ static int nss_dp_remove(struct platform
+@@ -990,7 +993,6 @@ static int nss_dp_remove(struct platform
#endif
hal_ops->exit(dp_priv->gmac_hal_ctx);
dp_ops->deinit(dp_priv->dpc);
--- a/nss_dp_main.c
+++ b/nss_dp_main.c
-@@ -924,7 +924,7 @@ static int nss_dp_remove(struct platform
+@@ -983,7 +983,7 @@ static int nss_dp_remove(struct platform
unregister_netdev(dp_priv->netdev);
if (dp_priv->phydev)
include $(TOPDIR)/rules.mk
PKG_NAME:=qca-ssdk
-PKG_RELEASE:=6
+PKG_RELEASE:=2
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_DATE:=2023-10-04
-PKG_SOURCE_VERSION:=23a5aa4a4d5834da7a07efb58baebfbee91786b0
-PKG_MIRROR_HASH:=53fb201053b3aca004c4da07b06a0608b0b3322a2062b1f7ab3b3a7871ddabcb
+PKG_SOURCE_DATE:=2024-04-17
+PKG_SOURCE_VERSION:=3d060f7ad70d087f6b0452abe79ab6d042e8cd53
+PKG_MIRROR_HASH:=6f5e390b294e699491584094f5d7eb941de6237ad8c5320191e9e306fbcd8eb5
PKG_FLAGS:=nonshared
PKG_BUILD_PARALLEL:=1
GCC_VERSION=$(GCC_VERSION) \
EXTRA_CFLAGS="-fno-stack-protector -I$(STAGING_DIR)/usr/include" \
SoC=$(CONFIG_TARGET_SUBTARGET) \
+ SHELL="$(BASH)" \
PTP_FEATURE=disable SWCONFIG_FEATURE=disable \
ISISC_ENABLE=disable IN_QCA803X_PHY=FALSE \
IN_QCA808X_PHY=FALSE IN_MALIBU_PHY=FALSE \
+++ /dev/null
-From f6c0115daaac586740e873a3b8145c5370a73dce Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Sat, 17 Feb 2024 13:02:31 +0100
-Subject: [PATCH] config: identify kernel 6.6
-
-Identify kernel 6.6 so it can be compiled against.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
----
- config | 5 +++++
- make/linux_opt.mk | 4 ++--
- 2 files changed, 7 insertions(+), 2 deletions(-)
-
---- a/config
-+++ b/config
-@@ -27,6 +27,11 @@ endif
- ifeq ($(KVER),$(filter 6.1%,$(KVER)))
- OS_VER=6_1
- endif
-+
-+ifeq ($(KVER),$(filter 6.6%,$(KVER)))
-+ OS_VER=6_6
-+endif
-+
- ifeq ($(KVER), 3.4.0)
- OS_VER=3_4
- endif
---- a/make/linux_opt.mk
-+++ b/make/linux_opt.mk
-@@ -450,7 +450,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
- KASAN_SHADOW_SCALE_SHIFT := 3
- endif
-
-- ifeq ($(OS_VER),$(filter 5_4 6_1, $(OS_VER)))
-+ ifeq ($(OS_VER),$(filter 5_4 6_1 6_6, $(OS_VER)))
- ifeq ($(ARCH), arm64)
- KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
- endif
-@@ -481,7 +481,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
-
- endif
-
-- ifeq ($(OS_VER),$(filter 4_4 5_4 6_1, $(OS_VER)))
-+ ifeq ($(OS_VER),$(filter 4_4 5_4 6_1 6_6, $(OS_VER)))
- MODULE_CFLAG += -DKVER34
- MODULE_CFLAG += -DKVER32
- MODULE_CFLAG += -DLNX26_22
--- a/src/hsl/phy/hsl_phy.c
+++ b/src/hsl/phy/hsl_phy.c
-@@ -1335,6 +1335,9 @@ hsl_port_phydev_interface_mode_status_ge
+@@ -1322,6 +1322,9 @@ hsl_port_phydev_interface_mode_status_ge
case PHY_INTERFACE_MODE_10GKR:
*interface_mode_status = PORT_10GBASE_R;
break;
--- a/include/init/ssdk_dts.h
+++ b/include/init/ssdk_dts.h
-@@ -101,6 +101,7 @@ typedef struct
+@@ -99,6 +99,7 @@ typedef struct
a_uint32_t emu_chip_ver; /*only valid when is_emulation is true*/
a_uint32_t clk_mode;
a_uint32_t pcie_hw_base;
+ a_uint32_t port3_pcs_channel;
+ led_ctrl_pattern_t source_pattern[SSDK_MAX_PORT_NUM][PORT_LED_SOURCE_MAX];
} ssdk_dt_cfg;
- #define SSDK_MAX_NR_ETH 6
-@@ -162,6 +163,7 @@ a_uint32_t ssdk_device_id_get(a_uint32_t
+@@ -161,6 +162,7 @@ a_uint32_t ssdk_device_id_get(a_uint32_t
struct device_node *ssdk_dts_node_get(a_uint32_t dev_id);
struct clk *ssdk_dts_essclk_get(a_uint32_t dev_id);
struct clk *ssdk_dts_cmnclk_get(a_uint32_t dev_id);
cppe_port_mux_ctrl.bf.port4_pcs_sel =
--- a/src/adpt/hppe/adpt_hppe_uniphy.c
+++ b/src/adpt/hppe/adpt_hppe_uniphy.c
-@@ -1122,9 +1122,6 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin
+@@ -1160,9 +1160,6 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin
{
a_uint32_t i;
sw_error_t rv = SW_OK;
union uniphy_mode_ctrl_u uniphy_mode_ctrl;
-@@ -1134,9 +1131,7 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin
+@@ -1172,9 +1169,7 @@ __adpt_hppe_uniphy_psgmii_mode_set(a_uin
SSDK_DEBUG("uniphy %d is psgmii mode\n", uniphy_index);
#if defined(CPPE)
if (adpt_ppe_type_get(dev_id) == CPPE_TYPE) {
+a_uint32_t ssdk_dts_port3_pcs_channel_get(a_uint32_t dev_id)
+{
+ ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id];
-+
++
+ return cfg->port3_pcs_channel;
+}
+
- #ifndef BOARD_AR71XX
#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
static void ssdk_dt_parse_mac_mode(a_uint32_t dev_id,
-@@ -306,6 +313,25 @@ static void ssdk_dt_parse_mac_mode(a_uin
+ struct device_node *switch_node, ssdk_init_cfg *cfg)
+@@ -305,6 +312,25 @@ static void ssdk_dt_parse_mac_mode(a_uin
return;
}
+{
+ const __be32 *port3_pcs_channel;
+ a_uint32_t len = 0;
-+
++
+ port3_pcs_channel = of_get_property(switch_node, "port3_pcs_channel", &len);
+ if (!port3_pcs_channel) {
+ ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port3_pcs_channel = 2;
#ifdef IN_UNIPHY
static void ssdk_dt_parse_uniphy(a_uint32_t dev_id)
{
-@@ -1292,6 +1318,7 @@ sw_error_t ssdk_dt_parse(ssdk_init_cfg *
+@@ -1347,6 +1373,7 @@ sw_error_t ssdk_dt_parse(ssdk_init_cfg *
rv = ssdk_dt_parse_access_mode(switch_node, ssdk_dt_priv);
SW_RTN_ON_ERROR(rv);
ssdk_dt_parse_mac_mode(*dev_id, switch_node, cfg);
+++ /dev/null
-From bdae481e89cbe551068a99028bb57119b59f5ff4 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robimarko@gmail.com>
-Date: Tue, 26 Mar 2024 12:19:49 +0100
-Subject: [PATCH] mdio: adapt to C22 and C45 read/write split
-
-Kernel 6.3 has introduced separate C45 read/write operations, and thus
-split them out of the C22 operations completely so the old way of marking
-C45 reads and writes via the register value does not work anymore.
-
-This is causing SSDK to fail and find C45 only PHY-s such as Aquantia ones:
-[ 22.187877] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 8, phy_id = 0x0 phytype doesn't match
-[ 22.209924] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 0, phy_id = 0x0 phytype doesn't match
-
-This in turn causes USXGMII MAC autoneg bit to not get set and then UNIPHY
-autoneg will time out, causing the 10G ports not to work:
-[ 37.292784] uniphy autoneg time out!
-
-So, lets detect C45 reads and writes by the magic BIT(30) in the register
-argument and if so call separate C45 mdiobus read/write functions.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
----
- include/init/ssdk_plat.h | 7 +++++++
- src/init/ssdk_plat.c | 30 ++++++++++++++++++++++++++++++
- 2 files changed, 37 insertions(+)
-
---- a/include/init/ssdk_plat.h
-+++ b/include/init/ssdk_plat.h
-@@ -505,3 +505,10 @@ void ssdk_plat_exit(a_uint32_t dev_id);
-
- #endif
- /*qca808x_end*/
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0))
-+#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)
-+#endif
---- a/src/init/ssdk_plat.c
-+++ b/src/init/ssdk_plat.c
-@@ -356,6 +356,18 @@ phy_addr_validation_check(a_uint32_t phy
- return A_TRUE;
- }
-
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0))
-+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);
-+}
-+#endif
-+
- sw_error_t
- qca_ar8327_phy_read(a_uint32_t dev_id, a_uint32_t phy_addr,
- a_uint32_t reg, a_uint16_t* data)
-@@ -371,9 +383,18 @@ qca_ar8327_phy_read(a_uint32_t dev_id, a
- if (!bus)
- return SW_NOT_SUPPORTED;
- phy_addr = TO_PHY_ADDR(phy_addr);
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0))
-+ mutex_lock(&bus->mdio_lock);
-+ if (reg & MII_ADDR_C45)
-+ *data = __mdiobus_c45_read(bus, phy_addr, mdiobus_c45_devad(reg), mdiobus_c45_regad(reg));
-+ else
-+ *data = __mdiobus_read(bus, phy_addr, reg);
-+ mutex_unlock(&bus->mdio_lock);
-+#else
- mutex_lock(&bus->mdio_lock);
- *data = __mdiobus_read(bus, phy_addr, reg);
- mutex_unlock(&bus->mdio_lock);
-+#endif
-
- return 0;
- }
-@@ -393,9 +414,18 @@ qca_ar8327_phy_write(a_uint32_t dev_id,
- if (!bus)
- return SW_NOT_SUPPORTED;
- phy_addr = TO_PHY_ADDR(phy_addr);
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0))
-+ mutex_lock(&bus->mdio_lock);
-+ if (reg & MII_ADDR_C45)
-+ __mdiobus_c45_write(bus, phy_addr, mdiobus_c45_devad(reg), mdiobus_c45_regad(reg), data);
-+ else
-+ __mdiobus_write(bus, phy_addr, reg, data);
-+ mutex_unlock(&bus->mdio_lock);
-+#else
- mutex_lock(&bus->mdio_lock);
- __mdiobus_write(bus, phy_addr, reg, data);
- mutex_unlock(&bus->mdio_lock);
-+#endif
-
- return 0;
- }
kslib_c:
--- a/make/linux_opt.mk
+++ b/make/linux_opt.mk
-@@ -777,6 +777,6 @@ LOCAL_CFLAGS += $(CPU_CFLAG) -D"KBUILD_M
+@@ -778,6 +778,6 @@ LOCAL_CFLAGS += $(CPU_CFLAG) -D"KBUILD_M
####################################################################
# cflags for LNX Modules-Style Makefile
####################################################################
--- /dev/null
+--- a/src/fal/fal_port_ctrl.c
++++ b/src/fal/fal_port_ctrl.c
+@@ -2089,7 +2089,7 @@ fal_port_hibernate_get (a_uint32_t dev_i
+ */
+ sw_error_t
+ fal_port_cdt (a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair,
+- a_uint32_t * cable_status, a_uint32_t * cable_len)
++ fal_cable_status_t * cable_status, a_uint32_t * cable_len)
+ {
+ sw_error_t rv;
+
+--- a/src/fal/fal_portvlan.c
++++ b/src/fal/fal_portvlan.c
+@@ -2173,7 +2173,7 @@ fal_netisolate_get(a_uint32_t dev_id, a_
+ * @return SW_OK or error code
+ */
+ sw_error_t
+-fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_bool_t enable)
++fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_uint32_t enable)
+ {
+ sw_error_t rv;
+
+@@ -2190,7 +2190,7 @@ fal_eg_trans_filter_bypass_en_set(a_uint
+ * @return SW_OK or error code
+ */
+ sw_error_t
+-fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_bool_t* enable)
++fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_uint32_t* enable)
+ {
+ sw_error_t rv;
+
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
-#include <linux/version.h>
/**
* Driver for the Ubiquiti RGB LED controller (LEDBAR).
return ret;
}
-
-static int ubnt_ledbar_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int ubnt_ledbar_probe(struct i2c_client *client)
{
struct device_node *np = client->dev.of_node;
struct ubnt_ledbar *ledbar;
return ubnt_ledbar_apply_state(ledbar);
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
-static int ubnt_ledbar_remove(struct i2c_client *client)
-#else
static void ubnt_ledbar_remove(struct i2c_client *client)
-#endif
{
struct ubnt_ledbar *ledbar = i2c_get_clientdata(client);
mutex_destroy(&ledbar->lock);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
- return 0;
-#endif
}
static const struct i2c_device_id ubnt_ledbar_id[] = {
include $(TOPDIR)/rules.mk
PKG_NAME:=libbpf
-PKG_VERSION:=1.4.0
+PKG_VERSION:=1.4.1
PKG_RELEASE:=1
PKG_SOURCE_URL:=https://github.com/libbpf/libbpf
-PKG_MIRROR_HASH:=4c37636699c604de345937bdbdf8f2e6ce69cbf768a4aa669c32b542e5302de6
+PKG_MIRROR_HASH:=46469f720ed246529e46d84a6444ae1c1a1eaf2a717a5a055c9973bb52159ec3
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_VERSION:=v1.4.0
+PKG_SOURCE_VERSION:=v1.4.1
PKG_ABI_VERSION:=$(firstword $(subst .,$(space),$(PKG_VERSION)))
PKG_MAINTAINER:=Tony Ambardar <itugrok@yahoo.com>
CATEGORY:=Libraries
TITLE:=The libunwind project
URL:=http://www.nongnu.org/libunwind/
- DEPENDS:=@((mips||mipsel||mips64||powerpc64||x86_64||arm||aarch64)||(USE_GLIBC&&(powerpc||i386))) +zlib
+ DEPENDS:=@((mips||mipsel||mips64||powerpc64||x86_64||arm||aarch64||loongarch64)||(USE_GLIBC&&(powerpc||i386))) +zlib
ABI_VERSION:=8
endef
--- /dev/null
+--- a/src/loongarch64/getcontext.S
++++ b/src/loongarch64/getcontext.S
+@@ -25,7 +25,9 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+ #include "offsets.h"
++#ifdef __GLIBC__
+ #include <endian.h>
++#endif
+ .text
+
+ #define SREG(X) st.d $r##X, $r4, (LINUX_UC_MCONTEXT_GREGS + 8 * X)
include $(TOPDIR)/rules.mk
PKG_NAME:=libxml2
-PKG_VERSION:=2.12.5
+PKG_VERSION:=2.12.6
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNOME/libxml2/$(basename $(PKG_VERSION))
-PKG_HASH:=a972796696afd38073e0f59c283c3a2f5a560b5268b4babc391b286166526b21
+PKG_HASH:=889c593a881a3db5fdd96cc9318c87df34eb648edfc458272ad46fd607353fbb
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=COPYING
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib*.so* $(1)/usr/lib/
$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib*.a $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/cmake $(1)/usr/lib/
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
$(CP) \
$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/mbedcrypto.pc \
--- /dev/null
+++ b/Configurations/25-openwrt.conf
-@@ -0,0 +1,56 @@
+@@ -0,0 +1,59 @@
+## Openwrt "CONFIG_ARCH" matching targets.
+
+# The targets need to end in '-openwrt' for the AFALG patch to work
+ "linux-i386-openwrt" => {
+ inherit_from => [ "linux-x86", "openwrt" ],
+ },
++ "linux-loongarch64-openwrt" => {
++ inherit_from => [ "linux64-loongarch64", "openwrt" ],
++ },
+ "linux-mips-openwrt" => {
+ inherit_from => [ "linux-mips32", "openwrt" ],
+ },
$(call Package/gcc/Default)
NAME:=libtsan
TITLE:=Runtime library for ThreadSanitizer in GCC
- DEPENDS:=@USE_GLIBC +librt +libstdcpp @!mips @!mipsel @!mips64 @!mips64el @!arc
+ DEPENDS:=@USE_GLIBC +librt +libstdcpp @!loongarch64 @!mips @!mipsel @!mips64 @!mips64el @!arc
ABI_VERSION:=0
endef
$(call Package/gcc/Default)
NAME:=liblsan
TITLE:=Runtime library for LeakSanitizer in GCC
- DEPENDS:=@USE_GLIBC +librt +libstdcpp @!mips @!mipsel @!mips64 @!mips64el @!arc
+ DEPENDS:=@USE_GLIBC +librt +libstdcpp @!loongarch64 @!mips @!mipsel @!mips64 @!mips64el @!arc
ABI_VERSION:=0
endef
and disables:
- AES
- RSA
- - SHA1
Reduces binary size by about 64 kB (MIPS) from default
configuration.
include $(TOPDIR)/rules.mk
PKG_NAME:=dropbear
-PKG_VERSION:=2022.83
+PKG_VERSION:=2024.85
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
https://matt.ucc.asn.au/dropbear/releases/ \
https://dropbear.nl/mirror/releases/
-PKG_HASH:=bc5a121ffbc94b5171ad5ebe01be42746d50aa797c9549a4639894a16749443b
+PKG_HASH:=86b036c433a69d89ce51ebae335d65c47738ccf90d13e5eb0fea832e556da502
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE libtomcrypt/LICENSE libtommath/LICENSE
CATEGORY:=Base system
TITLE:=Small SSH2 client/server
DEPENDS:= +DROPBEAR_ZLIB:zlib
- ALTERNATIVES:=
+ ALTERNATIVES:=100:/usr/bin/ssh-keygen:/usr/sbin/dropbear
$(if $(CONFIG_DROPBEAR_SCP),ALTERNATIVES+= \
100:/usr/bin/scp:/usr/sbin/dropbear,)
$(if $(CONFIG_DROPBEAR_DBCLIENT),ALTERNATIVES+= \
##############################################################################
#
# option,value - add option to localoptions.h
-# !!option,value - replace option in sysoptions.h
+# !!option,value - replace option in src/sysoptions.h
#
##############################################################################
##############################################################################
#
# option,config,enabled,disabled = add option to localoptions.h
-# !!option,config,enabled,disabled = replace option in sysoptions.h
+# !!option,config,enabled,disabled = replace option in src/sysoptions.h
#
# option := (config) ? enabled : disabled
#
xsedx:=$(shell printf '\027')
db_opt_add =echo '\#define $(1) $(2)' >> $(PKG_BUILD_DIR)/localoptions.h
-db_opt_replace =$(ESED) '/^\#define $(1) .*$$$$/{h;:a;$$$$!n;/^\#.+$$$$/bb;/^$$$$/bb;H;ba;:b;x;s$(xsedx)^.+$$$$$(xsedx)\#define $(1) $(2)$(xsedx)p;x};p' -n $(PKG_BUILD_DIR)/sysoptions.h
+db_opt_replace =$(ESED) '/^\#define $(1) .*$$$$/{h;:a;$$$$!n;/^\#.+$$$$/bb;/^$$$$/bb;H;ba;:b;x;s$(xsedx)^.+$$$$$(xsedx)\#define $(1) $(2)$(xsedx)p;x};p' -n $(PKG_BUILD_DIR)/src/sysoptions.h
define Build/Configure/dropbear_headers
$(strip $(foreach s,$(DB_OPT_COMMON), \
esac
local c=0
- # sysoptions.h
+ # src/sysoptions.h
local DROPBEAR_MAX_PORTS=10
local a n if_ipaddrs
# ref: validate_section_dropbear()
# default receive window size is 24576 (DEFAULT_RECV_WINDOW in default_options.h)
- # sysoptions.h
+ # src/sysoptions.h
local MAX_RECV_WINDOW=10485760
if [ "${RecvWindowSize}" -gt ${MAX_RECV_WINDOW} ] ; then
# separate logging is required because syslog misses dropbear's message
+++ /dev/null
-From 36a03132634a17c667c0fac0a8e1519b3d1b71c6 Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Mon, 28 Nov 2022 21:12:23 +0800
-Subject: Add #if DROPBEAR_RSA guards
-
-Fixes building with DROPBEAR_RSA disabled.
-Closes #197
----
- signkey.c | 8 +++++++-
- signkey.h | 2 ++
- sysoptions.h | 5 +----
- 3 files changed, 10 insertions(+), 5 deletions(-)
-
---- a/signkey.c
-+++ b/signkey.c
-@@ -120,6 +120,7 @@ enum signkey_type signkey_type_from_name
- /* Special case for rsa-sha2-256. This could be generalised if more
- signature names are added that aren't 1-1 with public key names */
- const char* signature_name_from_type(enum signature_type type, unsigned int *namelen) {
-+#if DROPBEAR_RSA
- #if DROPBEAR_RSA_SHA256
- if (type == DROPBEAR_SIGNATURE_RSA_SHA256) {
- if (namelen) {
-@@ -136,11 +137,13 @@ const char* signature_name_from_type(enu
- return SSH_SIGNKEY_RSA;
- }
- #endif
-+#endif /* DROPBEAR_RSA */
- return signkey_name_from_type((enum signkey_type)type, namelen);
- }
-
- /* Returns DROPBEAR_SIGNATURE_NONE if none match */
- enum signature_type signature_type_from_name(const char* name, unsigned int namelen) {
-+#if DROPBEAR_RSA
- #if DROPBEAR_RSA_SHA256
- if (namelen == strlen(SSH_SIGNATURE_RSA_SHA256)
- && memcmp(name, SSH_SIGNATURE_RSA_SHA256, namelen) == 0) {
-@@ -153,10 +156,11 @@ enum signature_type signature_type_from_
- return DROPBEAR_SIGNATURE_RSA_SHA1;
- }
- #endif
-+#endif /* DROPBEAR_RSA */
- return (enum signature_type)signkey_type_from_name(name, namelen);
- }
-
--/* Returns the signature type from a key type. Must not be called
-+/* Returns the signature type from a key type. Must not be called
- with RSA keytype */
- enum signature_type signature_type_from_signkey(enum signkey_type keytype) {
- #if DROPBEAR_RSA
-@@ -167,6 +171,7 @@ enum signature_type signature_type_from_
- }
-
- enum signkey_type signkey_type_from_signature(enum signature_type sigtype) {
-+#if DROPBEAR_RSA
- #if DROPBEAR_RSA_SHA256
- if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA256) {
- return DROPBEAR_SIGNKEY_RSA;
-@@ -177,6 +182,7 @@ enum signkey_type signkey_type_from_sign
- return DROPBEAR_SIGNKEY_RSA;
- }
- #endif
-+#endif /* DROPBEAR_RSA */
- assert((int)sigtype < (int)DROPBEAR_SIGNKEY_NUM_NAMED);
- return (enum signkey_type)sigtype;
- }
---- a/signkey.h
-+++ b/signkey.h
-@@ -79,12 +79,14 @@ enum signature_type {
- DROPBEAR_SIGNATURE_SK_ED25519 = DROPBEAR_SIGNKEY_SK_ED25519,
- #endif
- #endif
-+#if DROPBEAR_RSA
- #if DROPBEAR_RSA_SHA1
- DROPBEAR_SIGNATURE_RSA_SHA1 = 100, /* ssh-rsa signature (sha1) */
- #endif
- #if DROPBEAR_RSA_SHA256
- DROPBEAR_SIGNATURE_RSA_SHA256 = 101, /* rsa-sha2-256 signature. has a ssh-rsa key */
- #endif
-+#endif /* DROPBEAR_RSA */
- DROPBEAR_SIGNATURE_NONE = DROPBEAR_SIGNKEY_NONE,
- };
-
---- a/sysoptions.h
-+++ b/sysoptions.h
-@@ -137,7 +137,7 @@
-
- /* Debian doesn't define this in system headers */
- #if !defined(LTM_DESC) && (DROPBEAR_ECC)
--#define LTM_DESC
-+#define LTM_DESC
- #endif
-
- #define DROPBEAR_ECC_256 (DROPBEAR_ECC)
-@@ -151,9 +151,6 @@
- * signing operations slightly slower. */
- #define DROPBEAR_RSA_BLINDING 1
-
--#ifndef DROPBEAR_RSA_SHA1
--#define DROPBEAR_RSA_SHA1 DROPBEAR_RSA
--#endif
- #ifndef DROPBEAR_RSA_SHA256
- #define DROPBEAR_RSA_SHA256 DROPBEAR_RSA
- #endif
+++ /dev/null
-From ec2215726cffb976019d08ebf569edd2229e9dba Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Thu, 1 Dec 2022 11:34:43 +0800
-Subject: Fix y2038 issues with time_t conversion
-
-These changes were identified by building with and without
--D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64
-on 32-bit arm, logging warnings to files.
--Wconversion was added to CFLAGS in both builds.
-
-Then a "diff -I Wconversion log1 log2" shows new warnings that appear
-with the 64-bit time_t. There are a few false positives that have been
-fixed for quietness.
-
-struct logininfo and struct wtmp are still problematic, those will
-need to be handled by libc.
----
- common-session.c | 43 +++++++++++++++++++++++++++----------------
- dbutil.c | 2 +-
- loginrec.c | 2 ++
- loginrec.h | 4 ++--
- runopts.h | 4 ++--
- svr-auth.c | 2 +-
- 6 files changed, 35 insertions(+), 22 deletions(-)
-
---- a/common-session.c
-+++ b/common-session.c
-@@ -519,15 +519,24 @@ static void send_msg_keepalive() {
- ses.last_packet_time_idle = old_time_idle;
- }
-
-+/* Returns the difference in seconds, clamped to LONG_MAX */
-+static long elapsed(time_t now, time_t prev) {
-+ time_t del = now - prev;
-+ if (del > LONG_MAX) {
-+ return LONG_MAX;
-+ }
-+ return (long)del;
-+}
-+
- /* Check all timeouts which are required. Currently these are the time for
- * user authentication, and the automatic rekeying. */
- static void checktimeouts() {
-
- time_t now;
- now = monotonic_now();
--
-+
- if (IS_DROPBEAR_SERVER && ses.connect_time != 0
-- && now - ses.connect_time >= AUTH_TIMEOUT) {
-+ && elapsed(now, ses.connect_time) >= AUTH_TIMEOUT) {
- dropbear_close("Timeout before auth");
- }
-
-@@ -537,45 +546,47 @@ static void checktimeouts() {
- }
-
- if (!ses.kexstate.sentkexinit
-- && (now - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT
-+ && (elapsed(now, ses.kexstate.lastkextime) >= KEX_REKEY_TIMEOUT
- || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)) {
- TRACE(("rekeying after timeout or max data reached"))
- send_msg_kexinit();
- }
--
-+
- if (opts.keepalive_secs > 0 && ses.authstate.authdone) {
- /* Avoid sending keepalives prior to auth - those are
- not valid pre-auth packet types */
-
- /* Send keepalives if we've been idle */
-- if (now - ses.last_packet_time_any_sent >= opts.keepalive_secs) {
-+ if (elapsed(now, ses.last_packet_time_any_sent) >= opts.keepalive_secs) {
- send_msg_keepalive();
- }
-
- /* Also send an explicit keepalive message to trigger a response
- if the remote end hasn't sent us anything */
-- if (now - ses.last_packet_time_keepalive_recv >= opts.keepalive_secs
-- && now - ses.last_packet_time_keepalive_sent >= opts.keepalive_secs) {
-+ if (elapsed(now, ses.last_packet_time_keepalive_recv) >= opts.keepalive_secs
-+ && elapsed(now, ses.last_packet_time_keepalive_sent) >= opts.keepalive_secs) {
- send_msg_keepalive();
- }
-
-- if (now - ses.last_packet_time_keepalive_recv
-+ if (elapsed(now, ses.last_packet_time_keepalive_recv)
- >= opts.keepalive_secs * DEFAULT_KEEPALIVE_LIMIT) {
- dropbear_exit("Keepalive timeout");
- }
- }
-
-- if (opts.idle_timeout_secs > 0
-- && now - ses.last_packet_time_idle >= opts.idle_timeout_secs) {
-+ if (opts.idle_timeout_secs > 0
-+ && elapsed(now, ses.last_packet_time_idle) >= opts.idle_timeout_secs) {
- dropbear_close("Idle timeout");
- }
- }
-
--static void update_timeout(long limit, long now, long last_event, long * timeout) {
-- TRACE2(("update_timeout limit %ld, now %ld, last %ld, timeout %ld",
-- limit, now, last_event, *timeout))
-+static void update_timeout(long limit, time_t now, time_t last_event, long * timeout) {
-+ TRACE2(("update_timeout limit %ld, now %llu, last %llu, timeout %ld",
-+ limit,
-+ (unsigned long long)now,
-+ (unsigned long long)last_event, *timeout))
- if (last_event > 0 && limit > 0) {
-- *timeout = MIN(*timeout, last_event+limit-now);
-+ *timeout = MIN(*timeout, elapsed(now, last_event) + limit);
- TRACE2(("new timeout %ld", *timeout))
- }
- }
-@@ -584,7 +595,7 @@ static long select_timeout() {
- /* determine the minimum timeout that might be required, so
- as to avoid waking when unneccessary */
- long timeout = KEX_REKEY_TIMEOUT;
-- long now = monotonic_now();
-+ time_t now = monotonic_now();
-
- if (!ses.kexstate.sentkexinit) {
- update_timeout(KEX_REKEY_TIMEOUT, now, ses.kexstate.lastkextime, &timeout);
-@@ -596,7 +607,7 @@ static long select_timeout() {
- }
-
- if (ses.authstate.authdone) {
-- update_timeout(opts.keepalive_secs, now,
-+ update_timeout(opts.keepalive_secs, now,
- MAX(ses.last_packet_time_keepalive_recv, ses.last_packet_time_keepalive_sent),
- &timeout);
- }
---- a/dbutil.c
-+++ b/dbutil.c
-@@ -724,7 +724,7 @@ void gettime_wrapper(struct timespec *no
- /* Fallback for everything else - this will sometimes go backwards */
- gettimeofday(&tv, NULL);
- now->tv_sec = tv.tv_sec;
-- now->tv_nsec = 1000*tv.tv_usec;
-+ now->tv_nsec = 1000*(long)tv.tv_usec;
- }
-
- /* second-resolution monotonic timestamp */
---- a/loginrec.c
-+++ b/loginrec.c
-@@ -459,6 +459,7 @@ line_abbrevname(char *dst, const char *s
- void
- set_utmp_time(struct logininfo *li, struct utmp *ut)
- {
-+ /* struct utmp in glibc isn't y2038 safe yet */
- # ifdef HAVE_STRUCT_UTMP_UT_TV
- ut->ut_tv.tv_sec = li->tv_sec;
- ut->ut_tv.tv_usec = li->tv_usec;
-@@ -1272,6 +1273,7 @@ lastlog_construct(struct logininfo *li,
- (void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line));
- strlcpy(last->ll_host, li->hostname,
- MIN_SIZEOF(last->ll_host, li->hostname));
-+ /* struct lastlog in glibc isn't y2038 safe yet */
- last->ll_time = li->tv_sec;
- }
-
---- a/loginrec.h
-+++ b/loginrec.h
-@@ -139,8 +139,8 @@ struct logininfo {
- /* struct timeval (sys/time.h) isn't always available, if it isn't we'll
- * use time_t's value as tv_sec and set tv_usec to 0
- */
-- unsigned int tv_sec;
-- unsigned int tv_usec;
-+ time_t tv_sec;
-+ suseconds_t tv_usec;
- union login_netinfo hostaddr; /* caller's host address(es) */
- }; /* struct logininfo */
-
---- a/runopts.h
-+++ b/runopts.h
-@@ -39,8 +39,8 @@ typedef struct runopts {
- int listen_fwd_all;
- #endif
- unsigned int recv_window;
-- time_t keepalive_secs; /* Time between sending keepalives. 0 is off */
-- time_t idle_timeout_secs; /* Exit if no traffic is sent/received in this time */
-+ long keepalive_secs; /* Time between sending keepalives. 0 is off */
-+ long idle_timeout_secs; /* Exit if no traffic is sent/received in this time */
- int usingsyslog;
-
- #ifndef DISABLE_ZLIB
---- a/svr-auth.c
-+++ b/svr-auth.c
-@@ -389,7 +389,7 @@ void send_msg_userauth_failure(int parti
- Beware of integer overflow if increasing these values */
- const unsigned int mindelay = 250000000;
- const unsigned int vardelay = 100000000;
-- unsigned int rand_delay;
-+ suseconds_t rand_delay;
- struct timespec delay;
-
- gettime_wrapper(&delay);
+++ /dev/null
-From c043efb47c3173072fa636ca0da0d19875d4511f Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Tue, 6 Dec 2022 22:34:11 +0800
-Subject: Fix so DROPBEAR_DSS is only forced for fuzzing
-
-Regression from 787391ea3b5af2acf5e3c83372510f0c79477ad7,
-was missing fuzzing conditional
----
- sysoptions.h | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/sysoptions.h
-+++ b/sysoptions.h
-@@ -380,9 +380,11 @@
- #endif
-
- /* Fuzzing expects all key types to be enabled */
-+#if DROPBEAR_FUZZ
- #if defined(DROPBEAR_DSS)
- #undef DROPBEAR_DSS
- #endif
- #define DROPBEAR_DSS 1
-+#endif
-
- /* no include guard for this file */
+++ /dev/null
-From 860721558837441ab45019858e710a2625ffa46e Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Wed, 7 Dec 2022 13:04:10 +0800
-Subject: Allow users's own gid in pty permission check
-
-This allows non-root Dropbear to work even without devpts gid=5 mount
-option on Linux.
----
- sshpty.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/sshpty.c
-+++ b/sshpty.c
-@@ -380,7 +380,9 @@ pty_setowner(struct passwd *pw, const ch
- tty_name, strerror(errno));
- }
-
-- if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
-+ /* Allow either "tty" gid or user's own gid. On Linux with openpty()
-+ * this varies depending on the devpts mount options */
-+ if (st.st_uid != pw->pw_uid || !(st.st_gid == gid || st.st_gid == pw->pw_gid)) {
- if (chown(tty_name, pw->pw_uid, gid) < 0) {
- if (errno == EROFS &&
- (st.st_uid == pw->pw_uid || st.st_uid == 0)) {
+++ /dev/null
-From 01415ef8269e594a647f67ea0729ca8b590679de Mon Sep 17 00:00:00 2001
-From: Francois Perrad <francois.perrad@gadz.org>
-Date: Thu, 22 Dec 2022 10:19:54 +0100
-Subject: const parameter mp_int
-
----
- bignum.c | 2 +-
- bignum.h | 2 +-
- buffer.c | 2 +-
- buffer.h | 2 +-
- dbrandom.c | 2 +-
- dbrandom.h | 2 +-
- dbutil.c | 2 +-
- dbutil.h | 2 +-
- genrsa.c | 4 ++--
- 9 files changed, 10 insertions(+), 10 deletions(-)
-
---- a/bignum.c
-+++ b/bignum.c
-@@ -93,7 +93,7 @@ void bytes_to_mp(mp_int *mp, const unsig
-
- /* hash the ssh representation of the mp_int mp */
- void hash_process_mp(const struct ltc_hash_descriptor *hash_desc,
-- hash_state *hs, mp_int *mp) {
-+ hash_state *hs, const mp_int *mp) {
- buffer * buf;
-
- buf = buf_new(512 + 20); /* max buffer is a 4096 bit key,
---- a/bignum.h
-+++ b/bignum.h
-@@ -33,6 +33,6 @@ void m_mp_alloc_init_multi(mp_int **mp,
- void m_mp_free_multi(mp_int **mp, ...) ATTRIB_SENTINEL;
- void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len);
- void hash_process_mp(const struct ltc_hash_descriptor *hash_desc,
-- hash_state *hs, mp_int *mp);
-+ hash_state *hs, const mp_int *mp);
-
- #endif /* DROPBEAR_BIGNUM_H_ */
---- a/buffer.c
-+++ b/buffer.c
-@@ -299,7 +299,7 @@ void buf_putbytes(buffer *buf, const uns
-
- /* for our purposes we only need positive (or 0) numbers, so will
- * fail if we get negative numbers */
--void buf_putmpint(buffer* buf, mp_int * mp) {
-+void buf_putmpint(buffer* buf, const mp_int * mp) {
- size_t written;
- unsigned int len, pad = 0;
- TRACE2(("enter buf_putmpint"))
---- a/buffer.h
-+++ b/buffer.h
-@@ -65,7 +65,7 @@ void buf_putint(buffer* buf, unsigned in
- void buf_putstring(buffer* buf, const char* str, unsigned int len);
- void buf_putbufstring(buffer *buf, const buffer* buf_str);
- void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len);
--void buf_putmpint(buffer* buf, mp_int * mp);
-+void buf_putmpint(buffer* buf, const mp_int * mp);
- int buf_getmpint(buffer* buf, mp_int* mp);
- unsigned int buf_getint(buffer* buf);
-
---- a/dbrandom.c
-+++ b/dbrandom.c
-@@ -347,7 +347,7 @@ void genrandom(unsigned char* buf, unsig
- * rand must be an initialised *mp_int for the result.
- * the result rand satisfies: 0 < rand < max
- * */
--void gen_random_mpint(mp_int *max, mp_int *rand) {
-+void gen_random_mpint(const mp_int *max, mp_int *rand) {
-
- unsigned char *randbuf = NULL;
- unsigned int len = 0;
---- a/dbrandom.h
-+++ b/dbrandom.h
-@@ -30,6 +30,6 @@
- void seedrandom(void);
- void genrandom(unsigned char* buf, unsigned int len);
- void addrandom(const unsigned char * buf, unsigned int len);
--void gen_random_mpint(mp_int *max, mp_int *rand);
-+void gen_random_mpint(const mp_int *max, mp_int *rand);
-
- #endif /* DROPBEAR_RANDOM_H_ */
---- a/dbutil.c
-+++ b/dbutil.c
-@@ -442,7 +442,7 @@ void printhex(const char * label, const
- }
- }
-
--void printmpint(const char *label, mp_int *mp) {
-+void printmpint(const char *label, const mp_int *mp) {
- buffer *buf = buf_new(1000);
- buf_putmpint(buf, mp);
- fprintf(stderr, "%d bits ", mp_count_bits(mp));
---- a/dbutil.h
-+++ b/dbutil.h
-@@ -53,7 +53,7 @@ void dropbear_trace3(const char* format,
- void dropbear_trace4(const char* format, ...) ATTRIB_PRINTF(1,2);
- void dropbear_trace5(const char* format, ...) ATTRIB_PRINTF(1,2);
- void printhex(const char * label, const unsigned char * buf, int len);
--void printmpint(const char *label, mp_int *mp);
-+void printmpint(const char *label, const mp_int *mp);
- void debug_start_net(void);
- extern int debug_trace;
- #endif
---- a/genrsa.c
-+++ b/genrsa.c
-@@ -34,7 +34,7 @@
- #if DROPBEAR_RSA
-
- static void getrsaprime(mp_int* prime, mp_int *primeminus,
-- mp_int* rsa_e, unsigned int size_bytes);
-+ const mp_int* rsa_e, unsigned int size_bytes);
-
- /* mostly taken from libtomcrypt's rsa key generation routine */
- dropbear_rsa_key * gen_rsa_priv_key(unsigned int size) {
-@@ -89,7 +89,7 @@ dropbear_rsa_key * gen_rsa_priv_key(unsi
-
- /* return a prime suitable for p or q */
- static void getrsaprime(mp_int* prime, mp_int *primeminus,
-- mp_int* rsa_e, unsigned int size_bytes) {
-+ const mp_int* rsa_e, unsigned int size_bytes) {
-
- unsigned char *buf;
- int trials;
+++ /dev/null
-From 39d955c49f31fc155e885447ee2be61c869d8c2d Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Tue, 3 Jan 2023 22:05:14 +0800
-Subject: Add missing break in switch
-
-Has no effect on execution, the fallthrough does nothing
-Closes #208
----
- dropbearkey.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/dropbearkey.c
-+++ b/dropbearkey.c
-@@ -139,6 +139,7 @@ static void check_signkey_bits(enum sign
- dropbear_exit("DSS keys have a fixed size of 1024 bits\n");
- exit(EXIT_FAILURE);
- }
-+ break;
- #endif
- default:
- (void)0; /* quiet, compiler. ecdsa handles checks itself */
+++ /dev/null
-From 7a53c7f0f4b3eb23e002819553cb45558642c01d Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Wed, 4 Jan 2023 20:32:23 +0800
-Subject: Fix building only client or server
-
-Regressed when -Wundef was added
-
-Fixes #210
----
- sysoptions.h | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/sysoptions.h
-+++ b/sysoptions.h
-@@ -10,6 +10,14 @@
- #define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION
- #define PROGNAME "dropbear"
-
-+#ifndef DROPBEAR_CLIENT
-+#define DROPBEAR_CLIENT 0
-+#endif
-+
-+#ifndef DROPBEAR_SERVER
-+#define DROPBEAR_SERVER 0
-+#endif
-+
- /* Spec recommends after one hour or 1 gigabyte of data. One hour
- * is a bit too verbose, so we try 8 hours */
- #ifndef KEX_REKEY_TIMEOUT
+++ /dev/null
-From a113381c12a2da3c9b7bd594f47a1b2657bdfdf2 Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Sun, 12 Feb 2023 22:44:32 +0800
-Subject: Disable rsa signatures when no rsa hostkey
-
-Otherwise Dropbear will offer RSA as a hostkey signature option, but the
-session will exit with an assertion or NULL pointer dereference once
-that algorithm is negotiated.
-
-This likely regressed in 2020.79 when signature vs key type enums were
-split, for rsa-sha256.
-
-Fixes #219 on github
----
- svr-runopts.c | 21 +++++++++++----------
- 1 file changed, 11 insertions(+), 10 deletions(-)
-
---- a/svr-runopts.c
-+++ b/svr-runopts.c
-@@ -505,11 +505,11 @@ static void addportandaddress(const char
- svr_opts.portcount++;
- }
-
--static void disablekey(int type) {
-+static void disablekey(enum signature_type type) {
- int i;
- TRACE(("Disabling key type %d", type))
- for (i = 0; sigalgs[i].name != NULL; i++) {
-- if (sigalgs[i].val == type) {
-+ if ((int)sigalgs[i].val == (int)type) {
- sigalgs[i].usable = 0;
- break;
- }
-@@ -624,7 +624,8 @@ void load_all_hostkeys() {
-
- #if DROPBEAR_RSA
- if (!svr_opts.delay_hostkey && !svr_opts.hostkey->rsakey) {
-- disablekey(DROPBEAR_SIGNKEY_RSA);
-+ disablekey(DROPBEAR_SIGNATURE_RSA_SHA256);
-+ disablekey(DROPBEAR_SIGNATURE_RSA_SHA1);
- } else {
- any_keys = 1;
- }
-@@ -632,7 +633,7 @@ void load_all_hostkeys() {
-
- #if DROPBEAR_DSS
- if (!svr_opts.delay_hostkey && !svr_opts.hostkey->dsskey) {
-- disablekey(DROPBEAR_SIGNKEY_DSS);
-+ disablekey(DROPBEAR_SIGNATURE_DSS);
- } else {
- any_keys = 1;
- }
-@@ -666,35 +667,35 @@ void load_all_hostkeys() {
- #if DROPBEAR_ECC_256
- if (!svr_opts.hostkey->ecckey256
- && (!svr_opts.delay_hostkey || loaded_any_ecdsa || ECDSA_DEFAULT_SIZE != 256 )) {
-- disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP256);
-+ disablekey(DROPBEAR_SIGNATURE_ECDSA_NISTP256);
- }
- #endif
- #if DROPBEAR_ECC_384
- if (!svr_opts.hostkey->ecckey384
- && (!svr_opts.delay_hostkey || loaded_any_ecdsa || ECDSA_DEFAULT_SIZE != 384 )) {
-- disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP384);
-+ disablekey(DROPBEAR_SIGNATURE_ECDSA_NISTP384);
- }
- #endif
- #if DROPBEAR_ECC_521
- if (!svr_opts.hostkey->ecckey521
- && (!svr_opts.delay_hostkey || loaded_any_ecdsa || ECDSA_DEFAULT_SIZE != 521 )) {
-- disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP521);
-+ disablekey(DROPBEAR_SIGNATURE_ECDSA_NISTP521);
- }
- #endif
- #endif /* DROPBEAR_ECDSA */
-
- #if DROPBEAR_ED25519
- if (!svr_opts.delay_hostkey && !svr_opts.hostkey->ed25519key) {
-- disablekey(DROPBEAR_SIGNKEY_ED25519);
-+ disablekey(DROPBEAR_SIGNATURE_ED25519);
- } else {
- any_keys = 1;
- }
- #endif
- #if DROPBEAR_SK_ECDSA
-- disablekey(DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256);
-+ disablekey(DROPBEAR_SIGNATURE_SK_ECDSA_NISTP256);
- #endif
- #if DROPBEAR_SK_ED25519
-- disablekey(DROPBEAR_SIGNKEY_SK_ED25519);
-+ disablekey(DROPBEAR_SIGNATURE_SK_ED25519);
- #endif
-
- if (!any_keys) {
+++ /dev/null
-From 3292b8c6f1e5fcc405fa0f7a20e90a60f74037b2 Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Sun, 12 Feb 2023 23:00:00 +0800
-Subject: Use write() rather than fprintf() in segv handler
-
-fprintf isn't guaranteed safe (though hasn't had any problems reported).
----
- svr-main.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
---- a/svr-main.c
-+++ b/svr-main.c
-@@ -420,8 +420,12 @@ static void sigchld_handler(int UNUSED(u
-
- /* catch any segvs */
- static void sigsegv_handler(int UNUSED(unused)) {
-- fprintf(stderr, "Aiee, segfault! You should probably report "
-- "this as a bug to the developer\n");
-+ int i;
-+ const char *msg = "Aiee, segfault! You should probably report "
-+ "this as a bug to the developer\n";
-+ i = write(STDERR_FILENO, msg, strlen(msg));
-+ /* ignore short writes */
-+ (void)i;
- _exit(EXIT_FAILURE);
- }
-
+++ /dev/null
-From 5040f21cb4ee6ade966e60c6d5a3c270d03de1f1 Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Mon, 1 May 2023 22:05:43 +0800
-Subject: Remove SO_LINGER
-
-It could cause channels to take up to 5 seconds to close(), which would block
-the entire process. On busy TCP forwarding sessions this would result in
-channels seeming stuck and new connections not being accepted.
-
-We don't need to monitor for flushing failures since we can't report errors, so
-SO_LINGER wasn't useful.
-
-Thanks to GektorUA for reporting and testing
-
-Fixes #230
----
- netio.c | 4 ----
- 1 file changed, 4 deletions(-)
-
---- a/netio.c
-+++ b/netio.c
-@@ -472,7 +472,6 @@ int dropbear_listen(const char* address,
- struct addrinfo hints, *res = NULL, *res0 = NULL;
- int err;
- unsigned int nsock;
-- struct linger linger;
- int val;
- int sock;
- uint16_t *allocated_lport_p = NULL;
-@@ -551,9 +550,6 @@ int dropbear_listen(const char* address,
- val = 1;
- /* set to reuse, quick timeout */
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val));
-- linger.l_onoff = 1;
-- linger.l_linger = 5;
-- setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger));
-
- #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
- if (res->ai_family == AF_INET6) {
+++ /dev/null
-From fb64db9eac3fdc6434f2dc7b5ea407fe5df76e6f Mon Sep 17 00:00:00 2001
-From: Diederik De Coninck <diederik.deconinck_ext@softathome.com>
-Date: Tue, 11 Apr 2023 15:38:04 +0200
-Subject: Add option to bind to interface
-
----
- netio.c | 13 +++++++++++--
- netio.h | 2 +-
- runopts.h | 1 +
- svr-main.c | 2 +-
- svr-runopts.c | 9 +++++++++
- svr-tcpfwd.c | 1 +
- tcp-accept.c | 2 +-
- tcpfwd.h | 1 +
- 8 files changed, 26 insertions(+), 5 deletions(-)
-
---- a/netio.c
-+++ b/netio.c
-@@ -467,7 +467,7 @@ int get_sock_port(int sock) {
- * failure, if errstring wasn't NULL, it'll be a newly malloced error
- * string.*/
- int dropbear_listen(const char* address, const char* port,
-- int *socks, unsigned int sockcount, char **errstring, int *maxfd) {
-+ int *socks, unsigned int sockcount, char **errstring, int *maxfd, const char* interface) {
-
- struct addrinfo hints, *res = NULL, *res0 = NULL;
- int err;
-@@ -497,7 +497,11 @@ int dropbear_listen(const char* address,
- TRACE(("dropbear_listen: local loopback"))
- } else {
- if (address[0] == '\0') {
-- TRACE(("dropbear_listen: all interfaces"))
-+ if (interface) {
-+ TRACE(("dropbear_listen: %s", interface))
-+ } else {
-+ TRACE(("dropbear_listen: all interfaces"))
-+ }
- address = NULL;
- }
- hints.ai_flags = AI_PASSIVE;
-@@ -551,6 +555,11 @@ int dropbear_listen(const char* address,
- /* set to reuse, quick timeout */
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val));
-
-+ if(interface && setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface)) < 0) {
-+ dropbear_log(LOG_WARNING, "Couldn't set SO_BINDTODEVICE");
-+ TRACE(("Failed setsockopt with errno failure, %d %s", errno, strerror(errno)))
-+ }
-+
- #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
- if (res->ai_family == AF_INET6) {
- int on = 1;
---- a/netio.h
-+++ b/netio.h
-@@ -19,7 +19,7 @@ void get_socket_address(int fd, char **l
- void getaddrstring(struct sockaddr_storage* addr,
- char **ret_host, char **ret_port, int host_lookup);
- int dropbear_listen(const char* address, const char* port,
-- int *socks, unsigned int sockcount, char **errstring, int *maxfd);
-+ int *socks, unsigned int sockcount, char **errstring, int *maxfd, const char* interface);
-
- struct dropbear_progress_connection;
-
---- a/runopts.h
-+++ b/runopts.h
-@@ -128,6 +128,7 @@ typedef struct svr_runopts {
- char * pidfile;
-
- char * forced_command;
-+ char* interface;
-
- #if DROPBEAR_PLUGIN
- /* malloced */
---- a/svr-main.c
-+++ b/svr-main.c
-@@ -488,7 +488,7 @@ static size_t listensockets(int *socks,
-
- nsock = dropbear_listen(svr_opts.addresses[i], svr_opts.ports[i], &socks[sockpos],
- sockcount - sockpos,
-- &errstring, maxfd);
-+ &errstring, maxfd, svr_opts.interface);
-
- if (nsock < 0) {
- dropbear_log(LOG_WARNING, "Failed listening on '%s': %s",
---- a/svr-runopts.c
-+++ b/svr-runopts.c
-@@ -98,6 +98,8 @@ static void printhelp(const char * progn
- " (default port is %s if none specified)\n"
- "-P PidFile Create pid file PidFile\n"
- " (default %s)\n"
-+ "-l <interface>\n"
-+ " interface to bind on\n"
- #if INETD_MODE
- "-i Start for inetd\n"
- #endif
-@@ -265,6 +267,9 @@ void svr_getopts(int argc, char ** argv)
- case 'P':
- next = &svr_opts.pidfile;
- break;
-+ case 'l':
-+ next = &svr_opts.interface;
-+ break;
- #if DO_MOTD
- /* motd is displayed by default, -m turns it off */
- case 'm':
-@@ -438,6 +443,10 @@ void svr_getopts(int argc, char ** argv)
- dropbear_log(LOG_INFO, "Forced command set to '%s'", svr_opts.forced_command);
- }
-
-+ if (svr_opts.interface) {
-+ dropbear_log(LOG_INFO, "Binding to interface '%s'", svr_opts.interface);
-+ }
-+
- if (reexec_fd_arg) {
- if (m_str_to_uint(reexec_fd_arg, &svr_opts.reexec_childpipe) == DROPBEAR_FAILURE
- || svr_opts.reexec_childpipe < 0) {
---- a/svr-tcpfwd.c
-+++ b/svr-tcpfwd.c
-@@ -205,6 +205,7 @@ static int svr_remotetcpreq(int *allocat
- tcpinfo->listenport = port;
- tcpinfo->chantype = &svr_chan_tcpremote;
- tcpinfo->tcp_type = forwarded;
-+ tcpinfo->interface = svr_opts.interface;
-
- tcpinfo->request_listenaddr = request_addr;
- if (!opts.listen_fwd_all || (strcmp(request_addr, "localhost") == 0) ) {
---- a/tcp-accept.c
-+++ b/tcp-accept.c
-@@ -117,7 +117,7 @@ int listen_tcpfwd(struct TCPListener* tc
- snprintf(portstring, sizeof(portstring), "%u", tcpinfo->listenport);
-
- nsocks = dropbear_listen(tcpinfo->listenaddr, portstring, socks,
-- DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd);
-+ DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd, tcpinfo->interface);
- if (nsocks < 0) {
- dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring);
- m_free(errstring);
---- a/tcpfwd.h
-+++ b/tcpfwd.h
-@@ -42,6 +42,7 @@ struct TCPListener {
- unsigned int listenport;
- /* The address that the remote host asked to listen on */
- char *request_listenaddr;
-+ char* interface;
-
- const struct ChanType *chantype;
- enum {direct, forwarded} tcp_type;
+++ /dev/null
-From 031d09b47912b2401f4934667c0b6f857ede61ee Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Tue, 18 Jul 2023 23:20:16 +0800
-Subject: Add ifdef guards for SO_BINDTODEVICE
-
----
- netio.c | 2 ++
- svr-runopts.c | 4 ++++
- 2 files changed, 6 insertions(+)
-
---- a/netio.c
-+++ b/netio.c
-@@ -555,10 +555,12 @@ int dropbear_listen(const char* address,
- /* set to reuse, quick timeout */
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val));
-
-+#ifdef SO_BINDTODEVICE
- if(interface && setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface)) < 0) {
- dropbear_log(LOG_WARNING, "Couldn't set SO_BINDTODEVICE");
- TRACE(("Failed setsockopt with errno failure, %d %s", errno, strerror(errno)))
- }
-+#endif
-
- #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
- if (res->ai_family == AF_INET6) {
---- a/svr-runopts.c
-+++ b/svr-runopts.c
-@@ -98,8 +98,10 @@ static void printhelp(const char * progn
- " (default port is %s if none specified)\n"
- "-P PidFile Create pid file PidFile\n"
- " (default %s)\n"
-+#ifdef SO_BINDTODEVICE
- "-l <interface>\n"
- " interface to bind on\n"
-+#endif
- #if INETD_MODE
- "-i Start for inetd\n"
- #endif
-@@ -267,9 +269,11 @@ void svr_getopts(int argc, char ** argv)
- case 'P':
- next = &svr_opts.pidfile;
- break;
-+#ifdef SO_BINDTODEVICE
- case 'l':
- next = &svr_opts.interface;
- break;
-+#endif
- #if DO_MOTD
- /* motd is displayed by default, -m turns it off */
- case 'm':
+++ /dev/null
-From 62a06cd95f58060a59359f8769c3f35cd680d4fd Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Sun, 23 Jul 2023 21:01:48 +0800
-Subject: Make banner reading failure non-fatal
-
----
- svr-runopts.c | 45 ++++++++++++++++++++++++++++-----------------
- 1 file changed, 28 insertions(+), 17 deletions(-)
-
---- a/svr-runopts.c
-+++ b/svr-runopts.c
-@@ -38,6 +38,7 @@ static void printhelp(const char * progn
- static void addportandaddress(const char* spec);
- static void loadhostkey(const char *keyfile, int fatal_duplicate);
- static void addhostkey(const char *keyfile);
-+static void load_banner();
-
- static void printhelp(const char * progname) {
-
-@@ -382,23 +383,7 @@ void svr_getopts(int argc, char ** argv)
- }
-
- if (svr_opts.bannerfile) {
-- struct stat buf;
-- if (stat(svr_opts.bannerfile, &buf) != 0) {
-- dropbear_exit("Error opening banner file '%s'",
-- svr_opts.bannerfile);
-- }
--
-- if (buf.st_size > MAX_BANNER_SIZE) {
-- dropbear_exit("Banner file too large, max is %d bytes",
-- MAX_BANNER_SIZE);
-- }
--
-- svr_opts.banner = buf_new(buf.st_size);
-- if (buf_readfile(svr_opts.banner, svr_opts.bannerfile)!=DROPBEAR_SUCCESS) {
-- dropbear_exit("Error reading banner file '%s'",
-- svr_opts.bannerfile);
-- }
-- buf_setpos(svr_opts.banner, 0);
-+ load_banner();
- }
-
- #ifdef HAVE_GETGROUPLIST
-@@ -715,3 +700,29 @@ void load_all_hostkeys() {
- dropbear_exit("No hostkeys available. 'dropbear -R' may be useful or run dropbearkey.");
- }
- }
-+
-+static void load_banner() {
-+ struct stat buf;
-+ if (stat(svr_opts.bannerfile, &buf) != 0) {
-+ dropbear_log(LOG_WARNING, "Error opening banner file '%s'",
-+ svr_opts.bannerfile);
-+ return;
-+ }
-+
-+ if (buf.st_size > MAX_BANNER_SIZE) {
-+ dropbear_log(LOG_WARNING, "Banner file too large, max is %d bytes",
-+ MAX_BANNER_SIZE);
-+ return;
-+ }
-+
-+ svr_opts.banner = buf_new(buf.st_size);
-+ if (buf_readfile(svr_opts.banner, svr_opts.bannerfile) != DROPBEAR_SUCCESS) {
-+ dropbear_log(LOG_WARNING, "Error reading banner file '%s'",
-+ svr_opts.bannerfile);
-+ buf_free(svr_opts.banner);
-+ svr_opts.banner = NULL;
-+ return;
-+ }
-+ buf_setpos(svr_opts.banner, 0);
-+
-+}
+++ /dev/null
-From ec26975d442163b66d1646a48e022bc8c2f1607a Mon Sep 17 00:00:00 2001
-From: Sergey Ponomarev <stokito@gmail.com>
-Date: Sun, 27 Aug 2023 00:07:05 +0300
-Subject: dropbearkey.c Ignore unsupported command line options
-
-To generate non interactively a key with OpenSSH the simplest command is:
-
-ssh-keygen -t ed25519 -q -N '' -f ~/.ssh/id_ed25519
-
-The command has two options -q quiet and -N passphrase which aren't supported by the dropbearkey.
-
-To improve interoperability add explicit ignoring of the -q and -N with empty passphrase.
-Also ignore the -v even if the DEBUG_TRACE is not set.
-
-Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
----
- dropbearkey.c | 15 +++++++++++++--
- 1 file changed, 13 insertions(+), 2 deletions(-)
-
---- a/dropbearkey.c
-+++ b/dropbearkey.c
-@@ -159,6 +159,7 @@ int main(int argc, char ** argv) {
- enum signkey_type keytype = DROPBEAR_SIGNKEY_NONE;
- char * typetext = NULL;
- char * sizetext = NULL;
-+ char * passphrase = NULL;
- unsigned int bits = 0, genbits;
- int printpub = 0;
-
-@@ -194,11 +195,16 @@ int main(int argc, char ** argv) {
- printhelp(argv[0]);
- exit(EXIT_SUCCESS);
- break;
--#if DEBUG_TRACE
- case 'v':
-+#if DEBUG_TRACE
- debug_trace = DROPBEAR_VERBOSE_LEVEL;
-- break;
- #endif
-+ break;
-+ case 'q':
-+ break; /* quiet is default */
-+ case 'N':
-+ next = &passphrase;
-+ break;
- default:
- fprintf(stderr, "Unknown argument %s\n", argv[i]);
- printhelp(argv[0]);
-@@ -266,6 +272,11 @@ int main(int argc, char ** argv) {
- check_signkey_bits(keytype, bits);;
- }
-
-+ if (passphrase && *passphrase != '\0') {
-+ fprintf(stderr, "Only empty passphrase is supported\n");
-+ exit(EXIT_FAILURE);
-+ }
-+
- genbits = signkey_generate_get_bits(keytype, bits);
- fprintf(stderr, "Generating %u bit %s key, this may take a while...\n", genbits, typetext);
- if (signkey_generate(keytype, bits, filename, 0) == DROPBEAR_FAILURE)
+++ /dev/null
-From 3b576d95dcf791d7b945e75f639da8f89c1685a2 Mon Sep 17 00:00:00 2001
-From: czurnieden <czurnieden@gmx.de>
-Date: Tue, 9 May 2023 17:17:12 +0200
-Subject: Fix possible integer overflow
-
----
- libtommath/bn_mp_2expt.c | 4 ++++
- libtommath/bn_mp_grow.c | 4 ++++
- libtommath/bn_mp_init_size.c | 5 +++++
- libtommath/bn_mp_mul_2d.c | 4 ++++
- libtommath/bn_s_mp_mul_digs.c | 4 ++++
- libtommath/bn_s_mp_mul_digs_fast.c | 4 ++++
- libtommath/bn_s_mp_mul_high_digs.c | 4 ++++
- libtommath/bn_s_mp_mul_high_digs_fast.c | 4 ++++
- 8 files changed, 33 insertions(+)
-
---- a/libtommath/bn_mp_2expt.c
-+++ b/libtommath/bn_mp_2expt.c
-@@ -12,6 +12,10 @@ mp_err mp_2expt(mp_int *a, int b)
- {
- mp_err err;
-
-+ if (b < 0) {
-+ return MP_VAL;
-+ }
-+
- /* zero a as per default */
- mp_zero(a);
-
---- a/libtommath/bn_mp_grow.c
-+++ b/libtommath/bn_mp_grow.c
-@@ -9,6 +9,10 @@ mp_err mp_grow(mp_int *a, int size)
- int i;
- mp_digit *tmp;
-
-+ if (size < 0) {
-+ return MP_VAL;
-+ }
-+
- /* if the alloc size is smaller alloc more ram */
- if (a->alloc < size) {
- /* reallocate the array a->dp
---- a/libtommath/bn_mp_init_size.c
-+++ b/libtommath/bn_mp_init_size.c
-@@ -6,6 +6,11 @@
- /* init an mp_init for a given size */
- mp_err mp_init_size(mp_int *a, int size)
- {
-+
-+ if (size < 0) {
-+ return MP_VAL;
-+ }
-+
- size = MP_MAX(MP_MIN_PREC, size);
-
- /* alloc mem */
---- a/libtommath/bn_mp_mul_2d.c
-+++ b/libtommath/bn_mp_mul_2d.c
-@@ -9,6 +9,10 @@ mp_err mp_mul_2d(const mp_int *a, int b,
- mp_digit d;
- mp_err err;
-
-+ if (b < 0) {
-+ return MP_VAL;
-+ }
-+
- /* copy */
- if (a != c) {
- if ((err = mp_copy(a, c)) != MP_OKAY) {
---- a/libtommath/bn_s_mp_mul_digs.c
-+++ b/libtommath/bn_s_mp_mul_digs.c
-@@ -16,6 +16,10 @@ mp_err s_mp_mul_digs(const mp_int *a, co
- mp_word r;
- mp_digit tmpx, *tmpt, *tmpy;
-
-+ if (digs < 0) {
-+ return MP_VAL;
-+ }
-+
- /* can we use the fast multiplier? */
- if ((digs < MP_WARRAY) &&
- (MP_MIN(a->used, b->used) < MP_MAXFAST)) {
---- a/libtommath/bn_s_mp_mul_digs_fast.c
-+++ b/libtommath/bn_s_mp_mul_digs_fast.c
-@@ -26,6 +26,10 @@ mp_err s_mp_mul_digs_fast(const mp_int *
- mp_digit W[MP_WARRAY];
- mp_word _W;
-
-+ if (digs < 0) {
-+ return MP_VAL;
-+ }
-+
- /* grow the destination as required */
- if (c->alloc < digs) {
- if ((err = mp_grow(c, digs)) != MP_OKAY) {
---- a/libtommath/bn_s_mp_mul_high_digs.c
-+++ b/libtommath/bn_s_mp_mul_high_digs.c
-@@ -15,6 +15,10 @@ mp_err s_mp_mul_high_digs(const mp_int *
- mp_word r;
- mp_digit tmpx, *tmpt, *tmpy;
-
-+ if (digs < 0) {
-+ return MP_VAL;
-+ }
-+
- /* can we use the fast multiplier? */
- if (MP_HAS(S_MP_MUL_HIGH_DIGS_FAST)
- && ((a->used + b->used + 1) < MP_WARRAY)
---- a/libtommath/bn_s_mp_mul_high_digs_fast.c
-+++ b/libtommath/bn_s_mp_mul_high_digs_fast.c
-@@ -19,6 +19,10 @@ mp_err s_mp_mul_high_digs_fast(const mp_
- mp_digit W[MP_WARRAY];
- mp_word _W;
-
-+ if (digs < 0) {
-+ return MP_VAL;
-+ }
-+
- /* grow the destination as required */
- pa = a->used + b->used;
- if (c->alloc < pa) {
+++ /dev/null
-From 3cf8344769eda55e26eee53c1898b2c66544f188 Mon Sep 17 00:00:00 2001
-From: Justin Chen <justin.chen@broadcom.com>
-Date: Fri, 8 Sep 2023 11:35:18 -0700
-Subject: src: svr-tcpfwd: Fix noremotetcp behavior
-
-If noremotetcp is set, we should still reply with
-send_msg_request_failed. This matches the behavior
-of !DROPBEAR_SVR_REMOTETCPFWD.
-
-We were seeing keepalive packets being ignored when
-the "-k" option was used.
----
- svr-tcpfwd.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/svr-tcpfwd.c
-+++ b/svr-tcpfwd.c
-@@ -79,14 +79,14 @@ void recv_msg_global_request_remotetcp()
-
- TRACE(("enter recv_msg_global_request_remotetcp"))
-
-+ reqname = buf_getstring(ses.payload, &namelen);
-+ wantreply = buf_getbool(ses.payload);
-+
- if (svr_opts.noremotetcp || !svr_pubkey_allows_tcpfwd()) {
- TRACE(("leave recv_msg_global_request_remotetcp: remote tcp forwarding disabled"))
- goto out;
- }
-
-- reqname = buf_getstring(ses.payload, &namelen);
-- wantreply = buf_getbool(ses.payload);
--
- if (namelen > MAX_NAME_LEN) {
- TRACE(("name len is wrong: %d", namelen))
- goto out;
+++ /dev/null
-From e28ba1b9975eab48799aa3ed77d3cd91627d7b27 Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Sat, 9 Dec 2023 23:10:41 +0800
-Subject: Don't try to shutdown() a pty
-
-shutdown() of a pty doesn't work (ENOTSOCK), so we should close
-it instead.
-
-This will ensure that PTY controlling terminals are closed when a
-session exits, including when multiple sessions run over a single SSH
-connection. In the normal case of a single session, the PTY controlling
-terminal would be closed when the Dropbear server process exits anyway.
-
-This possibly fixes #264 on github
-
-It is possible that there could be subtle changes to PTY flushing
-behaviour, though nothing caught by tests at present.
----
- svr-chansession.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/svr-chansession.c
-+++ b/svr-chansession.c
-@@ -910,7 +910,7 @@ static int ptycommand(struct Channel *ch
- channel->readfd = chansess->master;
- /* don't need to set stderr here */
- ses.maxfd = MAX(ses.maxfd, chansess->master);
-- channel->bidir_fd = 1;
-+ channel->bidir_fd = 0;
-
- setnonblocking(chansess->master);
-
+++ /dev/null
-From 806586b585806cbe32013bcd3af3847278972060 Mon Sep 17 00:00:00 2001
-From: Sergey Ponomarev <stokito@gmail.com>
-Date: Sun, 10 Dec 2023 10:31:56 +0200
-Subject: dropbearkey: add alias to ssh-keygen
-
-The dropbearkey is partially compatible with ssh-keygen and can be used as an alias.
-
-Closes: #263
----
- dbmulti.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/dbmulti.c
-+++ b/dbmulti.c
-@@ -41,7 +41,8 @@ static int runprog(const char *multipath
- }
- #endif
- #ifdef DBMULTI_dropbearkey
-- if (strcmp(progname, "dropbearkey") == 0) {
-+ if (strcmp(progname, "dropbearkey") == 0
-+ || strcmp(progname, "ssh-keygen") == 0) {
- return dropbearkey_main(argc, argv);
- }
- #endif
-@@ -88,7 +89,7 @@ int main(int argc, char ** argv) {
- "'dbclient' or 'ssh' - the Dropbear client\n"
- #endif
- #ifdef DBMULTI_dropbearkey
-- "'dropbearkey' - the key generator\n"
-+ "'dropbearkey' or 'ssh-keygen' - the key generator\n"
- #endif
- #ifdef DBMULTI_dropbearconvert
- "'dropbearconvert' - the key converter\n"
+++ /dev/null
-From 383cc8c97a9420aad9cf93d88e77ec636b183a9d Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Mon, 11 Dec 2023 23:18:09 +0800
-Subject: Allow inetd with non-syslog
-
-An inetd-alike should be able to distinguish stdout and stderr, so
-it's a valid configuration.
-
-Fixes #218 on github
----
- svr-runopts.c | 12 ------------
- 1 file changed, 12 deletions(-)
-
---- a/svr-runopts.c
-+++ b/svr-runopts.c
-@@ -443,18 +443,6 @@ void svr_getopts(int argc, char ** argv)
- }
- }
-
--#if INETD_MODE
-- if (svr_opts.inetdmode && (
-- opts.usingsyslog == 0
--#if DEBUG_TRACE
-- || debug_trace
--#endif
-- )) {
-- /* log output goes to stderr which would get sent over the inetd network socket */
-- dropbear_exit("Dropbear inetd mode is incompatible with debug -v or non-syslog");
-- }
--#endif
--
- if (svr_opts.multiauthmethod && svr_opts.noauthpass) {
- dropbear_exit("-t and -s are incompatible");
- }
+++ /dev/null
-From 9ac650401ffc2fb05c9328d26e76a5e7ae39152a Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Mon, 11 Dec 2023 23:31:22 +0800
-Subject: Fix test for multiuser kernels
-
-getuid() succeeds even on non-multiuser kernels. Instead
-getgroups() is a valid test.
-
-Fixes #214 on github
----
- common-session.c | 11 +++++++----
- 1 file changed, 7 insertions(+), 4 deletions(-)
-
---- a/common-session.c
-+++ b/common-session.c
-@@ -71,10 +71,13 @@ void common_session_init(int sock_in, in
- #if !DROPBEAR_SVR_MULTIUSER
- /* A sanity check to prevent an accidental configuration option
- leaving multiuser systems exposed */
-- errno = 0;
-- getuid();
-- if (errno != ENOSYS) {
-- dropbear_exit("Non-multiuser Dropbear requires a non-multiuser kernel");
-+ {
-+ int ret;
-+ errno = 0;
-+ ret = getgroups(0, NULL);
-+ if (!(ret == -1 && errno == ENOSYS)) {
-+ dropbear_exit("Non-multiuser Dropbear requires a non-multiuser kernel");
-+ }
- }
- #endif
-
+++ /dev/null
-From 6e43be5c7b99dbee49dc72b6f989f29fdd7e9356 Mon Sep 17 00:00:00 2001
-From: Matt Johnston <matt@ucc.asn.au>
-Date: Mon, 20 Nov 2023 14:02:47 +0800
-Subject: Implement Strict KEX mode
-
-As specified by OpenSSH with kex-strict-c-v00@openssh.com and
-kex-strict-s-v00@openssh.com.
----
- cli-session.c | 11 +++++++++++
- common-algo.c | 6 ++++++
- common-kex.c | 26 +++++++++++++++++++++++++-
- kex.h | 3 +++
- process-packet.c | 34 +++++++++++++++++++---------------
- ssh.h | 4 ++++
- svr-session.c | 3 +++
- 7 files changed, 71 insertions(+), 16 deletions(-)
-
---- a/cli-session.c
-+++ b/cli-session.c
-@@ -46,6 +46,7 @@ static void cli_finished(void) ATTRIB_NO
- static void recv_msg_service_accept(void);
- static void cli_session_cleanup(void);
- static void recv_msg_global_request_cli(void);
-+static void cli_algos_initialise(void);
-
- struct clientsession cli_ses; /* GLOBAL */
-
-@@ -117,6 +118,7 @@ void cli_session(int sock_in, int sock_o
- }
-
- chaninitialise(cli_chantypes);
-+ cli_algos_initialise();
-
- /* Set up cli_ses vars */
- cli_session_init(proxy_cmd_pid);
-@@ -487,3 +489,12 @@ void cli_dropbear_log(int priority, cons
- fflush(stderr);
- }
-
-+static void cli_algos_initialise(void) {
-+ algo_type *algo;
-+ for (algo = sshkex; algo->name; algo++) {
-+ if (strcmp(algo->name, SSH_STRICT_KEX_S) == 0) {
-+ algo->usable = 0;
-+ }
-+ }
-+}
-+
---- a/common-algo.c
-+++ b/common-algo.c
-@@ -308,6 +308,12 @@ algo_type sshkex[] = {
- {SSH_EXT_INFO_C, 0, NULL, 1, NULL},
- #endif
- #endif
-+#if DROPBEAR_CLIENT
-+ {SSH_STRICT_KEX_C, 0, NULL, 1, NULL},
-+#endif
-+#if DROPBEAR_SERVER
-+ {SSH_STRICT_KEX_S, 0, NULL, 1, NULL},
-+#endif
- {NULL, 0, NULL, 0, NULL}
- };
-
---- a/common-kex.c
-+++ b/common-kex.c
-@@ -183,6 +183,10 @@ void send_msg_newkeys() {
- gen_new_keys();
- switch_keys();
-
-+ if (ses.kexstate.strict_kex) {
-+ ses.transseq = 0;
-+ }
-+
- TRACE(("leave send_msg_newkeys"))
- }
-
-@@ -193,7 +197,11 @@ void recv_msg_newkeys() {
-
- ses.kexstate.recvnewkeys = 1;
- switch_keys();
--
-+
-+ if (ses.kexstate.strict_kex) {
-+ ses.recvseq = 0;
-+ }
-+
- TRACE(("leave recv_msg_newkeys"))
- }
-
-@@ -550,6 +558,10 @@ void recv_msg_kexinit() {
-
- ses.kexstate.recvkexinit = 1;
-
-+ if (ses.kexstate.strict_kex && !ses.kexstate.donefirstkex && ses.recvseq != 1) {
-+ dropbear_exit("First packet wasn't kexinit");
-+ }
-+
- TRACE(("leave recv_msg_kexinit"))
- }
-
-@@ -859,6 +871,18 @@ static void read_kex_algos() {
- }
- #endif
-
-+ if (!ses.kexstate.donefirstkex) {
-+ const char* strict_name;
-+ if (IS_DROPBEAR_CLIENT) {
-+ strict_name = SSH_STRICT_KEX_S;
-+ } else {
-+ strict_name = SSH_STRICT_KEX_C;
-+ }
-+ if (buf_has_algo(ses.payload, strict_name) == DROPBEAR_SUCCESS) {
-+ ses.kexstate.strict_kex = 1;
-+ }
-+ }
-+
- algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess);
- allgood &= goodguess;
- if (algo == NULL || algo->data == NULL) {
---- a/kex.h
-+++ b/kex.h
-@@ -83,6 +83,9 @@ struct KEXState {
-
- unsigned our_first_follows_matches : 1;
-
-+ /* Boolean indicating that strict kex mode is in use */
-+ unsigned int strict_kex;
-+
- time_t lastkextime; /* time of the last kex */
- unsigned int datatrans; /* data transmitted since last kex */
- unsigned int datarecv; /* data received since last kex */
---- a/process-packet.c
-+++ b/process-packet.c
-@@ -44,6 +44,7 @@ void process_packet() {
-
- unsigned char type;
- unsigned int i;
-+ unsigned int first_strict_kex = ses.kexstate.strict_kex && !ses.kexstate.donefirstkex;
- time_t now;
-
- TRACE2(("enter process_packet"))
-@@ -54,22 +55,24 @@ void process_packet() {
- now = monotonic_now();
- ses.last_packet_time_keepalive_recv = now;
-
-- /* These packets we can receive at any time */
-- switch(type) {
-
-- case SSH_MSG_IGNORE:
-- goto out;
-- case SSH_MSG_DEBUG:
-- goto out;
--
-- case SSH_MSG_UNIMPLEMENTED:
-- /* debugging XXX */
-- TRACE(("SSH_MSG_UNIMPLEMENTED"))
-- goto out;
--
-- case SSH_MSG_DISCONNECT:
-- /* TODO cleanup? */
-- dropbear_close("Disconnect received");
-+ if (type == SSH_MSG_DISCONNECT) {
-+ /* Allowed at any time */
-+ dropbear_close("Disconnect received");
-+ }
-+
-+ /* These packets may be received at any time,
-+ except during first kex with strict kex */
-+ if (!first_strict_kex) {
-+ switch(type) {
-+ case SSH_MSG_IGNORE:
-+ goto out;
-+ case SSH_MSG_DEBUG:
-+ goto out;
-+ case SSH_MSG_UNIMPLEMENTED:
-+ TRACE(("SSH_MSG_UNIMPLEMENTED"))
-+ goto out;
-+ }
- }
-
- /* Ignore these packet types so that keepalives don't interfere with
-@@ -98,7 +101,8 @@ void process_packet() {
- if (type >= 1 && type <= 49
- && type != SSH_MSG_SERVICE_REQUEST
- && type != SSH_MSG_SERVICE_ACCEPT
-- && type != SSH_MSG_KEXINIT)
-+ && type != SSH_MSG_KEXINIT
-+ && !first_strict_kex)
- {
- TRACE(("unknown allowed packet during kexinit"))
- recv_unimplemented();
---- a/ssh.h
-+++ b/ssh.h
-@@ -100,6 +100,10 @@
- #define SSH_EXT_INFO_C "ext-info-c"
- #define SSH_SERVER_SIG_ALGS "server-sig-algs"
-
-+/* OpenSSH strict KEX feature */
-+#define SSH_STRICT_KEX_S "kex-strict-s-v00@openssh.com"
-+#define SSH_STRICT_KEX_C "kex-strict-c-v00@openssh.com"
-+
- /* service types */
- #define SSH_SERVICE_USERAUTH "ssh-userauth"
- #define SSH_SERVICE_USERAUTH_LEN 12
---- a/svr-session.c
-+++ b/svr-session.c
-@@ -370,6 +370,9 @@ static void svr_algos_initialise(void) {
- algo->usable = 0;
- }
- #endif
-+ if (strcmp(algo->name, SSH_STRICT_KEX_C) == 0) {
-+ algo->usable = 0;
-+ }
- }
- }
-
---- a/svr-authpubkey.c
-+++ b/svr-authpubkey.c
+--- a/src/svr-authpubkey.c
++++ b/src/svr-authpubkey.c
@@ -78,6 +78,13 @@ static void send_msg_userauth_pk_ok(cons
const unsigned char* keyblob, unsigned int keybloblen);
static int checkfileperm(char * filename);
---- a/svr-chansession.c
-+++ b/svr-chansession.c
-@@ -985,12 +985,12 @@ static void execchild(const void *user_d
+--- a/src/svr-chansession.c
++++ b/src/svr-chansession.c
+@@ -987,12 +987,12 @@ static void execchild(const void *user_d
/* We can only change uid/gid as root ... */
if (getuid() == 0) {
---- a/cli-runopts.c
-+++ b/cli-runopts.c
-@@ -329,6 +329,10 @@ void cli_getopts(int argc, char ** argv)
+--- a/src/cli-runopts.c
++++ b/src/cli-runopts.c
+@@ -340,6 +340,10 @@ void cli_getopts(int argc, char ** argv)
case 'z':
opts.disable_ip_tos = 1;
break;
---- a/dbutil.h
-+++ b/dbutil.h
+--- a/src/dbutil.h
++++ b/src/dbutil.h
@@ -80,7 +80,11 @@ int m_snprintf(char *str, size_t size, c
#define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL}
--- a/Makefile.in
+++ b/Makefile.in
-@@ -200,17 +200,17 @@ dropbearkey: $(dropbearkeyobjs)
+@@ -220,17 +220,17 @@ dropbearkey: $(dropbearkeyobjs)
dropbearconvert: $(dropbearconvertobjs)
dropbear: $(HEADERS) $(LIBTOM_DEPS) Makefile
# multi-binary compilation.
-@@ -221,7 +221,7 @@ ifeq ($(MULTI),1)
+@@ -241,7 +241,7 @@ ifeq ($(MULTI),1)
endif
dropbearmulti$(EXEEXT): $(HEADERS) $(MULTIOBJS) $(LIBTOM_DEPS) Makefile
---- a/svr-auth.c
-+++ b/svr-auth.c
+--- a/src/svr-auth.c
++++ b/src/svr-auth.c
@@ -124,7 +124,7 @@ void recv_msg_userauth_request() {
AUTH_METHOD_NONE_LEN) == 0) {
TRACE(("recv_msg_userauth_request: 'none' request"))
--- a/configure.ac
+++ b/configure.ac
-@@ -87,54 +87,6 @@ AC_ARG_ENABLE(harden,
+@@ -86,54 +86,6 @@ AC_ARG_ENABLE(harden,
if test "$hardenbuild" -eq 1; then
AC_MSG_NOTICE(Checking for available hardened build flags:)
--- a/configure.ac
+++ b/configure.ac
-@@ -45,11 +45,8 @@ fi
+@@ -44,11 +44,8 @@ fi
# LTM_CFLAGS is given to ./configure by the user,
# DROPBEAR_LTM_CFLAGS is substituted in the LTM Makefile.in
DROPBEAR_LTM_CFLAGS="$LTM_CFLAGS"
signkey.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
---- a/signkey.c
-+++ b/signkey.c
+--- a/src/signkey.c
++++ b/src/signkey.c
@@ -652,10 +652,18 @@ int buf_verify(buffer * buf, sign_key *k
sigtype = signature_type_from_name(type_name, type_name_len);
m_free(type_name);
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 1 May 2024 18:55:24 +0200
+Subject: [PATCH] AP: add missing null pointer check in hostapd_free_hapd_data
+
+When called from wpa_supplicant, iface->interfaces can be NULL
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -502,7 +502,7 @@ void hostapd_free_hapd_data(struct hosta
+ struct hapd_interfaces *ifaces = hapd->iface->interfaces;
+ size_t i;
+
+- for (i = 0; i < ifaces->count; i++) {
++ for (i = 0; ifaces && i < ifaces->count; i++) {
+ struct hostapd_iface *iface = ifaces->iface[i];
+ size_t j;
+
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcpd.git
-PKG_MIRROR_HASH:=08fddf4294929d1713e0c3f7b258f8c7bf4abe731d5f34fceb797faa411f7a58
-PKG_SOURCE_DATE:=2023-10-24
-PKG_SOURCE_VERSION:=d8118f6e76e5519881f9a37137c3a06b3cb60fd2
+PKG_MIRROR_HASH:=f6e1c18551a00e01229fa12caa7b3fe33ad82785150fedcbe615fcc651ba2876
+PKG_SOURCE_DATE:=2024-05-08
+PKG_SOURCE_VERSION:=a29882318a4ccb3ae26f7cc0145e06ad4ead224b
PKG_MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
PKG_LICENSE:=GPL-2.0
CFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
CLANG="$(CLANG)" \
- BPF_TARGET="$(BPF_TARGET)" \
- LLC="$(LLVM_LLC)"
+ BPF_TARGET="$(BPF_ARCH)-linux-gnu" \
+ LLC="$(LLVM_LLC)" \
+ BPF_LDFLAGS="-march=$(BPF_TARGET) -mcpu=v3"
+
+ifneq ($(findstring s,$(OPENWRT_VERBOSE)),)
+ MAKE_FLAGS+=V=1
+endif
MAKE_VARS += \
PREFIX=/usr \
define Build/Configure
$(call Build/Configure/Default)
- echo "BPF_CFLAGS += -I$(BPF_HEADERS_DIR)/tools/lib -fno-stack-protector" >> $(PKG_BUILD_DIR)/config.mk
+ echo "BPF_CFLAGS += $(BPF_CFLAGS) -Wno-error -fno-stack-protector" >> $(PKG_BUILD_DIR)/config.mk
endef
define Build/InstallDev
--- /dev/null
+From 1f160c287c14b4300c4248752e20da5981c9763e Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Wed, 18 Jan 2023 19:00:54 +0100
+Subject: [PATCH] libxdp: Use __noinline__ reserved attribute for XDP
+ dispatcher
+
+The use of noinline is wrong as noline is not a reserved attribute and
+with gcc12 this became an error. Use the reserved __noinline__ attribute
+to fix compilation error.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+[a.heider: adapt lib/libxdp/protocol.org too]
+Signed-off-by: Andre Heider <a.heider@gmail.com>
+---
+ lib/libxdp/protocol.org | 2 +-
+ lib/libxdp/xdp-dispatcher.c.in | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/lib/libxdp/protocol.org
++++ b/lib/libxdp/protocol.org
+@@ -54,7 +54,7 @@ static volatile const struct xdp_dispatc
+ /* The volatile return value prevents the compiler from assuming it knows the
+ * return value and optimising based on that.
+ */
+-__attribute__ ((noinline))
++__attribute__ ((__noinline__))
+ int prog0(struct xdp_md *ctx) {
+ volatile int ret = XDP_DISPATCHER_RETVAL;
+
+--- a/lib/libxdp/xdp-dispatcher.c.in
++++ b/lib/libxdp/xdp-dispatcher.c.in
+@@ -30,7 +30,7 @@ static volatile const struct xdp_dispatc
+ * return value and optimising based on that.
+ */
+ forloop(`i', `0', NUM_PROGS,
+-`__attribute__ ((noinline))
++`__attribute__ ((__noinline__))
+ int format(`prog%d', i)(struct xdp_md *ctx) {
+ volatile int ret = XDP_DISPATCHER_RETVAL;
+
+@@ -40,7 +40,7 @@ int format(`prog%d', i)(struct xdp_md *c
+ }
+ ')
+
+-__attribute__ ((noinline))
++__attribute__ ((__noinline__))
+ int compat_test(struct xdp_md *ctx) {
+ volatile int ret = XDP_DISPATCHER_RETVAL;
+
--- /dev/null
+From bc2a11227b5bed29d33926d5ff7e707228db9e87 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Wed, 18 Jan 2023 20:07:58 +0100
+Subject: [PATCH] headers: xdp: drop vlan_hdr as already defined
+
+Drop vlan_hdr as already defined by bpf headers.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ headers/xdp/parsing_helpers.h | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/headers/xdp/parsing_helpers.h
++++ b/headers/xdp/parsing_helpers.h
+@@ -33,16 +33,6 @@ struct hdr_cursor {
+ };
+
+ /*
+- * struct vlan_hdr - vlan header
+- * @h_vlan_TCI: priority and VLAN ID
+- * @h_vlan_encapsulated_proto: packet type ID or len
+- */
+-struct vlan_hdr {
+- __be16 h_vlan_TCI;
+- __be16 h_vlan_encapsulated_proto;
+-};
+-
+-/*
+ * Struct icmphdr_common represents the common part of the icmphdr and icmp6hdr
+ * structures.
+ */
--- /dev/null
+From 0388d7447de027e0d2369d6b8a9c58ea0f8f027c Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Wed, 18 Jan 2023 20:37:12 +0100
+Subject: [PATCH] xdp-dump: add missing perf_event include for bpf and xdp
+
+Add missing perf_event include needed for struct perf_event_header for
+bpf and xdp.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ xdp-dump/xdpdump_bpf.c | 1 +
+ xdp-dump/xdpdump_xdp.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/xdp-dump/xdpdump_bpf.c
++++ b/xdp-dump/xdpdump_bpf.c
+@@ -4,6 +4,7 @@
+ * Include files
+ *****************************************************************************/
+ #include <stdbool.h>
++#include <linux/perf_event.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
+ #include <bpf/bpf_trace_helpers.h>
+--- a/xdp-dump/xdpdump_xdp.c
++++ b/xdp-dump/xdpdump_xdp.c
+@@ -4,6 +4,7 @@
+ * Include files
+ *****************************************************************************/
+ #include <stdbool.h>
++#include <linux/perf_event.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
+ #include <bpf/bpf_trace_helpers.h>
--- /dev/null
+From cb1ef3322671a67e2050a3eee18b49cdb4ed4bed Mon Sep 17 00:00:00 2001
+From: Andre Heider <a.heider@gmail.com>
+Date: Wed, 18 Jan 2023 20:54:41 +0100
+Subject: [PATCH] libxdp: fix compilation on multiarch systems
+
+Multiarch systems require an additional include path, which is covered
+by ARCH_INCLUDES here. Just as lib/util, add it to BPF_CFLAGS.
+
+Fixes compilation on debian:
+
+In file included from xdp-dispatcher.c:3:
+In file included from ../../headers/linux/bpf.h:11:
+/usr/include/linux/types.h:5:10: fatal error: 'asm/types.h' file not found
+
+Signed-off-by: Andre Heider <a.heider@gmail.com>
+---
+ lib/libxdp/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/lib/libxdp/Makefile
++++ b/lib/libxdp/Makefile
+@@ -30,7 +30,7 @@ PC_FILE := $(OBJDIR)/libxdp.pc
+ TEMPLATED_SOURCES := xdp-dispatcher.c
+
+ CFLAGS += -I$(HEADER_DIR)
+-BPF_CFLAGS += -I$(HEADER_DIR)
++BPF_CFLAGS += -I$(HEADER_DIR) $(ARCH_INCLUDES)
+
+
+ ifndef BUILD_STATIC_ONLY
--- /dev/null
+From e2d8eae9477f6ba41ab75ad77202f235e34c04f7 Mon Sep 17 00:00:00 2001
+From: Andre Heider <a.heider@gmail.com>
+Date: Wed, 18 Jan 2023 22:30:23 +0100
+Subject: [PATCH] lib: allow overwriting -W* flags via BPF_CFLAGS
+
+The bpf header file situation is a mess, and the default warning
+compiler flags may not be suitable everywhere, especially with -Werror
+in the mix.
+
+Move BPF_CFLAGS further down, so these can be overwritten by builders.
+
+Signed-off-by: Andre Heider <a.heider@gmail.com>
+---
+ lib/common.mk | 2 +-
+ lib/libxdp/Makefile | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/lib/common.mk
++++ b/lib/common.mk
+@@ -108,12 +108,12 @@ $(XDP_OBJ): %.o: %.c $(KERN_USER_H) $(EX
+ $(QUIET_CLANG)$(CLANG) -S \
+ -target $(BPF_TARGET) \
+ -D __BPF_TRACING__ \
+- $(BPF_CFLAGS) \
+ -Wall \
+ -Wno-unused-value \
+ -Wno-pointer-sign \
+ -Wno-compare-distinct-pointer-types \
+ -Werror \
++ $(BPF_CFLAGS) \
+ -O2 -emit-llvm -c -g -o ${@:.o=.ll} $<
+ $(QUIET_LLC)$(LLC) -march=$(BPF_TARGET) -filetype=obj -o $@ ${@:.o=.ll}
+
+--- a/lib/libxdp/Makefile
++++ b/lib/libxdp/Makefile
+@@ -139,12 +139,12 @@ $(XDP_OBJS): %.o: %.c $(BPF_HEADERS) $(L
+ $(QUIET_CLANG)$(CLANG) -S \
+ -target $(BPF_TARGET) \
+ -D __BPF_TRACING__ \
+- $(BPF_CFLAGS) \
+ -Wall \
+ -Wno-unused-value \
+ -Wno-pointer-sign \
+ -Wno-compare-distinct-pointer-types \
+ -Werror \
++ $(BPF_CFLAGS) \
+ -O2 -emit-llvm -c -g -o ${@:.o=.ll} $<
+ $(QUIET_LLC)$(LLC) -march=$(BPF_TARGET) -filetype=obj -o $@ ${@:.o=.ll}
+
--- /dev/null
+From 7b00d4a90af1d7bff50833ffe1216cf59592353a Mon Sep 17 00:00:00 2001
+From: Andre Heider <a.heider@gmail.com>
+Date: Wed, 18 Jan 2023 22:42:28 +0100
+Subject: [PATCH] Add BPF_LDFLAGS to allow overwriting llc's -march argument
+
+The argument to clang's -target isn't necessarily the same as to
+llc's -march.
+
+Analogue to BPF_CFLAGS, introduce BPF_LDFLAGS to allow e.g.:
+BPF_TARGET="mipsel-linux-gnu" BPF_LDFLAGS="-march=bpfel -mcpu=v3"
+
+Signed-off-by: Andre Heider <a.heider@gmail.com>
+---
+ configure | 2 ++
+ lib/common.mk | 2 +-
+ lib/libxdp/Makefile | 2 +-
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/configure
++++ b/configure
+@@ -17,10 +17,12 @@ check_opts()
+ : ${DYNAMIC_LIBXDP:=0}
+ : ${MAX_DISPATCHER_ACTIONS:=10}
+ : ${BPF_TARGET:=bpf}
++ : ${BPF_LDFLAGS:=-march=$(BPF_TARGET)}
+ echo "PRODUCTION:=${PRODUCTION}" >>$CONFIG
+ echo "DYNAMIC_LIBXDP:=${DYNAMIC_LIBXDP}" >>$CONFIG
+ echo "MAX_DISPATCHER_ACTIONS:=${MAX_DISPATCHER_ACTIONS}" >>$CONFIG
+ echo "BPF_TARGET:=${BPF_TARGET}" >>$CONFIG
++ echo "BPF_LDFLAGS:=${BPF_LDFLAGS}" >>$CONFIG
+ }
+
+ find_tool()
+--- a/lib/common.mk
++++ b/lib/common.mk
+@@ -115,7 +115,7 @@ $(XDP_OBJ): %.o: %.c $(KERN_USER_H) $(EX
+ -Werror \
+ $(BPF_CFLAGS) \
+ -O2 -emit-llvm -c -g -o ${@:.o=.ll} $<
+- $(QUIET_LLC)$(LLC) -march=$(BPF_TARGET) -filetype=obj -o $@ ${@:.o=.ll}
++ $(QUIET_LLC)$(LLC) $(BPF_LDFLAGS) -filetype=obj -o $@ ${@:.o=.ll}
+
+ .PHONY: man
+ ifeq ($(EMACS),)
+--- a/lib/libxdp/Makefile
++++ b/lib/libxdp/Makefile
+@@ -146,7 +146,7 @@ $(XDP_OBJS): %.o: %.c $(BPF_HEADERS) $(L
+ -Werror \
+ $(BPF_CFLAGS) \
+ -O2 -emit-llvm -c -g -o ${@:.o=.ll} $<
+- $(QUIET_LLC)$(LLC) -march=$(BPF_TARGET) -filetype=obj -o $@ ${@:.o=.ll}
++ $(QUIET_LLC)$(LLC) $(BPF_LDFLAGS) -filetype=obj -o $@ ${@:.o=.ll}
+
+ .PHONY: man
+ ifeq ($(EMACS),)
#include <endian.h>
#include <string.h>
#include <errno.h>
+#include <netinet/in.h>
#include <sys/ioctl.h>
#include <mtd/mtd-user.h>
size_t block_offset;
if (quiet < 2)
- fprintf(stderr, "Trying to fix trx header in %s at 0x%x...\n", mtd, offset);
+ fprintf(stderr, "Trying to fix trx header in %s at 0x%zx...\n", mtd, offset);
fd = mtd_check_open(mtd);
if(fd < 0) {
trx->crc32 = STORE32_LE(crc32buf(buf, data_size));
if (mtd_erase_block(fd, block_offset)) {
- fprintf(stderr, "Can't erease block at 0x%x (%s)\n", block_offset, strerror(errno));
+ fprintf(stderr, "Can't erease block at 0x%zx (%s)\n", block_offset, strerror(errno));
exit(1);
}
#!/bin/sh
-[ -f /etc/opkg.conf ] && grep -q "src\/" /etc/opkg.conf || exit 0
+[ -f /etc/opkg.conf ] && grep -q "src/" /etc/opkg.conf || exit 0
echo -e "# Old feeds from previous image\n# Uncomment to reenable\n" >> /etc/opkg/customfeeds.conf
sed -n "s/.*\(src\/.*\)/# \1/p" /etc/opkg.conf >> /etc/opkg/customfeeds.conf
}
procd_add_mdns_service() {
- local service proto port
+ local service proto port txt_count=0
service=$1; shift
proto=$1; shift
port=$1; shift
json_add_object "${service}_$port"
json_add_string "service" "_$service._$proto.local"
json_add_int port "$port"
- [ -n "$1" ] && {
- json_add_array txt
- for txt in "$@"; do json_add_string "" "$txt"; done
- json_select ..
- }
+ for txt in "$@"; do
+ [ -z "$txt" ] && continue
+ txt_count=$((txt_count+1))
+ [ $txt_count -eq 1 ] && json_add_array txt
+ json_add_string "" "$txt"
+ done
+ [ $txt_count -gt 0 ] && json_select ..
+
json_select ..
}
PKG_NAME:=audit-userspace
PKG_VERSION:=3.1.4
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/linux-audit/audit-userspace/archive/refs/tags/v$(PKG_VERSION).tar.gz?
PKG_HASH:=aec501760acd13ebbe00e78b9b59f795d16a430b1d673628e346cd18905c594b
--- /dev/null
+From 429d031edd52566eeba03c3b3af32ad6e103fd94 Mon Sep 17 00:00:00 2001
+From: Steve Grubb <ausearch.1@gmail.com>
+Date: Fri, 3 May 2024 17:33:39 -0400
+Subject: [PATCH] Implicit builtin functions
+
+Correct a number of places where printf is being used without a prototype.
+All cases are in libraries which should not be using printf. Change them
+to return an error rather than communicate the problem.
+
+This is a backport of 8c7eaa7
+---
+ audisp/audispd-llist.c | 10 +++++-----
+ audisp/audispd-llist.h | 4 ++--
+ auparse/normalize-llist.c | 12 ++++++------
+ auparse/normalize-llist.h | 4 ++--
+ auparse/normalize.c | 14 +++++++++-----
+ src/auditctl-llist.c | 18 +++++++++---------
+ src/auditctl-llist.h | 4 ++--
+ src/ausearch-avc.c | 16 ++++++++--------
+ src/ausearch-avc.h | 4 ++--
+ src/ausearch-int.c | 12 ++++++------
+ src/ausearch-int.h | 4 ++--
+ src/ausearch-llist.c | 14 +++++++-------
+ src/ausearch-llist.h | 2 +-
+ src/ausearch-nvpair.c | 12 ++++++------
+ src/ausearch-nvpair.h | 4 ++--
+ src/ausearch-string.c | 10 +++++-----
+ src/ausearch-string.h | 2 +-
+ tools/aulastlog/aulastlog-llist.c | 18 +++++++++---------
+ tools/aulastlog/aulastlog-llist.h | 4 ++--
+ 19 files changed, 86 insertions(+), 82 deletions(-)
+
+--- a/audisp/audispd-llist.c
++++ b/audisp/audispd-llist.c
+@@ -69,15 +69,13 @@ unsigned int plist_count_active(const co
+ return cnt;
+ }
+
+-void plist_append(conf_llist *l, plugin_conf_t *p)
++int plist_append(conf_llist *l, plugin_conf_t *p)
+ {
+ lnode* newnode;
+
+ newnode = malloc(sizeof(lnode));
+- if (newnode == NULL) {
+- printf("Out of memory. Check %s file, %d line", __FILE__, __LINE__);
+- return;
+- }
++ if (newnode == NULL)
++ return 1;
+
+ if (p) {
+ void *pp = malloc(sizeof(struct plugin_conf));
+@@ -98,6 +96,8 @@ void plist_append(conf_llist *l, plugin_
+ // make newnode current
+ l->cur = newnode;
+ l->cnt++;
++
++ return 0;
+ }
+
+ void plist_clear(conf_llist* l)
+--- a/audisp/audispd-llist.h
++++ b/audisp/audispd-llist.h
+@@ -1,6 +1,6 @@
+ /*
+ * audispd-llist.h - Header file for ausearch-conf_llist.c
+-* Copyright (c) 2007,2013 Red Hat Inc., Durham, North Carolina.
++* Copyright (c) 2007,2013 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+@@ -51,7 +51,7 @@ unsigned int plist_count_active(const co
+ void plist_last(conf_llist *l);
+ lnode *plist_next(conf_llist *l);
+ static inline lnode *plist_get_cur(conf_llist *l) { return l->cur; }
+-void plist_append(conf_llist *l, plugin_conf_t *p);
++int plist_append(conf_llist *l, plugin_conf_t *p);
+ void plist_clear(conf_llist* l);
+ void plist_mark_all_unchecked(conf_llist* l);
+ lnode *plist_find_unchecked(conf_llist* l);
+--- a/auparse/normalize-llist.c
++++ b/auparse/normalize-llist.c
+@@ -1,6 +1,6 @@
+ /*
+ * normalize-llist.c - Minimal linked list library
+- * Copyright (c) 2016-17 Red Hat Inc., Durham, North Carolina.
++ * Copyright (c) 2016-17 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+@@ -61,15 +61,14 @@ data_node *cllist_next(cllist *l)
+ return l->cur;
+ }
+
+-void cllist_append(cllist *l, uint32_t num, void *data)
++// Returns 0 on success and 1 on error
++int cllist_append(cllist *l, uint32_t num, void *data)
+ {
+ data_node *newnode;
+
+ newnode = malloc(sizeof(data_node));
+- if (newnode == NULL) {
+- printf("Out of memory. Check %s file, %d line", __FILE__, __LINE__);
+- return;
+- }
++ if (newnode == NULL)
++ return 1;
+
+ newnode->num = num;
+ newnode->data = data;
+@@ -84,5 +83,6 @@ void cllist_append(cllist *l, uint32_t n
+ // make newnode current
+ l->cur = newnode;
+ l->cnt++;
++ return 0;
+ }
+
+--- a/auparse/normalize-llist.h
++++ b/auparse/normalize-llist.h
+@@ -1,6 +1,6 @@
+ /*
+ * normalize-llist.h - Header file for normalize-llist.c
+- * Copyright (c) 2016-17 Red Hat Inc., Durham, North Carolina.
++ * Copyright (c) 2016-17 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+@@ -53,7 +53,7 @@ AUDIT_HIDDEN_START
+ void cllist_create(cllist *l, void (*cleanup)(void *));
+ void cllist_clear(cllist* l);
+ data_node *cllist_next(cllist *l);
+-void cllist_append(cllist *l, uint32_t num, void *data);
++int cllist_append(cllist *l, uint32_t num, void *data);
+
+ AUDIT_HIDDEN_END
+
+--- a/auparse/normalize.c
++++ b/auparse/normalize.c
+@@ -179,7 +179,8 @@ static unsigned int add_subj_attr(aupars
+ if ((auparse_find_field(au, str))) {
+ attr = set_record(0, rnum);
+ attr = set_field(attr, auparse_get_field_num(au));
+- cllist_append(&D.actor.attr, attr, NULL);
++ if (cllist_append(&D.actor.attr, attr, NULL))
++ return 1;
+ return 0;
+ } else
+ auparse_goto_record_num(au, rnum);
+@@ -224,7 +225,8 @@ static unsigned int add_obj_attr(auparse
+ if ((auparse_find_field(au, str))) {
+ attr = set_record(0, rnum);
+ attr = set_field(attr, auparse_get_field_num(au));
+- cllist_append(&D.thing.attr, attr, NULL);
++ if (cllist_append(&D.thing.attr, attr, NULL))
++ return 1;
+ return 0;
+ } else
+ auparse_goto_record_num(au, rnum);
+@@ -360,21 +362,23 @@ static void collect_id_obj2(auparse_stat
+ }
+ }
+
+-static void collect_path_attrs(auparse_state_t *au)
++static int collect_path_attrs(auparse_state_t *au)
+ {
+ value_t attr;
+ unsigned int rnum = auparse_get_record_num(au);
+
+ auparse_first_field(au);
+ if (add_obj_attr(au, "mode", rnum))
+- return; // Failed opens don't have anything else
++ return 1; // Failed opens don't have anything else
+
+ // All the rest of the fields matter
+ while ((auparse_next_field(au))) {
+ attr = set_record(0, rnum);
+ attr = set_field(attr, auparse_get_field_num(au));
+- cllist_append(&D.thing.attr, attr, NULL);
++ if (cllist_append(&D.thing.attr, attr, NULL))
++ return 1;
+ }
++ return 0;
+ }
+
+ static void collect_cwd_attrs(auparse_state_t *au)
+--- a/src/auditctl-llist.c
++++ b/src/auditctl-llist.c
+@@ -1,7 +1,7 @@
+ /*
+ * ausearch-llist.c - Minimal linked list library
+-* Copyright (c) 2005 Red Hat Inc., Durham, North Carolina.
+-* All Rights Reserved.
++* Copyright (c) 2005 Red Hat Inc.
++* All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+ * terms of the GNU General Public License as published by the Free
+@@ -15,7 +15,7 @@
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to the
+-* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
++* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1335, USA.
+ *
+ * Authors:
+@@ -59,19 +59,17 @@ lnode *list_next(llist *l)
+ return l->cur;
+ }
+
+-void list_append(llist *l, struct audit_rule_data *r, size_t sz)
++int list_append(llist *l, struct audit_rule_data *r, size_t sz)
+ {
+ lnode* newnode;
+
+ newnode = malloc(sizeof(lnode));
+- if (newnode == NULL) {
+- printf("Out of memory. Check %s file, %d line", __FILE__, __LINE__);
+- return;
+- }
++ if (newnode == NULL)
++ return 1;
+
+ if (r) {
+ void *rr = malloc(sz);
+- if (rr)
++ if (rr)
+ memcpy(rr, r, sz);
+ newnode->r = rr;
+ } else
+@@ -89,6 +87,8 @@ void list_append(llist *l, struct audit_
+ // make newnode current
+ l->cur = newnode;
+ l->cnt++;
++
++ return 0;
+ }
+
+ void list_clear(llist* l)
+--- a/src/auditctl-llist.h
++++ b/src/auditctl-llist.h
+@@ -1,6 +1,6 @@
+ /*
+ * auditctl-llist.h - Header file for ausearch-llist.c
+-* Copyright (c) 2005 Red Hat Inc., Durham, North Carolina.
++* Copyright (c) 2005 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+@@ -50,7 +50,7 @@ void list_first(llist *l);
+ void list_last(llist *l);
+ lnode *list_next(llist *l);
+ static inline lnode *list_get_cur(llist *l) { return l->cur; }
+-void list_append(llist *l, struct audit_rule_data *r, size_t sz);
++int list_append(llist *l, struct audit_rule_data *r, size_t sz);
+ void list_clear(llist* l);
+
+ #endif
+--- a/src/ausearch-avc.c
++++ b/src/ausearch-avc.c
+@@ -1,7 +1,7 @@
+ /*
+ * ausearch-avc.c - Minimal linked list library for avcs
+-* Copyright (c) 2006,2008,2014 Red Hat Inc., Durham, North Carolina.
+-* All Rights Reserved.
++* Copyright (c) 2006,2008,2014 Red Hat Inc.
++* All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+ * terms of the GNU General Public License as published by the Free
+@@ -15,7 +15,7 @@
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to the
+-* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
++* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1335, USA.
+ *
+ * Authors:
+@@ -62,15 +62,13 @@ static void alist_last(alist *l)
+ l->cur = cur;
+ }
+
+-void alist_append(alist *l, anode *node)
++int alist_append(alist *l, anode *node)
+ {
+ anode* newnode;
+
+ newnode = malloc(sizeof(anode));
+- if (newnode == NULL) {
+- printf("Out of memory. Check %s file, %d line", __FILE__, __LINE__);
+- return;
+- }
++ if (newnode == NULL)
++ return 1;
+
+ if (node->scontext)
+ newnode->scontext = node->scontext;
+@@ -108,6 +106,8 @@ void alist_append(alist *l, anode *node)
+ // make newnode current
+ l->cur = newnode;
+ l->cnt++;
++
++ return 0;
+ }
+
+ int alist_find_subj(alist *l)
+--- a/src/ausearch-avc.h
++++ b/src/ausearch-avc.h
+@@ -1,6 +1,6 @@
+ /*
+ * ausearch-avc.h - Header file for ausearch-string.c
+-* Copyright (c) 2006,2008 Red Hat Inc., Durham, North Carolina.
++* Copyright (c) 2006,2008 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+@@ -54,7 +54,7 @@ void alist_create(alist *l);
+ static inline void alist_first(alist *l) { l->cur = l->head; }
+ anode *alist_next(alist *l);
+ static inline anode *alist_get_cur(alist *l) { return l->cur; }
+-void alist_append(alist *l, anode *node);
++int alist_append(alist *l, anode *node);
+ void anode_init(anode *an);
+ void anode_clear(anode *an);
+ void alist_clear(alist* l);
+--- a/src/ausearch-int.c
++++ b/src/ausearch-int.c
+@@ -1,6 +1,6 @@
+ /*
+ * ausearch-int.c - Minimal linked list library for integers
+-* Copyright (c) 2005,2008 Red Hat Inc., Durham, North Carolina.
++* Copyright (c) 2005,2008 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+@@ -41,15 +41,13 @@ int_node *ilist_next(ilist *l)
+ return l->cur;
+ }
+
+-void ilist_append(ilist *l, int num, unsigned int hits, int aux)
++int ilist_append(ilist *l, int num, unsigned int hits, int aux)
+ {
+ int_node* newnode;
+
+ newnode = malloc(sizeof(int_node));
+- if (newnode == NULL) {
+- printf("Out of memory. Check %s file, %d line", __FILE__, __LINE__);
+- return;
+- }
++ if (newnode == NULL)
++ return 1;
+
+ newnode->num = num;
+ newnode->hits = hits;
+@@ -65,6 +63,8 @@ void ilist_append(ilist *l, int num, uns
+ // make newnode current
+ l->cur = newnode;
+ l->cnt++;
++
++ return 0;
+ }
+
+ void ilist_clear(ilist* l)
+--- a/src/ausearch-int.h
++++ b/src/ausearch-int.h
+@@ -1,6 +1,6 @@
+ /*
+ * ausearch-int.h - Header file for ausearch-int.c
+-* Copyright (c) 2005,2008 Red Hat Inc., Durham, North Carolina.
++* Copyright (c) 2005,2008 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+@@ -48,7 +48,7 @@ void ilist_create(ilist *l);
+ static inline void ilist_first(ilist *l) { l->cur = l->head; }
+ int_node *ilist_next(ilist *l);
+ static inline int_node *ilist_get_cur(ilist *l) { return l->cur; }
+-void ilist_append(ilist *l, int num, unsigned int hits, int aux);
++int ilist_append(ilist *l, int num, unsigned int hits, int aux);
+ void ilist_clear(ilist* l);
+
+ /* append a number if its not already on the list */
+--- a/src/ausearch-llist.c
++++ b/src/ausearch-llist.c
+@@ -1,6 +1,6 @@
+ /*
+ * ausearch-llist.c - Minimal linked list library
+-* Copyright (c) 2005-2008,2011,2016 Red Hat Inc., Durham, North Carolina.
++* Copyright (c) 2005-2008,2011,2016 Red Hat Inc.
+ * Copyright (c) 2011 IBM Corp.
+ * All Rights Reserved.
+ *
+@@ -102,15 +102,13 @@ lnode *list_prev(llist *l)
+ return l->cur;
+ }
+
+-void list_append(llist *l, lnode *node)
++int list_append(llist *l, lnode *node)
+ {
+ lnode* newnode;
+
+ newnode = malloc(sizeof(lnode));
+- if (newnode == NULL) {
+- printf("Out of memory. Check %s file, %d line", __FILE__, __LINE__);
+- return;
+- }
++ if (newnode == NULL)
++ return 1;
+
+ if (node->message)
+ newnode->message = node->message;
+@@ -123,7 +121,7 @@ void list_append(llist *l, lnode *node)
+ newnode->type = node->type;
+ newnode->a0 = node->a0;
+ newnode->a1 = node->a1;
+- newnode->item = l->cnt;
++ newnode->item = l->cnt;
+ newnode->next = NULL;
+
+ // if we are at top, fix this up
+@@ -135,6 +133,8 @@ void list_append(llist *l, lnode *node)
+ // make newnode current
+ l->cur = newnode;
+ l->cnt++;
++
++ return 0;
+ }
+
+ int list_find_item(llist *l, unsigned int i)
+--- a/src/ausearch-llist.h
++++ b/src/ausearch-llist.h
+@@ -107,7 +107,7 @@ void list_last(llist *l);
+ lnode *list_next(llist *l);
+ lnode *list_prev(llist *l);
+ static inline lnode *list_get_cur(llist *l) { return l->cur; }
+-void list_append(llist *l, lnode *node);
++int list_append(llist *l, lnode *node);
+ void list_clear(llist* l);
+ int list_get_event(llist* l, event *e);
+
+--- a/src/ausearch-nvpair.c
++++ b/src/ausearch-nvpair.c
+@@ -1,6 +1,6 @@
+ /*
+ * ausearch-nvpair.c - Minimal linked list library for name-value pairs
+-* Copyright (c) 2006-08 Red Hat Inc., Durham, North Carolina.
++* Copyright (c) 2006-08 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+@@ -42,13 +42,11 @@ nvnode *search_list_next(nvlist *l)
+ return l->cur;
+ }
+
+-void search_list_append(nvlist *l, nvnode *node)
++int search_list_append(nvlist *l, nvnode *node)
+ {
+ nvnode* newnode = malloc(sizeof(nvnode));
+- if (newnode == NULL) {
+- printf("Out of memory. Check %s file, %d line", __FILE__, __LINE__);
+- return;
+- }
++ if (newnode == NULL)
++ return 1;
+
+ newnode->name = node->name;
+ newnode->val = node->val;
+@@ -66,6 +64,8 @@ void search_list_append(nvlist *l, nvnod
+ // make newnode current
+ l->cur = newnode;
+ l->cnt++;
++
++ return 0;
+ }
+
+ int search_list_find_val(nvlist *l, long val)
+--- a/src/ausearch-nvpair.h
++++ b/src/ausearch-nvpair.h
+@@ -1,6 +1,6 @@
+ /*
+ * ausearch-nvpair.h - Header file for ausearch-nvpair.c
+-* Copyright (c) 2006-08 Red Hat Inc., Durham, North Carolina.
++* Copyright (c) 2006-08 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+@@ -48,7 +48,7 @@ void search_list_create(nvlist *l);
+ static inline void search_list_first(nvlist *l) { l->cur = l->head; }
+ nvnode *search_list_next(nvlist *l);
+ static inline nvnode *search_list_get_cur(nvlist *l) { return l->cur; }
+-void search_list_append(nvlist *l, nvnode *node);
++int search_list_append(nvlist *l, nvnode *node);
+ void search_list_clear(nvlist* l);
+
+ /* Given a numeric index, find that record. */
+--- a/src/ausearch-string.c
++++ b/src/ausearch-string.c
+@@ -44,15 +44,13 @@ snode *slist_next(slist *l)
+ return l->cur;
+ }
+
+-void slist_append(slist *l, snode *node)
++int slist_append(slist *l, snode *node)
+ {
+ snode* newnode;
+
+ newnode = malloc(sizeof(snode));
+- if (newnode == NULL) {
+- printf("Out of memory. Check %s file, %d line", __FILE__, __LINE__);
+- return;
+- }
++ if (newnode == NULL)
++ return 1;
+
+ if (node->str)
+ newnode->str = node->str;
+@@ -79,6 +77,8 @@ void slist_append(slist *l, snode *node)
+ // make newnode current
+ l->cur = newnode;
+ l->cnt++;
++
++ return 0;
+ }
+
+ void slist_clear(slist* l)
+--- a/src/ausearch-string.h
++++ b/src/ausearch-string.h
+@@ -49,7 +49,7 @@ void slist_create(slist *l);
+ static inline void slist_first(slist *l) { l->cur = l->head; }
+ snode *slist_next(slist *l);
+ static inline snode *slist_get_cur(slist *l) { return l->cur; }
+-void slist_append(slist *l, snode *node);
++int slist_append(slist *l, snode *node);
+ void slist_clear(slist* l);
+
+ /* append a string if its not already on the list */
+--- a/tools/aulastlog/aulastlog-llist.c
++++ b/tools/aulastlog/aulastlog-llist.c
+@@ -1,7 +1,7 @@
+ /*
+ * aulastlog-llist.c - Minimal linked list library
+-* Copyright (c) 2008 Red Hat Inc., Durham, North Carolina.
+-* All Rights Reserved.
++* Copyright (c) 2008 Red Hat Inc..
++* All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+ * terms of the GNU General Public License as published by the Free
+@@ -15,7 +15,7 @@
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to the
+-* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
++* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1335, USA.
+ *
+ * Authors:
+@@ -41,15 +41,13 @@ lnode *list_next(llist *l)
+ return l->cur;
+ }
+
+-void list_append(llist *l, lnode *node)
++int list_append(llist *l, lnode *node)
+ {
+ lnode* newnode;
+
+ newnode = malloc(sizeof(lnode));
+- if (newnode == NULL) {
+- printf("Out of memory. Check %s file, %d line", __FILE__, __LINE__);
+- return;
+- }
++ if (newnode == NULL)
++ return 1;
+
+ newnode->sec = node->sec;
+ newnode->uid = node->uid;
+@@ -62,7 +60,7 @@ void list_append(llist *l, lnode *node)
+ newnode->term = strdup(node->term);
+ else
+ newnode->term = NULL;
+- newnode->item = l->cnt;
++ newnode->item = l->cnt;
+ newnode->next = NULL;
+
+ // if we are at top, fix this up
+@@ -74,6 +72,8 @@ void list_append(llist *l, lnode *node)
+ // make newnode current
+ l->cur = newnode;
+ l->cnt++;
++
++ return 0;
+ }
+
+ void list_clear(llist* l)
+--- a/tools/aulastlog/aulastlog-llist.h
++++ b/tools/aulastlog/aulastlog-llist.h
+@@ -1,6 +1,6 @@
+ /*
+ * aulastlog-llist.h - Header file for aulastlog-llist.c
+-* Copyright (c) 2008 Red Hat Inc., Durham, North Carolina.
++* Copyright (c) 2008 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * This software may be freely redistributed and/or modified under the
+@@ -53,7 +53,7 @@ static inline void list_first(llist *l)
+ lnode *list_next(llist *l);
+ static inline lnode *list_get_cur(llist *l) { return l->cur; }
+ static inline unsigned int list_get_cnt(llist *l) { return l->cnt; }
+-void list_append(llist *l, lnode *node);
++int list_append(llist *l, lnode *node);
+ void list_clear(llist* l);
+ int list_update_login(llist* l, time_t t);
+ int list_update_host(llist* l, const char *h);
include $(TOPDIR)/rules.mk
PKG_NAME:=bcm27xx-utils
-PKG_VERSION:=2024-01-18
+PKG_VERSION:=2024-04-24
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/raspberrypi/utils.git
-PKG_SOURCE_VERSION:=e65f5ec102e74218cda7da9fdc8b1caa0fd1127d
-PKG_MIRROR_HASH:=ea946fc4a86875c5d1efc35b2bc80f6b5482afc3d1ea13853b69abc2b4a2eee6
+PKG_SOURCE_VERSION:=451b9881b72cb994c102724b5a7d9b93f97dc315
+PKG_MIRROR_HASH:=b453976171187e0ffe7cacfdcab36cec6b5d02db8b6d978cb9afbbcafcfcff9d
PKG_FLAGS:=nonshared
PKG_BUILD_FLAGS:=no-lto
PKG_NAME:=mtd-utils
PKG_VERSION:=2.1.6
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://infraroot.at/pub/mtd/
MAKE_FLAGS += LDLIBS+="$(LIBGCC_S)"
CONFIGURE_ARGS += \
- --disable-tests \
+ --enable-tests \
--without-crypto \
--without-xattr \
--without-zstd \
define Package/nand-utils/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) \
- $(PKG_INSTALL_DIR)/usr/sbin/{flash_erase,nanddump,nandwrite,nandtest,mtdinfo} $(1)/usr/sbin/
+ $(PKG_INSTALL_DIR)/usr/sbin/{flash_erase,nanddump,nandwrite,nandtest,mtdinfo} \
+ $(PKG_INSTALL_DIR)/usr/lib/mtd-utils/nandbiterrs $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,ubi-utils))
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/jow-/ucode.git
-PKG_SOURCE_DATE:=2024-04-07
-PKG_SOURCE_VERSION:=5507654a498a339c44b642f62e203e1d5fb1f725
-PKG_MIRROR_HASH:=40d3df5308faaf3cddfca4ebbcd9ee7fff98cf7e7d406dc177972a7abf0ca16b
+PKG_SOURCE_DATE:=2024-05-09
+PKG_SOURCE_VERSION:=0d823e702bfe5f2bb5be694030a98afedf34aa6b
+PKG_MIRROR_HASH:=c52d499d2490e958e36ed80c32e8fd6d94cacf3b43b9d14c45c68a25bc44d536
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_LICENSE:=ISC
rtnl, RTNL_SUPPORT, +libnl-tiny +libubox, \
The rtnl plugin provides access to the Linux routing netlink API.))
+$(eval $(call UcodeModule, \
+ socket, SOCKET_SUPPORT, , \
+ The socket plugin provides access to IPv4, IPv6, Unix and packet socket APIs.))
+
$(eval $(call UcodeModule, \
struct, STRUCT_SUPPORT, , \
The struct plugin implements Python 3 compatible struct.pack/unpack functionality.))
config i686
bool
+config loongarch64
+ select ARCH_64BIT
+ bool
+
config m68k
bool
default "armeb" if armeb
default "i386" if i386
default "i686" if i686
+ default "loongarch64" if loongarch64
default "m68k" if m68k
default "mips" if mips
default "mipsel" if mipsel
FEATURES:=dt squashfs nand ramdisk gpio source-only
KERNEL_PATCHVER:=6.1
+KERNEL_TESTING_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
--- /dev/null
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_AIROHA=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_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GIC_V3=y
+CONFIG_ARM_GIC_V3_ITS=y
+CONFIG_ARM_GIC_V3_ITS_PCI=y
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_HEAVY_MB=y
+# CONFIG_ARM_HIGHBANK_CPUIDLE 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_PSCI=y
+CONFIG_ARM_PSCI_FW=y
+# CONFIG_ARM_SMMU is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=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_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_EN7523=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_IDLE=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_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_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=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_DMA_OPS=y
+CONFIG_DTC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=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_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_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_CDEV=y
+CONFIG_GPIO_EN7523=y
+CONFIG_GPIO_GENERIC=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_HOTPLUG_CORE_SYNC=y
+CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HW_RANDOM=y
+CONFIG_HZ_FIXED=0
+CONFIG_INITRAMFS_SOURCE=""
+# 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_IRQCHIP=y
+CONFIG_IRQSTACKS=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED 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_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGRATION=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_FIT_FW=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+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_SELFTESTS=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=2
+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_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_PERCPU=y
+CONFIG_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIE_MEDIATEK=y
+CONFIG_PCIE_PME=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_PINCTRL=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_SYSFS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_FSL=y
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=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_AIROHA_EN7523=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_STACKTRACE=y
+# CONFIG_SWAP is not set
+CONFIG_SWPHY=y
+CONFIG_SWP_EMULATE=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_TREE_RCU=y
+CONFIG_TREE_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_SUPPORT=y
+CONFIG_USB_XHCI_HCD=y
+# CONFIG_USB_XHCI_PLATFORM is not set
+CONFIG_USE_OF=y
+# CONFIG_VFP is not set
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_XZ_DEC_ARM=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
--- /dev/null
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -353,6 +353,12 @@ config SPI_DLN2
+ This driver can also be built as a module. If so, the module
+ will be called spi-dln2.
+
++config SPI_AIROHA_EN7523
++ bool "Airoha EN7523 SPI controller support"
++ depends on ARCH_AIROHA
++ help
++ This enables SPI controller support for the Airoha EN7523 SoC.
++
+ config SPI_EP93XX
+ tristate "Cirrus Logic EP93xx SPI controller"
+ depends on ARCH_EP93XX || COMPILE_TEST
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -50,6 +50,7 @@ obj-$(CONFIG_SPI_DW_BT1) += spi-dw-bt1.
+ obj-$(CONFIG_SPI_DW_MMIO) += spi-dw-mmio.o
+ obj-$(CONFIG_SPI_DW_PCI) += spi-dw-pci.o
+ obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o
++obj-$(CONFIG_SPI_AIROHA_EN7523) += spi-en7523.o
+ obj-$(CONFIG_SPI_FALCON) += spi-falcon.o
+ obj-$(CONFIG_SPI_FSI) += spi-fsi.o
+ obj-$(CONFIG_SPI_FSL_CPM) += spi-fsl-cpm.o
+--- /dev/null
++++ b/drivers/spi/spi-en7523.c
+@@ -0,0 +1,313 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/mod_devicetable.h>
++#include <linux/spi/spi.h>
++
++
++#define ENSPI_READ_IDLE_EN 0x0004
++#define ENSPI_MTX_MODE_TOG 0x0014
++#define ENSPI_RDCTL_FSM 0x0018
++#define ENSPI_MANUAL_EN 0x0020
++#define ENSPI_MANUAL_OPFIFO_EMPTY 0x0024
++#define ENSPI_MANUAL_OPFIFO_WDATA 0x0028
++#define ENSPI_MANUAL_OPFIFO_FULL 0x002C
++#define ENSPI_MANUAL_OPFIFO_WR 0x0030
++#define ENSPI_MANUAL_DFIFO_FULL 0x0034
++#define ENSPI_MANUAL_DFIFO_WDATA 0x0038
++#define ENSPI_MANUAL_DFIFO_EMPTY 0x003C
++#define ENSPI_MANUAL_DFIFO_RD 0x0040
++#define ENSPI_MANUAL_DFIFO_RDATA 0x0044
++#define ENSPI_IER 0x0090
++#define ENSPI_NFI2SPI_EN 0x0130
++
++// TODO not in spi block
++#define ENSPI_CLOCK_DIVIDER ((void __iomem *)0x1fa201c4)
++
++#define OP_CSH 0x00
++#define OP_CSL 0x01
++#define OP_CK 0x02
++#define OP_OUTS 0x08
++#define OP_OUTD 0x09
++#define OP_OUTQ 0x0A
++#define OP_INS 0x0C
++#define OP_INS0 0x0D
++#define OP_IND 0x0E
++#define OP_INQ 0x0F
++#define OP_OS2IS 0x10
++#define OP_OS2ID 0x11
++#define OP_OS2IQ 0x12
++#define OP_OD2IS 0x13
++#define OP_OD2ID 0x14
++#define OP_OD2IQ 0x15
++#define OP_OQ2IS 0x16
++#define OP_OQ2ID 0x17
++#define OP_OQ2IQ 0x18
++#define OP_OSNIS 0x19
++#define OP_ODNID 0x1A
++
++#define MATRIX_MODE_AUTO 1
++#define CONF_MTX_MODE_AUTO 0
++#define MANUALEN_AUTO 0
++#define MATRIX_MODE_MANUAL 0
++#define CONF_MTX_MODE_MANUAL 9
++#define MANUALEN_MANUAL 1
++
++#define _ENSPI_MAX_XFER 0x1ff
++
++#define REG(x) (iobase + x)
++
++
++static void __iomem *iobase;
++
++
++static void opfifo_write(u32 cmd, u32 len)
++{
++ u32 tmp = ((cmd & 0x1f) << 9) | (len & 0x1ff);
++
++ writel(tmp, REG(ENSPI_MANUAL_OPFIFO_WDATA));
++
++ /* Wait for room in OPFIFO */
++ while (readl(REG(ENSPI_MANUAL_OPFIFO_FULL)))
++ ;
++
++ /* Shift command into OPFIFO */
++ writel(1, REG(ENSPI_MANUAL_OPFIFO_WR));
++
++ /* Wait for command to finish */
++ while (!readl(REG(ENSPI_MANUAL_OPFIFO_EMPTY)))
++ ;
++}
++
++static void set_cs(int state)
++{
++ if (state)
++ opfifo_write(OP_CSH, 1);
++ else
++ opfifo_write(OP_CSL, 1);
++}
++
++static void manual_begin_cmd(void)
++{
++ /* Disable read idle state */
++ writel(0, REG(ENSPI_READ_IDLE_EN));
++
++ /* Wait for FSM to reach idle state */
++ while (readl(REG(ENSPI_RDCTL_FSM)))
++ ;
++
++ /* Set SPI core to manual mode */
++ writel(CONF_MTX_MODE_MANUAL, REG(ENSPI_MTX_MODE_TOG));
++ writel(MANUALEN_MANUAL, REG(ENSPI_MANUAL_EN));
++}
++
++static void manual_end_cmd(void)
++{
++ /* Set SPI core to auto mode */
++ writel(CONF_MTX_MODE_AUTO, REG(ENSPI_MTX_MODE_TOG));
++ writel(MANUALEN_AUTO, REG(ENSPI_MANUAL_EN));
++
++ /* Enable read idle state */
++ writel(1, REG(ENSPI_READ_IDLE_EN));
++}
++
++static void dfifo_read(u8 *buf, int len)
++{
++ int i;
++
++ for (i = 0; i < len; i++) {
++ /* Wait for requested data to show up in DFIFO */
++ while (readl(REG(ENSPI_MANUAL_DFIFO_EMPTY)))
++ ;
++ buf[i] = readl(REG(ENSPI_MANUAL_DFIFO_RDATA));
++ /* Queue up next byte */
++ writel(1, REG(ENSPI_MANUAL_DFIFO_RD));
++ }
++}
++
++static void dfifo_write(const u8 *buf, int len)
++{
++ int i;
++
++ for (i = 0; i < len; i++) {
++ /* Wait for room in DFIFO */
++ while (readl(REG(ENSPI_MANUAL_DFIFO_FULL)))
++ ;
++ writel(buf[i], REG(ENSPI_MANUAL_DFIFO_WDATA));
++ }
++}
++
++#if 0
++static void set_spi_clock_speed(int freq_mhz)
++{
++ u32 tmp, val;
++
++ tmp = readl(ENSPI_CLOCK_DIVIDER);
++ tmp &= 0xffff0000;
++ writel(tmp, ENSPI_CLOCK_DIVIDER);
++
++ val = (400 / (freq_mhz * 2));
++ tmp |= (val << 8) | 1;
++ writel(tmp, ENSPI_CLOCK_DIVIDER);
++}
++#endif
++
++static void init_hw(void)
++{
++ /* Disable manual/auto mode clash interrupt */
++ writel(0, REG(ENSPI_IER));
++
++ // TODO via clk framework
++ // set_spi_clock_speed(50);
++
++ /* Disable DMA */
++ writel(0, REG(ENSPI_NFI2SPI_EN));
++}
++
++static int xfer_read(struct spi_transfer *xfer)
++{
++ int opcode;
++ uint8_t *buf = xfer->rx_buf;
++
++ switch (xfer->rx_nbits) {
++ case SPI_NBITS_SINGLE:
++ opcode = OP_INS;
++ break;
++ case SPI_NBITS_DUAL:
++ opcode = OP_IND;
++ break;
++ case SPI_NBITS_QUAD:
++ opcode = OP_INQ;
++ break;
++ }
++
++ opfifo_write(opcode, xfer->len);
++ dfifo_read(buf, xfer->len);
++
++ return xfer->len;
++}
++
++static int xfer_write(struct spi_transfer *xfer, int next_xfer_is_rx)
++{
++ int opcode;
++ const uint8_t *buf = xfer->tx_buf;
++
++ if (next_xfer_is_rx) {
++ /* need to use Ox2Ix opcode to set the core to input afterwards */
++ switch (xfer->tx_nbits) {
++ case SPI_NBITS_SINGLE:
++ opcode = OP_OS2IS;
++ break;
++ case SPI_NBITS_DUAL:
++ opcode = OP_OS2ID;
++ break;
++ case SPI_NBITS_QUAD:
++ opcode = OP_OS2IQ;
++ break;
++ }
++ } else {
++ switch (xfer->tx_nbits) {
++ case SPI_NBITS_SINGLE:
++ opcode = OP_OUTS;
++ break;
++ case SPI_NBITS_DUAL:
++ opcode = OP_OUTD;
++ break;
++ case SPI_NBITS_QUAD:
++ opcode = OP_OUTQ;
++ break;
++ }
++ }
++
++ opfifo_write(opcode, xfer->len);
++ dfifo_write(buf, xfer->len);
++
++ return xfer->len;
++}
++
++size_t max_transfer_size(struct spi_device *spi)
++{
++ return _ENSPI_MAX_XFER;
++}
++
++int transfer_one_message(struct spi_controller *ctrl, struct spi_message *msg)
++{
++ struct spi_transfer *xfer;
++ int next_xfer_is_rx = 0;
++
++ manual_begin_cmd();
++ set_cs(0);
++ list_for_each_entry(xfer, &msg->transfers, transfer_list) {
++ if (xfer->tx_buf) {
++ if (!list_is_last(&xfer->transfer_list, &msg->transfers)
++ && list_next_entry(xfer, transfer_list)->rx_buf != NULL)
++ next_xfer_is_rx = 1;
++ else
++ next_xfer_is_rx = 0;
++ msg->actual_length += xfer_write(xfer, next_xfer_is_rx);
++ } else if (xfer->rx_buf) {
++ msg->actual_length += xfer_read(xfer);
++ }
++ }
++ set_cs(1);
++ manual_end_cmd();
++
++ msg->status = 0;
++ spi_finalize_current_message(ctrl);
++
++ return 0;
++}
++
++static int spi_probe(struct platform_device *pdev)
++{
++ struct spi_controller *ctrl;
++ int err;
++
++ ctrl = devm_spi_alloc_master(&pdev->dev, 0);
++ if (!ctrl) {
++ dev_err(&pdev->dev, "Error allocating SPI controller\n");
++ return -ENOMEM;
++ }
++
++ iobase = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
++ if (IS_ERR(iobase)) {
++ dev_err(&pdev->dev, "Could not map SPI register address");
++ return -ENOMEM;
++ }
++
++ init_hw();
++
++ ctrl->dev.of_node = pdev->dev.of_node;
++ ctrl->flags = SPI_CONTROLLER_HALF_DUPLEX;
++ ctrl->mode_bits = SPI_RX_DUAL | SPI_TX_DUAL;
++ ctrl->max_transfer_size = max_transfer_size;
++ ctrl->transfer_one_message = transfer_one_message;
++ err = devm_spi_register_controller(&pdev->dev, ctrl);
++ if (err) {
++ dev_err(&pdev->dev, "Could not register SPI controller\n");
++ return -ENODEV;
++ }
++
++ return 0;
++}
++
++static const struct of_device_id spi_of_ids[] = {
++ { .compatible = "airoha,en7523-spi" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, spi_of_ids);
++
++static struct platform_driver spi_driver = {
++ .probe = spi_probe,
++ .driver = {
++ .name = "airoha-en7523-spi",
++ .of_match_table = spi_of_ids,
++ },
++};
++
++module_platform_driver(spi_driver);
++
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("Bert Vermeulen <bert@biot.com>");
++MODULE_DESCRIPTION("Airoha EN7523 SPI driver");
FEATURES+=cpiogz ext4 ramdisk squashfs targz vmdk
KERNEL_PATCHVER:=6.1
+KERNEL_TESTING_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
--- /dev/null
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MMAP_RND_BITS=8
+CONFIG_ARCH_MULTIPLATFORM=y
+# CONFIG_ARCH_MULTI_V4 is not set
+# CONFIG_ARCH_MULTI_V4T is not set
+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_VIRT=y
+CONFIG_ARM=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_HAS_SG_CHAIN=y
+CONFIG_ARM_HEAVY_MB=y
+# CONFIG_ARM_HIGHBANK_CPUIDLE 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_THUMB=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_CACHE_L2X0=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_DCACHE_WRITETHROUGH is not set
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_SPECTRE=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DMA_OPS=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_VDSO_32=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_HAVE_SMP=y
+CONFIG_HZ_FIXED=0
+CONFIG_HZ_PERIODIC=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_NEON=y
+CONFIG_NR_CPUS=4
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PHYS_OFFSET=0
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+# CONFIG_UNWINDER_FRAME_POINTER is not set
+CONFIG_USE_OF=y
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
--- /dev/null
+CONFIG_64BIT=y
+CONFIG_ACPI_APEI=y
+# CONFIG_ACPI_FFH is not set
+# CONFIG_ACPI_FPDT is not set
+CONFIG_ACPI_HMAT=y
+CONFIG_ACPI_PCC=y
+CONFIG_AHCI_IMX=y
+CONFIG_AHCI_MVEBU=y
+CONFIG_AHCI_QORIQ=y
+CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y
+CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM2835=y
+# CONFIG_ARCH_BCMBCA is not set
+CONFIG_ARCH_BCM_IPROC=y
+CONFIG_ARCH_BRCMSTB=y
+CONFIG_ARCH_HISI=y
+CONFIG_ARCH_INTEL_SOCFPGA=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=24
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_MVEBU=y
+CONFIG_ARCH_MXC=y
+CONFIG_ARCH_NXP=y
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+CONFIG_ARCH_R8A774A1=y
+CONFIG_ARCH_R8A774B1=y
+CONFIG_ARCH_R8A774C0=y
+CONFIG_ARCH_R8A774E1=y
+# CONFIG_ARCH_R8A77950 is not set
+# CONFIG_ARCH_R8A77951 is not set
+# CONFIG_ARCH_R8A77960 is not set
+# CONFIG_ARCH_R8A77961 is not set
+# CONFIG_ARCH_R8A77965 is not set
+# CONFIG_ARCH_R8A77970 is not set
+# CONFIG_ARCH_R8A77980 is not set
+# CONFIG_ARCH_R8A77990 is not set
+# CONFIG_ARCH_R8A77995 is not set
+# CONFIG_ARCH_R8A779A0 is not set
+# CONFIG_ARCH_R8A779F0 is not set
+# CONFIG_ARCH_R8A779G0 is not set
+CONFIG_ARCH_R9A07G043=y
+CONFIG_ARCH_R9A07G044=y
+CONFIG_ARCH_R9A07G054=y
+CONFIG_ARCH_R9A09G011=y
+CONFIG_ARCH_RENESAS=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_SYNQUACER=y
+CONFIG_ARCH_THUNDER=y
+CONFIG_ARCH_THUNDER2=y
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_ARCH_WANTS_NO_INSTR=y
+CONFIG_ARCH_ZYNQMP=y
+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
+CONFIG_ARM64_ERRATUM_1319367=y
+CONFIG_ARM64_ERRATUM_1418040=y
+CONFIG_ARM64_ERRATUM_1463225=y
+CONFIG_ARM64_ERRATUM_1508412=y
+CONFIG_ARM64_ERRATUM_1530923=y
+CONFIG_ARM64_ERRATUM_1542419=y
+CONFIG_ARM64_ERRATUM_1742098=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_2457168=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_834220=y
+CONFIG_ARM64_ERRATUM_843419=y
+CONFIG_ARM64_ERRATUM_845719=y
+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
+CONFIG_ARM64_PTR_AUTH_KERNEL=y
+CONFIG_ARM64_RAS_EXTN=y
+CONFIG_ARM64_SME=y
+CONFIG_ARM64_SVE=y
+CONFIG_ARM64_TAGGED_ADDR_ABI=y
+CONFIG_ARM64_TLB_RANGE=y
+CONFIG_ARM64_VA_BITS=48
+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_ARMADA_37XX_RWTM_MBOX is not set
+CONFIG_ARMADA_37XX_WATCHDOG=y
+CONFIG_ARMADA_THERMAL=y
+CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
+# CONFIG_ARM_DMC620_PMU is not set
+# CONFIG_ARM_MHU_V2 is not set
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
+CONFIG_ARM_SBSA_WATCHDOG=y
+CONFIG_ARM_SCPI_POWER_DOMAIN=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_ARM_SMCCC_SOC_ID=y
+CONFIG_ARM_SMC_WATCHDOG=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_PMU is not set
+# CONFIG_ARM_SMMU_V3_SVA is not set
+CONFIG_ATOMIC64_SELFTEST=y
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
+# CONFIG_AXI_DMAC is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BCM2711_THERMAL is not set
+CONFIG_BCM2835_MBOX=y
+CONFIG_BCM2835_POWER=y
+# CONFIG_BCM2835_THERMAL is not set
+# CONFIG_BCM2835_VCHIQ is not set
+CONFIG_BCM2835_WDT=y
+# CONFIG_BCMASP is not set
+# CONFIG_BCMGENET is not set
+# CONFIG_BCM_CYGNUS_PHY is not set
+# CONFIG_BCM_FLEXRM_MBOX is not set
+# CONFIG_BCM_NS_THERMAL is not set
+# CONFIG_BCM_PDC_MBOX is not set
+# CONFIG_BCM_SR_THERMAL is not set
+CONFIG_BCM_VIDEOCORE=y
+# CONFIG_BGMAC_PLATFORM is not set
+CONFIG_BLK_PM=y
+# CONFIG_BRCMSTB_PM is not set
+# CONFIG_BRCMSTB_THERMAL is not set
+CONFIG_BRCM_USB_PINMAP=y
+CONFIG_CAVIUM_ERRATUM_22375=y
+CONFIG_CAVIUM_ERRATUM_23144=y
+CONFIG_CAVIUM_ERRATUM_23154=y
+CONFIG_CAVIUM_ERRATUM_27456=y
+CONFIG_CAVIUM_ERRATUM_30115=y
+CONFIG_CAVIUM_TX2_ERRATUM_219=y
+CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
+CONFIG_CLK_BCM2711_DVP=y
+CONFIG_CLK_BCM2835=y
+CONFIG_CLK_BCM_NS2=y
+CONFIG_CLK_BCM_SR=y
+CONFIG_CLK_IMX8MM=y
+CONFIG_CLK_IMX8MN=y
+CONFIG_CLK_IMX8MP=y
+CONFIG_CLK_IMX8MQ=y
+CONFIG_CLK_IMX8QXP=y
+CONFIG_CLK_IMX8ULP=y
+CONFIG_CLK_IMX93=y
+CONFIG_CLK_INTEL_SOCFPGA=y
+CONFIG_CLK_INTEL_SOCFPGA64=y
+CONFIG_CLK_LS1028A_PLLDIG=y
+CONFIG_CLK_PX30=y
+CONFIG_CLK_QORIQ=y
+CONFIG_CLK_RASPBERRYPI=y
+CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
+CONFIG_CLK_RENESAS=y
+CONFIG_CLK_RK3308=y
+CONFIG_CLK_RK3328=y
+CONFIG_CLK_RK3368=y
+CONFIG_CLK_RK3399=y
+CONFIG_CLK_RK3568=y
+CONFIG_CLK_RK3588=y
+CONFIG_CLK_SP810=y
+CONFIG_CLK_SUNXI=y
+CONFIG_CLK_SUNXI_CLOCKS=y
+# CONFIG_CLK_SUNXI_PRCM_SUN6I is not set
+# CONFIG_CLK_SUNXI_PRCM_SUN8I is not set
+# CONFIG_CLK_SUNXI_PRCM_SUN9I is not set
+CONFIG_CLK_VEXPRESS_OSC=y
+CONFIG_CMA=y
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=19
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+CONFIG_CMA_SIZE_MBYTES=32
+# 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_FSL_FLEXSPI is not set
+# CONFIG_COMMON_CLK_FSL_SAI is not set
+CONFIG_COMMON_CLK_HI3516CV300=y
+CONFIG_COMMON_CLK_HI3519=y
+CONFIG_COMMON_CLK_HI3559A=y
+CONFIG_COMMON_CLK_HI3660=y
+CONFIG_COMMON_CLK_HI3670=y
+CONFIG_COMMON_CLK_HI3798CV200=y
+CONFIG_COMMON_CLK_HI6220=y
+CONFIG_COMMON_CLK_HI655X=y
+CONFIG_COMMON_CLK_ROCKCHIP=y
+CONFIG_COMMON_CLK_SCPI=y
+CONFIG_COMMON_CLK_ZYNQMP=y
+CONFIG_COMMON_RESET_HI3660=y
+CONFIG_COMMON_RESET_HI6220=y
+# CONFIG_COMPAT_32BIT_TIME is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_PM=y
+CONFIG_CRYPTO_AES_ARM64=y
+CONFIG_CRYPTO_AES_ARM64_BS=y
+CONFIG_CRYPTO_AES_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y
+CONFIG_CRYPTO_CHACHA20=y
+CONFIG_CRYPTO_CHACHA20_NEON=y
+CONFIG_CRYPTO_CRYPTD=y
+# CONFIG_CRYPTO_DEV_ALLWINNER is not set
+# CONFIG_CRYPTO_DEV_BCM_SPU is not set
+# CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM is not set
+# CONFIG_CRYPTO_DEV_HISI_HPRE is not set
+# CONFIG_CRYPTO_DEV_HISI_SEC2 is not set
+# CONFIG_CRYPTO_DEV_HISI_TRNG is not set
+# CONFIG_CRYPTO_DEV_OCTEONTX2_CPT is not set
+# CONFIG_CRYPTO_DEV_ROCKCHIP is not set
+# CONFIG_CRYPTO_DEV_ZYNQMP_AES is not set
+# CONFIG_CRYPTO_DEV_ZYNQMP_SHA3 is not set
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y
+CONFIG_CRYPTO_POLYVAL_ARM64_CE=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA256_ARM64=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA512_ARM64=y
+CONFIG_CRYPTO_SIMD=y
+# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set
+# CONFIG_CRYPTO_SM4_ARM64_CE_CCM is not set
+# CONFIG_CRYPTO_SM4_ARM64_CE_GCM is not set
+# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set
+# CONFIG_DEV_DAX_HMEM is not set
+CONFIG_DMA_BCM2835=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_DIRECT_REMAP=y
+# CONFIG_DMA_NUMA_CMA is not set
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMA_SUN6I=y
+CONFIG_DRM=y
+CONFIG_DRM_BOCHS=y
+CONFIG_DRM_BRIDGE=y
+# CONFIG_DRM_FSL_LDB is not set
+CONFIG_DRM_GEM_SHMEM_HELPER=y
+# 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 is not set
+# CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI is not set
+# CONFIG_DRM_IMX_DCSS is not set
+# CONFIG_DRM_IMX_LCDC is not set
+CONFIG_DRM_KMS_HELPER=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_BRIDGE=y
+# CONFIG_DRM_PANEL_HIMAX_HX8394 is not set
+# CONFIG_DRM_PANEL_JADARD_JD9365DA_H3 is not set
+# CONFIG_DRM_PANEL_NEWVISION_NV3051D is not set
+# CONFIG_DRM_PANEL_NOVATEK_NT36523 is not set
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+# CONFIG_DRM_PANEL_SONY_TD4353_JDI is not set
+# CONFIG_DRM_PANEL_STARTEK_KD070FHFID015 is not set
+# CONFIG_DRM_PANEL_VISIONOX_R66451 is not set
+# CONFIG_DRM_PANEL_VISIONOX_VTDR6130 is not set
+CONFIG_DRM_QXL=y
+# CONFIG_DRM_RCAR_DU is not set
+# CONFIG_DRM_ROCKCHIP is not set
+# CONFIG_DRM_RZG2L_MIPI_DSI is not set
+# CONFIG_DRM_SHMOBILE is not set
+CONFIG_DRM_TTM=y
+CONFIG_DRM_TTM_HELPER=y
+# CONFIG_DRM_V3D is not set
+CONFIG_DRM_VIRTIO_GPU=y
+CONFIG_DRM_VIRTIO_GPU_KMS=y
+CONFIG_DRM_VRAM_HELPER=y
+# CONFIG_DWMAC_SUN8I is not set
+# CONFIG_DWMAC_SUNXI is not set
+CONFIG_DW_WATCHDOG=y
+CONFIG_EFI_CAPSULE_LOADER=y
+CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y
+CONFIG_EFI_SOFT_RESERVE=y
+CONFIG_EFI_VARS_PSTORE=y
+# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set
+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_MODE_HELPERS=y
+CONFIG_FB_MX3=y
+# CONFIG_FB_SH_MOBILE_LCDC is not set
+# CONFIG_FB_XILINX is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_FSL_DPAA is not set
+# CONFIG_FSL_DPAA2_QDMA is not set
+CONFIG_FSL_ERRATUM_A008585=y
+# CONFIG_FSL_IMX8_DDR_PMU is not set
+# CONFIG_FSL_PQ_MDIO is not set
+CONFIG_FUJITSU_ERRATUM_010001=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+# CONFIG_GIANFAR is not set
+CONFIG_GPIO_BCM_XGS_IPROC=y
+CONFIG_GPIO_BRCMSTB=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_MPC8XXX=y
+CONFIG_GPIO_MXC=y
+CONFIG_GPIO_RASPBERRYPI_EXP=y
+CONFIG_GPIO_ROCKCHIP=y
+CONFIG_GPIO_THUNDERX=y
+CONFIG_GPIO_XLP=y
+CONFIG_GPIO_ZYNQ=y
+CONFIG_GPIO_ZYNQMP_MODEPIN=y
+CONFIG_HDMI=y
+CONFIG_HI3660_MBOX=y
+CONFIG_HI6220_MBOX=y
+CONFIG_HISILICON_ERRATUM_161600802=y
+CONFIG_HISILICON_LPC=y
+CONFIG_HISI_PMU=y
+CONFIG_HISI_THERMAL=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_ACPI=y
+# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=y
+# CONFIG_HW_RANDOM_HISI is not set
+# CONFIG_HW_RANDOM_HISTB is not set
+CONFIG_HW_RANDOM_VIRTIO=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALTERA=y
+# CONFIG_I2C_BCM2835 is not set
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_HIX5HD2 is not set
+CONFIG_I2C_IMX=y
+CONFIG_I2C_IMX_LPI2C=y
+CONFIG_I2C_RIIC=y
+# CONFIG_I2C_RZV2M is not set
+# CONFIG_I2C_SLAVE_TESTUNIT is not set
+CONFIG_I2C_SYNQUACER=y
+CONFIG_I2C_THUNDERX=y
+# CONFIG_I2C_XLP9XX is not set
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+# CONFIG_IMX2_WDT is not set
+# CONFIG_IMX8MM_THERMAL is not set
+# CONFIG_IMX8QXP_ADC is not set
+# CONFIG_IMX93_ADC is not set
+# CONFIG_IMX_DMA is not set
+# CONFIG_IMX_DSP is not set
+CONFIG_IMX_INTMUX=y
+CONFIG_IMX_IRQSTEER=y
+CONFIG_IMX_MBOX=y
+# CONFIG_IMX_MU_MSI is not set
+CONFIG_IMX_SCU=y
+CONFIG_IMX_SCU_PD=y
+# CONFIG_IMX_SC_THERMAL is not set
+# CONFIG_IMX_SC_WDT is not set
+# CONFIG_IMX_SDMA is not set
+# CONFIG_IMX_WEIM is not set
+# CONFIG_INPUT_BBNSM_PWRKEY is not set
+# CONFIG_INPUT_HISI_POWERKEY is not set
+# CONFIG_INPUT_IBM_PANEL is not set
+# CONFIG_INTEL_STRATIX10_RSU is not set
+# CONFIG_INTEL_STRATIX10_SERVICE is not set
+CONFIG_INTERCONNECT=y
+CONFIG_INTERCONNECT_IMX=y
+CONFIG_INTERCONNECT_IMX8MM=y
+CONFIG_INTERCONNECT_IMX8MN=y
+CONFIG_INTERCONNECT_IMX8MP=y
+CONFIG_INTERCONNECT_IMX8MQ=y
+# CONFIG_IOMMUFD is not set
+# CONFIG_IOMMU_DEBUGFS is not set
+# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
+CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
+CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y
+# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
+# CONFIG_IOMMU_IO_PGTABLE_DART is not set
+# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set
+CONFIG_IOMMU_SUPPORT=y
+# CONFIG_IPMMU_VMSA is not set
+# CONFIG_K3_DMA is not set
+CONFIG_KCMP=y
+# CONFIG_KEYBOARD_IMX_SC_KEY is not set
+# CONFIG_KEYBOARD_SUN4I_LRADC is not set
+CONFIG_KSM=y
+# CONFIG_KUNPENG_HCCS is not set
+CONFIG_KVM=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_PLATFORM is not set
+# CONFIG_MAILBOX_TEST is not set
+CONFIG_MARVELL_10G_PHY=y
+# CONFIG_MARVELL_CN10K_DDR_PMU is not set
+# CONFIG_MARVELL_CN10K_TAD_PMU is not set
+# CONFIG_MARVELL_GTI_WDT is not set
+CONFIG_MDIO_BCM_IPROC=y
+CONFIG_MDIO_BUS_MUX_BCM_IPROC=y
+CONFIG_MDIO_SUN4I=y
+# CONFIG_MFD_ALTERA_A10SR is not set
+CONFIG_MFD_ALTERA_SYSMGR=y
+# CONFIG_MFD_AXP20X_RSB is not set
+CONFIG_MFD_CORE=y
+CONFIG_MFD_HI655X_PMIC=y
+# CONFIG_MFD_KHADAS_MCU is not set
+CONFIG_MFD_SUN4I_GPADC=y
+# CONFIG_MFD_SUN6I_PRCM is not set
+CONFIG_MFD_SYSCON=y
+CONFIG_MFD_VEXPRESS_SYSREG=y
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_BCM2835=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_CAVIUM_THUNDERX=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_ROCKCHIP=y
+# CONFIG_MMC_MXC is not set
+CONFIG_MMC_RICOH_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ACPI=y
+CONFIG_MMC_SDHCI_CADENCE=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MMC_SDHCI_IPROC=y
+CONFIG_MMC_SDHCI_OF_ESDHC=y
+CONFIG_MMC_SDHCI_PCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SDHI_INTERNAL_DMAC=y
+# CONFIG_MMC_SDHI_SYS_DMAC is not set
+# CONFIG_MMC_SH_MMCIF is not set
+CONFIG_MMC_SUNXI=y
+CONFIG_MODULES_USE_ELF_RELA=y
+# CONFIG_MVNETA is not set
+# CONFIG_MVPP2 is not set
+# CONFIG_MV_XOR is not set
+# CONFIG_MX3_IPU is not set
+CONFIG_MXC_CLK=y
+CONFIG_MXC_CLK_SCU=y
+# CONFIG_MXS_DMA is not set
+CONFIG_NEED_SG_DMA_LENGTH=y
+# CONFIG_NET_VENDOR_ALLWINNER is not set
+CONFIG_NODES_SHIFT=4
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_NO_HZ=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=256
+CONFIG_NUMA=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y
+# CONFIG_NVHE_EL2_DEBUG is not set
+CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y
+# CONFIG_NVMEM_IMX_IIM is not set
+# CONFIG_NVMEM_IMX_OCOTP_ELE is not set
+CONFIG_NVMEM_IMX_OCOTP_SCU=y
+# CONFIG_NVMEM_LAYERSCAPE_SFP is not set
+CONFIG_NVMEM_ROCKCHIP_EFUSE=y
+# CONFIG_NVMEM_ROCKCHIP_OTP is not set
+# CONFIG_NVMEM_SNVS_LPGPR is not set
+# CONFIG_NVMEM_SUNXI_SID is not set
+# CONFIG_NVMEM_ZYNQMP is not set
+CONFIG_PCC=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_ARMADA_8K=y
+CONFIG_PCIE_BRCMSTB=y
+CONFIG_PCIE_HISI_STB=y
+CONFIG_PCIE_IPROC_MSI=y
+CONFIG_PCIE_IPROC_PLATFORM=y
+CONFIG_PCIE_LAYERSCAPE=y
+CONFIG_PCIE_MOBIVEIL_PLAT=y
+# CONFIG_PCIE_RCAR_EP is not set
+CONFIG_PCIE_RCAR_HOST=y
+CONFIG_PCIE_ROCKCHIP=y
+# CONFIG_PCIE_ROCKCHIP_DW_HOST is not set
+CONFIG_PCIE_ROCKCHIP_HOST=y
+CONFIG_PCIE_XILINX_CPM=y
+CONFIG_PCIE_XILINX_NWL=y
+CONFIG_PCI_AARDVARK=y
+CONFIG_PCI_HISI=y
+CONFIG_PCI_HOST_THUNDER_ECAM=y
+CONFIG_PCI_HOST_THUNDER_PEM=y
+CONFIG_PCI_IMX6=y
+CONFIG_PCI_IMX6_HOST=y
+CONFIG_PCI_IOV=y
+CONFIG_PCI_LAYERSCAPE=y
+CONFIG_PCI_PASID=y
+# CONFIG_PCI_RCAR_GEN2 is not set
+CONFIG_PHY_BCM_SR_PCIE=y
+CONFIG_PHY_BCM_SR_USB=y
+CONFIG_PHY_BRCM_SATA=y
+CONFIG_PHY_BRCM_USB=y
+CONFIG_PHY_FSL_IMX8M_PCIE=y
+# CONFIG_PHY_FSL_LYNX_28G is not set
+CONFIG_PHY_HI3660_USB=y
+CONFIG_PHY_HI3670_PCIE=y
+CONFIG_PHY_HI3670_USB=y
+CONFIG_PHY_HI6220_USB=y
+CONFIG_PHY_HISI_INNO_USB2=y
+# CONFIG_PHY_HISTB_COMBPHY is not set
+# CONFIG_PHY_MIXEL_LVDS_PHY is not set
+CONFIG_PHY_MVEBU_A3700_COMPHY=y
+CONFIG_PHY_MVEBU_A3700_UTMI=y
+CONFIG_PHY_MVEBU_A38X_COMPHY=y
+CONFIG_PHY_MVEBU_CP110_COMPHY=y
+CONFIG_PHY_NS2_PCIE=y
+CONFIG_PHY_NS2_USB_DRD=y
+# CONFIG_PHY_R8A779F0_ETHERNET_SERDES is not set
+# CONFIG_PHY_RCAR_GEN2 is not set
+CONFIG_PHY_RCAR_GEN3_PCIE=y
+CONFIG_PHY_RCAR_GEN3_USB2=y
+CONFIG_PHY_RCAR_GEN3_USB3=y
+# CONFIG_PHY_ROCKCHIP_DP is not set
+# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set
+CONFIG_PHY_ROCKCHIP_EMMC=y
+# CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY is not set
+# CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set
+# CONFIG_PHY_ROCKCHIP_INNO_HDMI is not set
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+# CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY is not set
+CONFIG_PHY_ROCKCHIP_PCIE=y
+CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
+CONFIG_PHY_ROCKCHIP_TYPEC=y
+# CONFIG_PHY_ROCKCHIP_USB is not set
+CONFIG_PHY_SUN4I_USB=y
+CONFIG_PHY_SUN50I_USB3=y
+# CONFIG_PHY_SUN6I_MIPI_DPHY is not set
+CONFIG_PHY_SUN9I_USB=y
+# CONFIG_PHY_XILINX_ZYNQMP is not set
+CONFIG_PINCTRL_IMX=y
+CONFIG_PINCTRL_IMX8DXL=y
+CONFIG_PINCTRL_IMX8MM=y
+CONFIG_PINCTRL_IMX8MN=y
+CONFIG_PINCTRL_IMX8MP=y
+CONFIG_PINCTRL_IMX8MQ=y
+CONFIG_PINCTRL_IMX8QM=y
+CONFIG_PINCTRL_IMX8QXP=y
+CONFIG_PINCTRL_IMX8ULP=y
+CONFIG_PINCTRL_IMX93=y
+# CONFIG_PINCTRL_IMXRT1050 is not set
+# CONFIG_PINCTRL_IMXRT1170 is not set
+CONFIG_PINCTRL_IMX_SCU=y
+CONFIG_PINCTRL_IPROC_GPIO=y
+CONFIG_PINCTRL_NS2_MUX=y
+CONFIG_PINCTRL_ROCKCHIP=y
+# CONFIG_PINCTRL_SUN20I_D1 is not set
+CONFIG_PINCTRL_SUN4I_A10=y
+CONFIG_PINCTRL_SUN50I_A100=y
+CONFIG_PINCTRL_SUN50I_A100_R=y
+CONFIG_PINCTRL_SUN50I_A64=y
+CONFIG_PINCTRL_SUN50I_A64_R=y
+CONFIG_PINCTRL_SUN50I_H5=y
+CONFIG_PINCTRL_SUN50I_H6=y
+CONFIG_PINCTRL_SUN50I_H616=y
+CONFIG_PINCTRL_SUN50I_H616_R=y
+CONFIG_PINCTRL_SUN50I_H6_R=y
+CONFIG_PINCTRL_SUN5I=y
+# CONFIG_PINCTRL_SUN6I_A31 is not set
+# CONFIG_PINCTRL_SUN6I_A31_R is not set
+# CONFIG_PINCTRL_SUN8I_A23 is not set
+# CONFIG_PINCTRL_SUN8I_A23_R is not set
+# CONFIG_PINCTRL_SUN8I_A33 is not set
+# CONFIG_PINCTRL_SUN8I_A83T is not set
+# CONFIG_PINCTRL_SUN8I_A83T_R is not set
+# CONFIG_PINCTRL_SUN8I_H3 is not set
+# CONFIG_PINCTRL_SUN8I_H3_R is not set
+# CONFIG_PINCTRL_SUN8I_V3S is not set
+# CONFIG_PINCTRL_SUN9I_A80 is not set
+# CONFIG_PINCTRL_SUN9I_A80_R is not set
+CONFIG_PINCTRL_ZYNQMP=y
+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_HISI=y
+CONFIG_POWER_RESET_VEXPRESS=y
+CONFIG_POWER_SUPPLY=y
+# CONFIG_PTP_1588_CLOCK_DTE is not set
+# CONFIG_PWM_BCM2835 is not set
+CONFIG_QCOM_FALKOR_ERRATUM_1003=y
+CONFIG_QCOM_FALKOR_ERRATUM_1009=y
+CONFIG_QCOM_FALKOR_ERRATUM_E1041=y
+CONFIG_QCOM_QDF2400_ERRATUM_0065=y
+CONFIG_QORIQ_THERMAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_RASPBERRYPI_POWER=y
+# CONFIG_RAVB is not set
+CONFIG_RCAR_DMAC=y
+# CONFIG_RCAR_GEN3_THERMAL is not set
+# CONFIG_RCAR_THERMAL is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_HI655X=y
+CONFIG_REGULATOR_PFUZE100=y
+# CONFIG_REGULATOR_VEXPRESS is not set
+CONFIG_RELOCATABLE=y
+# CONFIG_RENESAS_ETHER_SWITCH is not set
+CONFIG_RENESAS_OSTM=y
+# CONFIG_RENESAS_RZAWDT is not set
+# CONFIG_RENESAS_RZG2LWDT is not set
+# CONFIG_RENESAS_RZN1WDT is not set
+CONFIG_RENESAS_USB_DMAC=y
+# CONFIG_RENESAS_WDT is not set
+# CONFIG_RESET_BRCMSTB is not set
+CONFIG_RESET_IMX7=y
+# CONFIG_RESET_RASPBERRYPI is not set
+CONFIG_RESET_RZG2L_USBPHY_CTRL=y
+CONFIG_ROCKCHIP_IODOMAIN=y
+CONFIG_ROCKCHIP_IOMMU=y
+# CONFIG_ROCKCHIP_MBOX is not set
+CONFIG_ROCKCHIP_PM_DOMAINS=y
+# CONFIG_ROCKCHIP_SARADC is not set
+# CONFIG_ROCKCHIP_THERMAL is not set
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
+# CONFIG_RTC_DRV_BBNSM is not set
+# CONFIG_RTC_DRV_BRCMSTB is not set
+# CONFIG_RTC_DRV_FSL_FTM_ALARM is not set
+# CONFIG_RTC_DRV_IMXDI is not set
+# CONFIG_RTC_DRV_IMX_SC is not set
+CONFIG_RTC_DRV_MV=y
+# CONFIG_RTC_DRV_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+# CONFIG_RTC_DRV_SH is not set
+CONFIG_RTC_I2C_AND_SPI=y
+# CONFIG_RZG2L_ADC is not set
+# CONFIG_RZG2L_THERMAL is not set
+CONFIG_RZ_DMAC=y
+CONFIG_RZ_MTU3=y
+CONFIG_SATA_SIL24=y
+# CONFIG_SCHED_CORE is not set
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+# CONFIG_SENSORS_ARM_SCPI is not set
+CONFIG_SERIAL_8250_BCM2835AUX=y
+CONFIG_SERIAL_8250_BCM7271=y
+# CONFIG_SERIAL_8250_EXAR is not set
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_PCI=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_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_IMX_EARLYCON=y
+CONFIG_SERIAL_MVEBU_CONSOLE=y
+CONFIG_SERIAL_MVEBU_UART=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_SERIAL_SH_SCI_EARLYCON=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=18
+# CONFIG_SMC91X is not set
+# CONFIG_SND_SOC_RCAR is not set
+# CONFIG_SND_SOC_RZ is not set
+# CONFIG_SND_SOC_SH4_FSI is not set
+# CONFIG_SND_SUN4I_I2S is not set
+# CONFIG_SND_SUN50I_CODEC_ANALOG is not set
+# CONFIG_SND_SUN50I_DMIC is not set
+# CONFIG_SND_SUN8I_CODEC is not set
+# CONFIG_SND_SUN8I_CODEC_ANALOG is not set
+# CONFIG_SNI_NETSEC is not set
+CONFIG_SOCIONEXT_SYNQUACER_PREITS=y
+CONFIG_SOC_IMX8M=y
+CONFIG_SOC_IMX9=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPI_ARMADA_3700=y
+# CONFIG_SPI_BCM2835 is not set
+CONFIG_SPI_FSL_LPSPI=y
+# CONFIG_SPI_FSL_QUADSPI is not set
+# CONFIG_SPI_HISI_KUNPENG is not set
+# CONFIG_SPI_HISI_SFC is not set
+# CONFIG_SPI_HISI_SFC_V3XX is not set
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_ROCKCHIP_SFC is not set
+# CONFIG_SPI_RSPI is not set
+# CONFIG_SPI_RZV2M_CSI is not set
+# CONFIG_SPI_SH_HSPI is not set
+# CONFIG_SPI_SH_MSIOF is not set
+# CONFIG_SPI_SUN4I is not set
+# CONFIG_SPI_SUN6I is not set
+# CONFIG_SPI_SYNQUACER is not set
+CONFIG_SPI_THUNDERX=y
+# CONFIG_SPI_XLP is not set
+# CONFIG_SSIF_IPMI_BMC is not set
+CONFIG_STUB_CLK_HI3660=y
+CONFIG_STUB_CLK_HI6220=y
+# CONFIG_SUN20I_GPADC is not set
+# CONFIG_SUN20I_PPU is not set
+CONFIG_SUN50I_A100_CCU=y
+CONFIG_SUN50I_A100_R_CCU=y
+CONFIG_SUN50I_A64_CCU=y
+CONFIG_SUN50I_H616_CCU=y
+CONFIG_SUN50I_H6_CCU=y
+CONFIG_SUN50I_H6_R_CCU=y
+CONFIG_SUN50I_IOMMU=y
+CONFIG_SUN6I_MSGBOX=y
+CONFIG_SUN6I_RTC_CCU=y
+# CONFIG_SUN8I_A83T_CCU is not set
+CONFIG_SUN8I_DE2_CCU=y
+# CONFIG_SUN8I_H3_CCU is not set
+CONFIG_SUN8I_R_CCU=y
+CONFIG_SUN8I_THERMAL=y
+CONFIG_SUNXI_CCU=y
+CONFIG_SUNXI_RSB=y
+CONFIG_SUNXI_WATCHDOG=y
+CONFIG_SYNC_FILE=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+# CONFIG_TCG_TIS_SYNQUACER is not set
+CONFIG_THREAD_INFO_IN_TASK=y
+# CONFIG_THUNDERX2_PMU is not set
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
+# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set
+# CONFIG_TURRIS_MOX_RWTM is not set
+CONFIG_TYPEC=y
+# CONFIG_TYPEC_ANX7411 is not set
+# CONFIG_TYPEC_DP_ALTMODE is not set
+# CONFIG_TYPEC_FUSB302 is not set
+# CONFIG_TYPEC_HD3SS3220 is not set
+# CONFIG_TYPEC_MUX_FSA4480 is not set
+# CONFIG_TYPEC_MUX_GPIO_SBU is not set
+# CONFIG_TYPEC_MUX_NB7VPQ904M is not set
+# CONFIG_TYPEC_MUX_PI3USB30532 is not set
+# CONFIG_TYPEC_RT1711H is not set
+# CONFIG_TYPEC_RT1719 is not set
+# CONFIG_TYPEC_STUSB160X is not set
+CONFIG_TYPEC_TCPCI=y
+# CONFIG_TYPEC_TCPCI_MAXIM is not set
+CONFIG_TYPEC_TCPM=y
+# CONFIG_TYPEC_TPS6598X is not set
+# CONFIG_TYPEC_WUSB3801 is not set
+# CONFIG_UACCE is not set
+CONFIG_UNMAP_KERNEL_AT_EL0=y
+# CONFIG_USB_BRCMSTB is not set
+# CONFIG_USB_CDNS2_UDC is not set
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_GENERIC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_CHIPIDEA_IMX=y
+CONFIG_USB_CHIPIDEA_PCI=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_DUAL_ROLE=y
+# CONFIG_USB_DWC3_GADGET is not set
+CONFIG_USB_DWC3_HAPS=y
+# CONFIG_USB_DWC3_HOST is not set
+CONFIG_USB_DWC3_IMX8MP=y
+# CONFIG_USB_DWC3_OF_SIMPLE is not set
+CONFIG_USB_DWC3_PCI=y
+# CONFIG_USB_DWC3_ULPI is not set
+CONFIG_USB_DWC3_XILINX=y
+CONFIG_USB_EHCI_FSL=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_ORION=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+# CONFIG_USB_EMXX is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_OHCI_EXYNOS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PCI=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_OTG=y
+CONFIG_USB_OTG_FSM=y
+CONFIG_USB_RENESAS_USB3=y
+CONFIG_USB_RENESAS_USBF=y
+CONFIG_USB_RENESAS_USBHS=y
+CONFIG_USB_RENESAS_USBHS_HCD=y
+CONFIG_USB_RENESAS_USBHS_UDC=y
+CONFIG_USB_RZV2M_USB3DRD=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_HISTB=y
+CONFIG_USB_XHCI_MVEBU=y
+CONFIG_USB_XHCI_PLATFORM=y
+# CONFIG_USB_XHCI_RCAR is not set
+CONFIG_USB_XHCI_RZV2M=y
+CONFIG_VEXPRESS_CONFIG=y
+# CONFIG_VFIO_AMBA is not set
+CONFIG_VIDEOMODE_HELPERS=y
+# CONFIG_VIDEO_IMX7_CSI is not set
+# CONFIG_VIDEO_IMX8MQ_MIPI_CSI2 is not set
+# CONFIG_VIDEO_IMX8_ISI is not set
+# CONFIG_VIDEO_RZG2L_CRU is not set
+# CONFIG_VIDEO_RZG2L_CSI2 is not set
+CONFIG_VIRTIO_DMA_SHARED_BUFFER=y
+# CONFIG_VIRTIO_IOMMU is not set
+CONFIG_VIRTUALIZATION=y
+CONFIG_VMAP_STACK=y
+CONFIG_WDAT_WDT=y
+# CONFIG_XILINX_AMS is not set
+# CONFIG_XILINX_INTC is not set
+CONFIG_XLNX_EVENT_MANAGER=y
+CONFIG_ZONE_DMA32=y
+CONFIG_ZYNQMP_FIRMWARE=y
+# CONFIG_ZYNQMP_FIRMWARE_DEBUG is not set
+CONFIG_ZYNQMP_PM_DOMAINS=y
+CONFIG_ZYNQMP_POWER=y
. /lib/functions/uci-defaults.sh
+KERNEL_MAJOR=$(uname -r | awk -F '.' '{print $1}')
+KERNEL_MINOR=$(uname -r | awk -F '.' '{print $2}')
+
board_config_update
board=$(board_name)
case "$board" in
traverse,ten64)
- ucidef_add_gpio_switch "lte_reset" "Cell Modem Reset" "376"
- ucidef_add_gpio_switch "lte_power" "Cell Modem Power" "377"
- ucidef_add_gpio_switch "lte_disable" "Cell Modem Airplane mode" "378"
- ucidef_add_gpio_switch "gnss_disable" "Cell Modem Disable GNSS receiver" "379"
- ucidef_add_gpio_switch "lower_sfp_txidsable" "Lower SFP+ TX Disable" "369"
- ucidef_add_gpio_switch "upper_sfp_txdisable" "Upper SFP+ TX Disable" "373"
+ if [ "${KERNEL_MAJOR}" -ge "6" ] && [ "${KERNEL_MINOR}" -ge "6" ]; then
+ I2C_GPIO_BASE=640
+ else
+ I2C_GPIO_BASE=368
+ fi
+ ucidef_add_gpio_switch "lte_reset" "Cell Modem Reset" "$(($I2C_GPIO_BASE + 8))"
+ ucidef_add_gpio_switch "lte_power" "Cell Modem Power" "$(($I2C_GPIO_BASE + 9))"
+ ucidef_add_gpio_switch "lte_disable" "Cell Modem Airplane mode" "$((I2C_GPIO_BASE + 10))"
+ ucidef_add_gpio_switch "gnss_disable" "Cell Modem Disable GNSS receiver" "$(($I2C_GPIO_BASE + 11))"
+ ucidef_add_gpio_switch "lower_sfp_txidsable" "Lower SFP+ TX Disable" "$(($I2C_GPIO_BASE + 1))"
+ ucidef_add_gpio_switch "upper_sfp_txdisable" "Upper SFP+ TX Disable" "$(($I2C_GPIO_BASE + 5))"
;;
esac
--- /dev/null
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# This script migrates GPIO switch pin numbers
+# from kernel versions prior to 6.6
+# See https://lists.openwrt.org/pipermail/openwrt-devel/2024-March/042448.html
+
+. /lib/functions.sh
+
+ten64_update_gpioswitch_num() {
+ local section="$1"
+ config_get gpio_pin "${section}" gpio_pin
+ config_get gpio_name "${section}" name
+ if [ -z "${gpio_pin}" ]; then
+ return
+ fi
+ local this_pin_name=$(uci get "system.${section}.name")
+ if [ "${gpio_pin}" -lt 640 ]; then
+ new_pin_value=$(( $gpio_pin + 272 ))
+ uci set "system.${section}.gpio_pin=${new_pin_value}"
+ fi
+}
+
+board=$(board_name)
+if [ "${board}" != "traverse,ten64" ]; then
+ exit 0
+fi
+
+KERNEL_MINOR=$(uname -r | awk -F '.' '{print $2}')
+if [ "${KERNEL_MINOR}" -lt "6" ]; then
+ exit 0
+fi
+
+config_load system
+config_foreach ten64_update_gpioswitch_num gpio_switch
+
+exit 0
\ No newline at end of file
--- /dev/null
+CONFIG_64BIT=y
+CONFIG_9P_FS=y
+# CONFIG_9P_FS_POSIX_ACL is not set
+# CONFIG_9P_FS_SECURITY is not set
+# CONFIG_A64FX_DIAG is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_APEI=y
+CONFIG_ACPI_APEI_EINJ=y
+# CONFIG_ACPI_APEI_ERST_DEBUG is not set
+CONFIG_ACPI_APEI_GHES=y
+CONFIG_ACPI_APEI_MEMORY_FAILURE=y
+CONFIG_ACPI_APEI_PCIEAER=y
+CONFIG_ACPI_BATTERY=y
+# CONFIG_ACPI_BGRT is not set
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_CCA_REQUIRED=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_CPPC_CPUFREQ=y
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_DEBUGGER is not set
+# CONFIG_ACPI_DOCK is not set
+# CONFIG_ACPI_EC_DEBUGFS is not set
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_GENERIC_GSI=y
+CONFIG_ACPI_GTDT=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_I2C_OPREGION=y
+CONFIG_ACPI_IORT=y
+CONFIG_ACPI_MCFG=y
+# CONFIG_ACPI_PCI_SLOT is not set
+# CONFIG_ACPI_PFRUT is not set
+CONFIG_ACPI_PPTT=y
+CONFIG_ACPI_PRMT=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_PROCESSOR_IDLE=y
+CONFIG_ACPI_REDUCED_HARDWARE_ONLY=y
+CONFIG_ACPI_SPCR_TABLE=y
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_TINY_POWER_BUTTON is not set
+# CONFIG_ALIBABA_UNCORE_DRW_PMU is not set
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=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_ACPI_PARKING_PROTOCOL is not set
+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_TAGGED_ADDR_ABI=y
+CONFIG_ARM64_VA_BITS=39
+CONFIG_ARM64_VA_BITS_39=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GIC_V2M=y
+CONFIG_ARM_GIC_V3=y
+CONFIG_ARM_GIC_V3_ITS=y
+CONFIG_ARM_GIC_V3_ITS_PCI=y
+CONFIG_ARM_PSCI_FW=y
+# CONFIG_ARM_SMMU_V3_PMU is not set
+CONFIG_ATA=y
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
+CONFIG_BALLOON_COMPACTION=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NVME=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_MQ_VIRTIO=y
+CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+# CONFIG_COMPAT_32BIT_TIME is not set
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ACPI=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_REMAP=y
+CONFIG_DMI=y
+CONFIG_DMIID=y
+CONFIG_DMI_SYSFS=y
+CONFIG_DTC=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EFI=y
+CONFIG_EFIVAR_FS=y
+CONFIG_EFI_ARMSTUB_DTB_LOADER=y
+# CONFIG_EFI_BOOTLOADER_CONTROL is not set
+# CONFIG_EFI_CAPSULE_LOADER is not set
+# CONFIG_EFI_COCO_SECRET is not set
+# CONFIG_EFI_CUSTOM_SSDT_OVERLAYS is not set
+# CONFIG_EFI_DISABLE_PCI_DMA is not set
+# CONFIG_EFI_DISABLE_RUNTIME is not set
+CONFIG_EFI_EARLYCON=y
+CONFIG_EFI_ESRT=y
+CONFIG_EFI_GENERIC_STUB=y
+# CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER is not set
+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_EXT4_FS=y
+CONFIG_F2FS_FS=y
+CONFIG_FAILOVER=y
+CONFIG_FB_EFI=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=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_FS_IOMAP=y
+CONFIG_FS_MBCACHE=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_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_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_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_ACPI=y
+CONFIG_GPIO_CDEV=y
+# CONFIG_GPIO_HISI is not set
+CONFIG_GPIO_PL061=y
+# CONFIG_GPIO_VF610 is not set
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HID=y
+CONFIG_HID_GENERIC=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HOTPLUG_PCI_ACPI=y
+CONFIG_HVC_DRIVER=y
+CONFIG_HZ_PERIODIC=y
+# CONFIG_I2C_AMD_MP2 is not set
+CONFIG_I2C_HID_ACPI=y
+# CONFIG_I2C_HISI is not set
+# CONFIG_I2C_SLAVE_TESTUNIT is not set
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_ISCSI_IBFT is not set
+CONFIG_JBD2=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MEMORY_BALLOON=y
+CONFIG_MIGRATION=y
+# CONFIG_MLXBF_GIGE is not set
+CONFIG_MMC_SDHCI_ACPI=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_MVMDIO=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NET_9P=y
+# CONFIG_NET_9P_DEBUG is not set
+# CONFIG_NET_9P_FD is not set
+CONFIG_NET_9P_VIRTIO=y
+CONFIG_NET_FAILOVER=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NLS=y
+CONFIG_NR_CPUS=256
+CONFIG_NVMEM=y
+CONFIG_NVME_CORE=y
+# CONFIG_NVME_MULTIPATH is not set
+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_PADATA=y
+CONFIG_PAGE_REPORTING=y
+CONFIG_PARTITION_PERCPU=y
+CONFIG_PCI=y
+# CONFIG_PCIE_HISI_ERR is not set
+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_LABEL=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYS_ADDR_T_64BIT=y
+# CONFIG_PMIC_OPREGION is not set
+CONFIG_PNP=y
+CONFIG_PNPACPI=y
+CONFIG_PNP_DEBUG_MESSAGES=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RATIONAL=y
+# CONFIG_RESET_ATTACK_MITIGATION is not set
+CONFIG_RFS_ACCEL=y
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_EFI=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_SATA_HOST=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SCSI_VIRTIO=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_PNP=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_EARLYCON=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SRCU=y
+# CONFIG_SURFACE_PLATFORMS is not set
+CONFIG_SWIOTLB=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYSFB=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_ACPI=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+# CONFIG_UACCE is not set
+CONFIG_UCS2_STRING=y
+CONFIG_UNMAP_KERNEL_AT_EL0=y
+CONFIG_USB=y
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_PCI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PCI=y
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_BLK=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+CONFIG_VIRTIO_NET=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_PCI_LEGACY=y
+CONFIG_VIRTIO_PCI_LIB=y
+CONFIG_VMAP_STACK=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XPS=y
+CONFIG_ZONE_DMA32=y
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-vf.ko \
$(LINUX_DIR)/drivers/net/ethernet/freescale/enetc/fsl-enetc-mdio.ko \
$(LINUX_DIR)/drivers/net/ethernet/freescale/enetc/fsl-enetc-ierb.ko
--- /dev/null
+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
+@@ -128,7 +128,6 @@ config ARM
+ select HOTPLUG_CORE_SYNC_DEAD if HOTPLUG_CPU
+ 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
FEATURES:=ramdisk squashfs usbgadget
KERNEL_PATCHVER:=6.1
+KERNEL_TESTING_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
CONFIG_GPIO_ATH79=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_GENERIC=y
-# CONFIG_GPIO_LATCH is not set
+# CONFIG_GPIO_LATCH_MIKROTIK is not set
# CONFIG_GPIO_RB91X_KEY is not set
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
--- /dev/null
+CONFIG_AG71XX=y
+# CONFIG_AG71XX_DEBUG is not set
+CONFIG_AG71XX_DEBUG_FS=y
+CONFIG_AR8216_PHY=y
+CONFIG_AR8216_PHY_LEDS=y
+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_AT803X_PHY=y
+CONFIG_ATH79=y
+CONFIG_ATH79_WDT=y
+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="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_COMMON_CLK=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_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_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_DMA_NONCOHERENT=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_ETHERNET_PACKET_MANGLE=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=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_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_IDLE_POLL_SETUP=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_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_74X164=y
+CONFIG_GPIO_ATH79=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
+# CONFIG_GPIO_LATCH_MIKROTIK is not set
+# CONFIG_GPIO_RB91X_KEY is not set
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=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_LEDS_GPIO=y
+# CONFIG_LEDS_RESET is not set
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MDIO_GPIO=y
+# CONFIG_MFD_RB4XX_CPLD is not set
+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_BUILTIN_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_I2 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+CONFIG_MTD_PARSER_CYBERTAN=y
+# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_ELF_FW=y
+CONFIG_MTD_SPLIT_LZMA_FW=y
+CONFIG_MTD_SPLIT_SEAMA_FW=y
+CONFIG_MTD_SPLIT_TPLINK_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_MTD_SPLIT_WRGG_FW=y
+CONFIG_MTD_VIRT_CONCAT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_XGRESS=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=y
+CONFIG_PCI_AR71XX=y
+CONFIG_PCI_AR724X=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_PHYLIB_LEDS=y
+# CONFIG_PHY_AR7100_USB is not set
+# CONFIG_PHY_AR7200_USB is not set
+# CONFIG_PHY_ATH79_USB is not set
+CONFIG_PINCTRL=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QCOM_NET_PHYLIB=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_RESET_ATH79=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_AR933X=y
+CONFIG_SERIAL_AR933X_CONSOLE=y
+CONFIG_SERIAL_AR933X_NR_UARTS=2
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_AR934X=y
+CONFIG_SPI_ATH79=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+# CONFIG_SPI_RB4XX is not set
+# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set
+CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE=y
+CONFIG_SQUASHFS_DECOMP_SINGLE=y
+CONFIG_SWCONFIG=y
+CONFIG_SWCONFIG_LEDS=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=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_ZBOOT=y
+CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TINY_SRCU=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_ZBOOT_LOAD_ADDRESS=0x0
};
gpio_latch: gpio_latch {
- compatible = "gpio-latch";
+ compatible = "gpio-latch-mikrotik";
gpio-controller;
#gpio-cells = <2>;
gpios = <&gpio 0 GPIO_ACTIVE_HIGH>,
interrupts = <4>;
phy-mode = "mii";
+ syscon-no-reset;
mdio0: mdio {
status = "disabled";
interrupts = <5>;
phy-mode = "mii";
+ syscon-no-reset;
mdio1: mdio {
status = "disabled";
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "qca955x_senao_loader.dtsi"
+
+&partitions {
+ partition@ff0000 {
+ label = "art";
+ reg = <0xff0000 0x010000>;
+ 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>;
+ };
+
+ calibration_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
+ calibration_art_5000: calibration@5000 {
+ reg = <0x5000 0x844>;
+ };
+ };
+ };
+};
+
+&mdio0 {
+ status = "okay";
+
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ eee-broken-100tx;
+ eee-broken-1000t;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ eee-broken-100tx;
+ eee-broken-1000t;
+ at803x-override-sgmii-link-check;
+ };
+};
+
+ð0 {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_art_0 0>;
+ nvmem-cell-names = "mac-address";
+
+ phy-handle = <&phy1>;
+ phy-mode = "rgmii-id";
+
+ pll-data = <0x82000000 0x80000101 0x80001313>;
+};
+
+ð1 {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_art_0 1>;
+ nvmem-cell-names = "mac-address";
+
+ phy-handle = <&phy2>;
+
+ pll-data = <0x03000000 0x00000101 0x00001313>;
+
+ qca955x-sgmii-fixup;
+};
+
+&wmac {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_art_0 2>, <&calibration_art_1000>;
+ nvmem-cell-names = "mac-address", "calibration";
+};
+
+&ath10k_1 {
+ nvmem-cells = <&macaddr_art_0 3>, <&calibration_art_5000>;
+ nvmem-cell-names = "mac-address", "calibration";
+};
+
+&pcie1 {
+ status = "okay";
+};
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "qca9558_engenius_dual_ap.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "engenius,ens1750", "qca,qca9558";
+ model = "EnGenius ENS1750";
+
+ aliases {
+ label-mac-device = ð0;
+ led-boot = &led_wifi5g;
+ led-failsafe = &led_wifi5g;
+ led-upgrade = &led_wifi5g;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
+ debounce-interval = <60>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ wifi2g {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "phy1tpt";
+ };
+
+ led_wifi5g: wifi5g {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "phy0tpt";
+ };
+ };
+};
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include "qca955x_senao_loader.dtsi"
+#include "qca9558_engenius_dual_ap.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
/ {
compatible = "engenius,ews660ap", "qca,qca9558";
compatible = "gpio-leds";
wifi2g {
- label = "green:wifi2g";
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_2GHZ;
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
linux,default-trigger = "phy1tpt";
};
led_wifi5g: wifi5g {
- label = "green:wifi5g";
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_5GHZ;
gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
linux,default-trigger = "phy0tpt";
};
};
};
-
-&partitions {
- partition@ff0000 {
- label = "art";
- reg = <0xff0000 0x010000>;
- 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>;
- };
-
- calibration_art_1000: calibration@1000 {
- reg = <0x1000 0x440>;
- };
-
- calibration_art_5000: calibration@5000 {
- reg = <0x5000 0x844>;
- };
- };
- };
-};
-
-&mdio0 {
- status = "okay";
-
- phy1: ethernet-phy@1 {
- reg = <1>;
- eee-broken-100tx;
- eee-broken-1000t;
- };
-
- phy2: ethernet-phy@2 {
- reg = <2>;
- eee-broken-100tx;
- eee-broken-1000t;
- at803x-override-sgmii-link-check;
- };
-};
-
-ð0 {
- status = "okay";
-
- nvmem-cells = <&macaddr_art_0 0>;
- nvmem-cell-names = "mac-address";
-
- phy-handle = <&phy1>;
- phy-mode = "rgmii-id";
-
- pll-data = <0x82000000 0x80000101 0x80001313>;
-};
-
-ð1 {
- status = "okay";
-
- nvmem-cells = <&macaddr_art_0 1>;
- nvmem-cell-names = "mac-address";
-
- phy-handle = <&phy2>;
-
- pll-data = <0x03000000 0x00000101 0x00001313>;
-
- qca955x-sgmii-fixup;
-};
-
-&wmac {
- status = "okay";
-
- nvmem-cells = <&macaddr_art_0 2>, <&calibration_art_1000>;
- nvmem-cell-names = "mac-address", "calibration";
-};
-
-&ath10k_1 {
- status = "okay";
-
- nvmem-cells = <&macaddr_art_0 3>, <&calibration_art_5000>;
- nvmem-cell-names = "mac-address", "calibration";
-};
-
-&pcie1 {
- status = "okay";
-};
};
partition@40000 {
+ compatible = "u-boot,env";
label = "u-boot-env";
reg = <0x040000 0x010000>;
};
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * GPIO latch driver
+ *
+ * Copyright (C) 2014 Gabor Juhos <juhosg@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
+#define GPIO_LATCH_DRIVER_NAME "gpio-latch-mikrotik"
+#define GPIO_LATCH_LINES 9
+
+struct gpio_latch_chip {
+ struct gpio_chip gc;
+ struct mutex mutex;
+ struct mutex latch_mutex;
+ bool latch_enabled;
+ int le_gpio;
+ bool le_active_low;
+ struct gpio_desc *gpios[GPIO_LATCH_LINES];
+};
+
+static inline struct gpio_latch_chip *to_gpio_latch_chip(struct gpio_chip *gc)
+{
+ return container_of(gc, struct gpio_latch_chip, gc);
+}
+
+static void gpio_latch_lock(struct gpio_latch_chip *glc, bool enable)
+{
+ mutex_lock(&glc->mutex);
+
+ if (enable)
+ glc->latch_enabled = true;
+
+ if (glc->latch_enabled)
+ mutex_lock(&glc->latch_mutex);
+}
+
+static void gpio_latch_unlock(struct gpio_latch_chip *glc, bool disable)
+{
+ if (glc->latch_enabled)
+ mutex_unlock(&glc->latch_mutex);
+
+ if (disable)
+ glc->latch_enabled = true;
+
+ mutex_unlock(&glc->mutex);
+}
+
+static int
+gpio_latch_get(struct gpio_chip *gc, unsigned offset)
+{
+ struct gpio_latch_chip *glc = to_gpio_latch_chip(gc);
+ int ret;
+
+ gpio_latch_lock(glc, false);
+ ret = gpiod_get_raw_value_cansleep(glc->gpios[offset]);
+ gpio_latch_unlock(glc, false);
+
+ return ret;
+}
+
+static void
+gpio_latch_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+ struct gpio_latch_chip *glc = to_gpio_latch_chip(gc);
+ bool enable_latch = false;
+ bool disable_latch = false;
+
+ if (offset == glc->le_gpio) {
+ enable_latch = value ^ glc->le_active_low;
+ disable_latch = !enable_latch;
+ }
+
+ gpio_latch_lock(glc, enable_latch);
+ gpiod_set_raw_value_cansleep(glc->gpios[offset], value);
+ gpio_latch_unlock(glc, disable_latch);
+}
+
+static int
+gpio_latch_direction_output(struct gpio_chip *gc, unsigned offset, int value)
+{
+ struct gpio_latch_chip *glc = to_gpio_latch_chip(gc);
+ bool enable_latch = false;
+ bool disable_latch = false;
+ int ret;
+
+ if (offset == glc->le_gpio) {
+ enable_latch = value ^ glc->le_active_low;
+ disable_latch = !enable_latch;
+ }
+
+ gpio_latch_lock(glc, enable_latch);
+ ret = gpiod_direction_output_raw(glc->gpios[offset], value);
+ gpio_latch_unlock(glc, disable_latch);
+
+ return ret;
+}
+
+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);
+ if (!glc)
+ return -ENOMEM;
+
+ mutex_init(&glc->mutex);
+ 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);
+ 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]);
+ }
+ }
+
+ glc->le_gpio = 8;
+ glc->le_active_low = gpiod_is_active_low(glc->gpios[glc->le_gpio]);
+
+ if (!glc->gpios[glc->le_gpio]) {
+ dev_err(dev, "missing required latch-enable gpio %d\n",
+ glc->le_gpio);
+ return -EINVAL;
+ }
+
+ gc = &glc->gc;
+ gc->label = GPIO_LATCH_DRIVER_NAME;
+ 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;
+}
+
+static const struct of_device_id gpio_latch_match[] = {
+ { .compatible = GPIO_LATCH_DRIVER_NAME },
+ {},
+};
+
+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,
+ .of_match_table = gpio_latch_match,
+ },
+};
+
+module_platform_driver(gpio_latch_driver);
+
+MODULE_DESCRIPTION("GPIO latch driver");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_AUTHOR("Denis Kalashnikov <denis281089@gmail.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" GPIO_LATCH_DRIVER_NAME);
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * GPIO latch driver
- *
- * Copyright (C) 2014 Gabor Juhos <juhosg@openwrt.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/gpio/consumer.h>
-#include <linux/gpio/driver.h>
-#include <linux/platform_device.h>
-#include <linux/of_platform.h>
-#include <linux/of_gpio.h>
-
-#define GPIO_LATCH_DRIVER_NAME "gpio-latch"
-#define GPIO_LATCH_LINES 9
-
-struct gpio_latch_chip {
- struct gpio_chip gc;
- struct mutex mutex;
- struct mutex latch_mutex;
- bool latch_enabled;
- int le_gpio;
- bool le_active_low;
- struct gpio_desc *gpios[GPIO_LATCH_LINES];
-};
-
-static inline struct gpio_latch_chip *to_gpio_latch_chip(struct gpio_chip *gc)
-{
- return container_of(gc, struct gpio_latch_chip, gc);
-}
-
-static void gpio_latch_lock(struct gpio_latch_chip *glc, bool enable)
-{
- mutex_lock(&glc->mutex);
-
- if (enable)
- glc->latch_enabled = true;
-
- if (glc->latch_enabled)
- mutex_lock(&glc->latch_mutex);
-}
-
-static void gpio_latch_unlock(struct gpio_latch_chip *glc, bool disable)
-{
- if (glc->latch_enabled)
- mutex_unlock(&glc->latch_mutex);
-
- if (disable)
- glc->latch_enabled = true;
-
- mutex_unlock(&glc->mutex);
-}
-
-static int
-gpio_latch_get(struct gpio_chip *gc, unsigned offset)
-{
- struct gpio_latch_chip *glc = to_gpio_latch_chip(gc);
- int ret;
-
- gpio_latch_lock(glc, false);
- ret = gpiod_get_raw_value_cansleep(glc->gpios[offset]);
- gpio_latch_unlock(glc, false);
-
- return ret;
-}
-
-static void
-gpio_latch_set(struct gpio_chip *gc, unsigned offset, int value)
-{
- struct gpio_latch_chip *glc = to_gpio_latch_chip(gc);
- bool enable_latch = false;
- bool disable_latch = false;
-
- if (offset == glc->le_gpio) {
- enable_latch = value ^ glc->le_active_low;
- disable_latch = !enable_latch;
- }
-
- gpio_latch_lock(glc, enable_latch);
- gpiod_set_raw_value_cansleep(glc->gpios[offset], value);
- gpio_latch_unlock(glc, disable_latch);
-}
-
-static int
-gpio_latch_direction_output(struct gpio_chip *gc, unsigned offset, int value)
-{
- struct gpio_latch_chip *glc = to_gpio_latch_chip(gc);
- bool enable_latch = false;
- bool disable_latch = false;
- int ret;
-
- if (offset == glc->le_gpio) {
- enable_latch = value ^ glc->le_active_low;
- disable_latch = !enable_latch;
- }
-
- gpio_latch_lock(glc, enable_latch);
- ret = gpiod_direction_output_raw(glc->gpios[offset], value);
- gpio_latch_unlock(glc, disable_latch);
-
- return ret;
-}
-
-static int gpio_latch_probe(struct platform_device *pdev)
-{
- struct gpio_latch_chip *glc;
- struct gpio_chip *gc;
- struct device *dev = &pdev->dev;
- struct device_node *of_node = dev->of_node;
- int i, n;
-
- glc = devm_kzalloc(dev, sizeof(*glc), GFP_KERNEL);
- if (!glc)
- return -ENOMEM;
-
- mutex_init(&glc->mutex);
- 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);
- 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]);
- }
- }
-
- glc->le_gpio = 8;
- glc->le_active_low = gpiod_is_active_low(glc->gpios[glc->le_gpio]);
-
- if (!glc->gpios[glc->le_gpio]) {
- dev_err(dev, "missing required latch-enable gpio %d\n",
- glc->le_gpio);
- return -EINVAL;
- }
-
- gc = &glc->gc;
- gc->label = GPIO_LATCH_DRIVER_NAME;
- 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->of_node = of_node;
-
- 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;
-}
-
-static const struct of_device_id gpio_latch_match[] = {
- { .compatible = GPIO_LATCH_DRIVER_NAME },
- {},
-};
-
-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,
- .of_match_table = gpio_latch_match,
- },
-};
-
-module_platform_driver(gpio_latch_driver);
-
-MODULE_DESCRIPTION("GPIO latch driver");
-MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
-MODULE_AUTHOR("Denis Kalashnikov <denis281089@gmail.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:" GPIO_LATCH_DRIVER_NAME);
struct gpio_rb91x_key *drvdata;
struct gpio_chip *gc;
struct device *dev = &pdev->dev;
- struct device_node *of_node = dev->of_node;
+ struct fwnode_handle *fwnode = dev->fwnode;
int r;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
gc->set = gpio_rb91x_key_set;
gc->direction_output = gpio_rb91x_key_direction_output;
gc->direction_input = gpio_rb91x_key_direction_input;
- gc->of_node = of_node;
+ gc->fwnode = fwnode;
platform_set_drvdata(pdev, drvdata);
int ring_mask = BIT(ring->order) - 1;
int ring_size = BIT(ring->order);
struct list_head rx_list;
- struct sk_buff *next;
struct sk_buff *skb;
int done = 0;
ag71xx_ring_rx_refill(ag);
- list_for_each_entry_safe(skb, next, &rx_list, list)
+ list_for_each_entry(skb, &rx_list, list)
skb->protocol = eth_type_trans(skb, dev);
netif_receive_skb_list(&rx_list);
elecom,wab-i1750-ps|\
elecom,wab-s1167-ps|\
elecom,wab-s600-ps|\
+ engenius,ens1750|\
engenius,enstationac-v1|\
engenius,ews511ap|\
engenius,ews660ap|\
engenius,eap300-v2|\
engenius,eap600|\
engenius,ecb600|\
+ engenius,ens1750|\
engenius,ens202ext-v1|\
engenius,enstationac-v1|\
engenius,ews660ap|\
endef
TARGET_DEVICES += engenius_ews511ap
-define Device/engenius_ews660ap
+define Device/engenius_ews_dual_ap
$(Device/senao_loader_okli)
SOC := qca9558
DEVICE_VENDOR := EnGenius
- DEVICE_MODEL := EWS660AP
DEVICE_PACKAGES := ath10k-firmware-qca988x-ct kmod-ath10k-ct
IMAGE_SIZE := 11584k
LOADER_FLASH_OFFS := 0x220000
+endef
+
+define Device/engenius_ews660ap
+ $(Device/engenius_ews_dual_ap)
+ DEVICE_MODEL := EWS660AP
SENAO_IMGNAME := ar71xx-generic-ews660ap
endef
TARGET_DEVICES += engenius_ews660ap
+define Device/engenius_ens1750
+ $(Device/engenius_ews_dual_ap)
+ DEVICE_MODEL := ENS1750
+ SENAO_IMGNAME := ar71xx-generic-ens1750
+endef
+TARGET_DEVICES += engenius_ens1750
+
define Device/enterasys_ws-ap3705i
SOC := ar9344
DEVICE_VENDOR := Enterasys
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_ZSTD=y
-CONFIG_GPIO_LATCH=y
+CONFIG_GPIO_LATCH_MIKROTIK=y
CONFIG_GPIO_RB4XX=y
CONFIG_GPIO_RB91X_KEY=y
CONFIG_GPIO_WATCHDOG=y
goto next_ht;
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
-@@ -259,7 +259,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *
+@@ -290,7 +290,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *
continue;
iph2 = (struct ipv6hdr *)(p->data + off);
If unsure, say N.
-+config GPIO_LATCH
++config GPIO_LATCH_MIKROTIK
+ tristate "MikroTik RouterBOARD GPIO latch support"
+ depends on ATH79
+ help
obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
-+obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o
++obj-$(CONFIG_GPIO_LATCH_MIKROTIK) += gpio-latch-mikrotik.o
obj-$(CONFIG_GPIO_LOGICVC) += gpio-logicvc.o
obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o
--- /dev/null
+From 661edfc3dab943a67c8821353b63cc23057f7ce9 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+Date: Tue, 9 Jan 2024 20:48:46 +0100
+Subject: [PATCH] reset: ath79: read back reset register
+
+Read back the reset register in order to flush the cache. This fixes
+spurious reboot hangs on TP-Link TL-WDR3600 and TL-WDR4300 with Zentel
+DRAM chips.
+
+This issue was fixed in the past, but switching to the reset-driver
+specific implementation removed the old fix.
+
+Link: https://github.com/freifunk-gluon/gluon/issues/2904
+Link: https://github.com/openwrt/openwrt/issues/13043
+Link: https://dev.archive.openwrt.org/ticket/17839
+Link: f8a7bfe1cb2c ("MIPS: ath79: fix system restart")
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+---
+ drivers/reset/reset-ath79.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/reset/reset-ath79.c
++++ b/drivers/reset/reset-ath79.c
+@@ -37,6 +37,8 @@ static int ath79_reset_update(struct res
+ else
+ val &= ~BIT(id);
+ writel(val, ath79_reset->base);
++ /* Flush cache */
++ readl(ath79_reset->base);
+ spin_unlock_irqrestore(&ath79_reset->lock, flags);
+
+ return 0;
--- /dev/null
+From f3eacff2310a60348a755c50a8da6fc251fc8587 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Tue, 6 Mar 2018 09:55:13 +0100
+Subject: [PATCH 07/33] irqchip/irq-ath79-intc: add irq cascade driver for
+ QCA9556 SoCs
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/irqchip/Makefile | 1 +
+ drivers/irqchip/irq-ath79-intc.c | 142 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 143 insertions(+)
+ create mode 100644 drivers/irqchip/irq-ath79-intc.c
+
+--- a/drivers/irqchip/Makefile
++++ b/drivers/irqchip/Makefile
+@@ -4,6 +4,7 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o
+ obj-$(CONFIG_AL_FIC) += irq-al-fic.o
+ obj-$(CONFIG_ALPINE_MSI) += irq-alpine-msi.o
+ obj-$(CONFIG_ATH79) += irq-ath79-cpu.o
++obj-$(CONFIG_ATH79) += irq-ath79-intc.o
+ obj-$(CONFIG_ATH79) += irq-ath79-misc.o
+ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
+ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o
+--- /dev/null
++++ b/drivers/irqchip/irq-ath79-intc.c
+@@ -0,0 +1,142 @@
++/*
++ * Atheros AR71xx/AR724x/AR913x specific interrupt handling
++ *
++ * Copyright (C) 2018 John Crispin <john@phrozen.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/interrupt.h>
++#include <linux/irqchip.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
++#include <linux/irqdomain.h>
++
++#include <asm/irq_cpu.h>
++#include <asm/mach-ath79/ath79.h>
++#include <asm/mach-ath79/ar71xx_regs.h>
++
++#define ATH79_MAX_INTC_CASCADE 3
++
++struct ath79_intc {
++ struct irq_chip chip;
++ u32 irq;
++ u32 pending_mask;
++ u32 int_status;
++ u32 irq_mask[ATH79_MAX_INTC_CASCADE];
++ u32 irq_wb_chan[ATH79_MAX_INTC_CASCADE];
++};
++
++static void ath79_intc_irq_handler(struct irq_desc *desc)
++{
++ struct irq_domain *domain = irq_desc_get_handler_data(desc);
++ struct ath79_intc *intc = domain->host_data;
++ u32 pending;
++
++ pending = ath79_reset_rr(intc->int_status);
++ pending &= intc->pending_mask;
++
++ if (pending) {
++ int i;
++
++ for (i = 0; i < domain->hwirq_max; i++)
++ if (pending & intc->irq_mask[i]) {
++ if (intc->irq_wb_chan[i] != 0xffffffff)
++ ath79_ddr_wb_flush(intc->irq_wb_chan[i]);
++ generic_handle_irq(irq_find_mapping(domain, i));
++ }
++ } else {
++ spurious_interrupt();
++ }
++}
++
++static void ath79_intc_irq_enable(struct irq_data *d)
++{
++ struct ath79_intc *intc = d->domain->host_data;
++ enable_irq(intc->irq);
++}
++
++static void ath79_intc_irq_disable(struct irq_data *d)
++{
++ struct ath79_intc *intc = d->domain->host_data;
++ disable_irq(intc->irq);
++}
++
++static int ath79_intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
++{
++ struct ath79_intc *intc = d->host_data;
++
++ irq_set_chip_and_handler(irq, &intc->chip, handle_level_irq);
++
++ return 0;
++}
++
++static const struct irq_domain_ops ath79_irq_domain_ops = {
++ .xlate = irq_domain_xlate_onecell,
++ .map = ath79_intc_map,
++};
++
++static int __init ath79_intc_of_init(
++ struct device_node *node, struct device_node *parent)
++{
++ struct irq_domain *domain;
++ struct ath79_intc *intc;
++ int cnt, cntwb, i, err;
++
++ cnt = of_property_count_u32_elems(node, "qca,pending-bits");
++ if (cnt > ATH79_MAX_INTC_CASCADE)
++ panic("Too many INTC pending bits\n");
++
++ intc = kzalloc(sizeof(*intc), GFP_KERNEL);
++ if (!intc)
++ panic("Failed to allocate INTC memory\n");
++ intc->chip = dummy_irq_chip;
++ intc->chip.name = "INTC";
++ intc->chip.irq_disable = ath79_intc_irq_disable;
++ intc->chip.irq_enable = ath79_intc_irq_enable;
++
++ if (of_property_read_u32(node, "qca,int-status-addr", &intc->int_status) < 0) {
++ panic("Missing address of interrupt status register\n");
++ }
++
++ of_property_read_u32_array(node, "qca,pending-bits", intc->irq_mask, cnt);
++ for (i = 0; i < cnt; i++) {
++ intc->pending_mask |= intc->irq_mask[i];
++ intc->irq_wb_chan[i] = 0xffffffff;
++ }
++
++ cntwb = of_count_phandle_with_args(
++ node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells");
++
++ for (i = 0; i < cntwb; i++) {
++ struct of_phandle_args args;
++ u32 irq = i;
++
++ of_property_read_u32_index(
++ node, "qca,ddr-wb-channel-interrupts", i, &irq);
++ if (irq >= ATH79_MAX_INTC_CASCADE)
++ continue;
++
++ err = of_parse_phandle_with_args(
++ node, "qca,ddr-wb-channels",
++ "#qca,ddr-wb-channel-cells",
++ i, &args);
++ if (err)
++ return err;
++
++ intc->irq_wb_chan[irq] = args.args[0];
++ }
++
++ intc->irq = irq_of_parse_and_map(node, 0);
++ if (!intc->irq)
++ panic("Failed to get INTC IRQ");
++
++ domain = irq_domain_add_linear(node, cnt, &ath79_irq_domain_ops, intc);
++ irq_set_chained_handler_and_data(intc->irq, ath79_intc_irq_handler, domain);
++
++ return 0;
++}
++IRQCHIP_DECLARE(ath79_intc, "qca,ar9340-intc",
++ ath79_intc_of_init);
--- /dev/null
+From e029f998594f151008ecbfa024e2957edd2a5189 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Tue, 6 Mar 2018 09:58:19 +0100
+Subject: [PATCH 08/33] irqchip/irq-ath79-cpu: drop !OF init helper
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/irqchip/irq-ath79-cpu.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+--- a/drivers/irqchip/irq-ath79-cpu.c
++++ b/drivers/irqchip/irq-ath79-cpu.c
+@@ -85,10 +85,3 @@ static int __init ar79_cpu_intc_of_init(
+ }
+ IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
+ ar79_cpu_intc_of_init);
+-
+-void __init ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3)
+-{
+- irq_wb_chan[2] = irq_wb_chan2;
+- irq_wb_chan[3] = irq_wb_chan3;
+- mips_cpu_irq_init();
+-}
--- /dev/null
+From 4a4f869ec58ed8910b9b2e68d0eee50957e9bb20 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Mon, 25 Jun 2018 15:52:10 +0200
+Subject: [PATCH 17/33] dt-bindings: PCI: qcom,ar7100: adds binding doc
+
+With the driver being converted from platform_data to pure OF, we need to
+also add some docs.
+
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: devicetree@vger.kernel.org
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ .../devicetree/bindings/pci/qcom,ar7100-pci.txt | 38 ++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pci/qcom,ar7100-pci.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pci/qcom,ar7100-pci.txt
+@@ -0,0 +1,38 @@
++* Qualcomm Atheros AR7100 PCI express root complex
++
++Required properties:
++- compatible: should contain "qcom,ar7100-pci" to identify the core.
++- reg: Should contain the register ranges as listed in the reg-names property.
++- reg-names: Definition: Must include the following entries
++ - "cfg_base" IO Memory
++- #address-cells: set to <3>
++- #size-cells: set to <2>
++- ranges: ranges for the PCI memory and I/O regions
++- interrupt-map-mask and interrupt-map: standard PCI
++ properties to define the mapping of the PCIe interface to interrupt
++ numbers.
++- #interrupt-cells: set to <1>
++- interrupt-controller: define to enable the builtin IRQ cascade.
++
++Optional properties:
++- interrupt-parent: phandle to the MIPS IRQ controller
++
++* Example for ar7100
++ pcie@180c0000 {
++ compatible = "qca,ar7100-pci";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ bus-range = <0x0 0x0>;
++ reg = <0x17010000 0x100>;
++ reg-names = "cfg_base";
++ ranges = <0x2000000 0 0x10000000 0x10000000 0 0x07000000
++ 0x1000000 0 0x00000000 0x00000000 0 0x00000001>;
++ interrupt-parent = <&cpuintc>;
++ interrupts = <2>;
++
++ interrupt-controller;
++ #interrupt-cells = <1>;
++
++ interrupt-map-mask = <0 0 0 1>;
++ interrupt-map = <0 0 0 0 &pcie0 0>;
++ };
--- /dev/null
+From 1855ab6b1d27f5b38a648baf57ff6a534afec26d Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Sat, 23 Jun 2018 15:07:23 +0200
+Subject: [PATCH 18/33] MIPS: pci-ar71xx: convert to OF
+
+With the ath79 target getting converted to pure OF, we can drop all the
+platform data code and add the missing OF bits to the driver. We also add
+a irq domain for the PCI/e controllers cascade, thus making it usable from
+dts files.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ arch/mips/pci/pci-ar71xx.c | 82 +++++++++++++++++++++++-----------------------
+ 1 file changed, 41 insertions(+), 41 deletions(-)
+
+--- a/arch/mips/pci/pci-ar71xx.c
++++ b/arch/mips/pci/pci-ar71xx.c
+@@ -15,8 +15,11 @@
+ #include <linux/pci.h>
+ #include <linux/pci_regs.h>
+ #include <linux/interrupt.h>
++#include <linux/irqchip/chained_irq.h>
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
++#include <linux/of_irq.h>
++#include <linux/of_pci.h>
+
+ #include <asm/mach-ath79/ar71xx_regs.h>
+ #include <asm/mach-ath79/ath79.h>
+@@ -46,12 +49,13 @@
+ #define AR71XX_PCI_IRQ_COUNT 5
+
+ struct ar71xx_pci_controller {
++ struct device_node *np;
+ void __iomem *cfg_base;
+ int irq;
+- int irq_base;
+ struct pci_controller pci_ctrl;
+ struct resource io_res;
+ struct resource mem_res;
++ struct irq_domain *domain;
+ };
+
+ /* Byte lane enable bits */
+@@ -225,29 +229,30 @@ static struct pci_ops ar71xx_pci_ops = {
+
+ static void ar71xx_pci_irq_handler(struct irq_desc *desc)
+ {
+- struct ar71xx_pci_controller *apc;
+ void __iomem *base = ath79_reset_base;
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct ar71xx_pci_controller *apc = irq_desc_get_handler_data(desc);
+ u32 pending;
+
+- apc = irq_desc_get_handler_data(desc);
+-
++ chained_irq_enter(chip, desc);
+ pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
+ __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+
+ if (pending & AR71XX_PCI_INT_DEV0)
+- generic_handle_irq(apc->irq_base + 0);
++ generic_handle_irq(irq_linear_revmap(apc->domain, 1));
+
+ else if (pending & AR71XX_PCI_INT_DEV1)
+- generic_handle_irq(apc->irq_base + 1);
++ generic_handle_irq(irq_linear_revmap(apc->domain, 2));
+
+ else if (pending & AR71XX_PCI_INT_DEV2)
+- generic_handle_irq(apc->irq_base + 2);
++ generic_handle_irq(irq_linear_revmap(apc->domain, 3));
+
+ else if (pending & AR71XX_PCI_INT_CORE)
+- generic_handle_irq(apc->irq_base + 4);
++ generic_handle_irq(irq_linear_revmap(apc->domain, 4));
+
+ else
+ spurious_interrupt();
++ chained_irq_exit(chip, desc);
+ }
+
+ static void ar71xx_pci_irq_unmask(struct irq_data *d)
+@@ -258,7 +263,7 @@ static void ar71xx_pci_irq_unmask(struct
+ u32 t;
+
+ apc = irq_data_get_irq_chip_data(d);
+- irq = d->irq - apc->irq_base;
++ irq = irq_linear_revmap(apc->domain, d->irq);
+
+ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+@@ -275,7 +280,7 @@ static void ar71xx_pci_irq_mask(struct i
+ u32 t;
+
+ apc = irq_data_get_irq_chip_data(d);
+- irq = d->irq - apc->irq_base;
++ irq = irq_linear_revmap(apc->domain, d->irq);
+
+ t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+@@ -291,24 +296,31 @@ static struct irq_chip ar71xx_pci_irq_ch
+ .irq_mask_ack = ar71xx_pci_irq_mask,
+ };
+
++static int ar71xx_pci_irq_map(struct irq_domain *d,
++ unsigned int irq, irq_hw_number_t hw)
++{
++ struct ar71xx_pci_controller *apc = d->host_data;
++
++ irq_set_chip_and_handler(irq, &ar71xx_pci_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, apc);
++
++ return 0;
++}
++
++static const struct irq_domain_ops ar71xx_pci_domain_ops = {
++ .xlate = irq_domain_xlate_onecell,
++ .map = ar71xx_pci_irq_map,
++};
++
+ static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc)
+ {
+ void __iomem *base = ath79_reset_base;
+- int i;
+
+ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+ __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
+
+- BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT);
+-
+- apc->irq_base = ATH79_PCI_IRQ_BASE;
+- for (i = apc->irq_base;
+- i < apc->irq_base + AR71XX_PCI_IRQ_COUNT; i++) {
+- irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip,
+- handle_level_irq);
+- irq_set_chip_data(i, apc);
+- }
+-
++ apc->domain = irq_domain_add_linear(apc->np, AR71XX_PCI_IRQ_COUNT,
++ &ar71xx_pci_domain_ops, apc);
+ irq_set_chained_handler_and_data(apc->irq, ar71xx_pci_irq_handler,
+ apc);
+ }
+@@ -325,10 +337,14 @@ static void ar71xx_pci_reset(void)
+ mdelay(100);
+ }
+
++static const struct of_device_id ar71xx_pci_ids[] = {
++ { .compatible = "qca,ar7100-pci" },
++ {},
++};
++
+ static int ar71xx_pci_probe(struct platform_device *pdev)
+ {
+ struct ar71xx_pci_controller *apc;
+- struct resource *res;
+ u32 t;
+
+ apc = devm_kzalloc(&pdev->dev, sizeof(struct ar71xx_pci_controller),
+@@ -345,26 +361,6 @@ static int ar71xx_pci_probe(struct platf
+ if (apc->irq < 0)
+ return -EINVAL;
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
+- if (!res)
+- return -EINVAL;
+-
+- apc->io_res.parent = res;
+- apc->io_res.name = "PCI IO space";
+- apc->io_res.start = res->start;
+- apc->io_res.end = res->end;
+- apc->io_res.flags = IORESOURCE_IO;
+-
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
+- if (!res)
+- return -EINVAL;
+-
+- apc->mem_res.parent = res;
+- apc->mem_res.name = "PCI memory space";
+- apc->mem_res.start = res->start;
+- apc->mem_res.end = res->end;
+- apc->mem_res.flags = IORESOURCE_MEM;
+-
+ ar71xx_pci_reset();
+
+ /* setup COMMAND register */
+@@ -377,9 +373,11 @@ static int ar71xx_pci_probe(struct platf
+
+ ar71xx_pci_irq_init(apc);
+
++ apc->np = pdev->dev.of_node;
+ apc->pci_ctrl.pci_ops = &ar71xx_pci_ops;
+ apc->pci_ctrl.mem_resource = &apc->mem_res;
+ apc->pci_ctrl.io_resource = &apc->io_res;
++ pci_load_of_ranges(&apc->pci_ctrl, pdev->dev.of_node);
+
+ register_pci_controller(&apc->pci_ctrl);
+
+@@ -390,6 +388,7 @@ static struct platform_driver ar71xx_pci
+ .probe = ar71xx_pci_probe,
+ .driver = {
+ .name = "ar71xx-pci",
++ .of_match_table = of_match_ptr(ar71xx_pci_ids),
+ },
+ };
+
--- /dev/null
+From ea27764bc3ef2a05decf3ae05edffc289cd0d93c Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Mon, 25 Jun 2018 15:52:02 +0200
+Subject: [PATCH 19/33] dt-bindings: PCI: qcom,ar7240: adds binding doc
+
+With the driver being converted from platform_data to pure OF, we need to
+also add some docs.
+
+Cc: Rob Herring <robh+dt@kernel.org>
+Cc: devicetree@vger.kernel.org
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ .../devicetree/bindings/pci/qcom,ar7240-pci.txt | 42 ++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pci/qcom,ar7240-pci.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pci/qcom,ar7240-pci.txt
+@@ -0,0 +1,42 @@
++* Qualcomm Atheros AR724X PCI express root complex
++
++Required properties:
++- compatible: should contain "qcom,ar7240-pci" to identify the core.
++- reg: Should contain the register ranges as listed in the reg-names property.
++- reg-names: Definition: Must include the following entries
++ - "crp_base" Configuration registers
++ - "ctrl_base" Control registers
++ - "cfg_base" IO Memory
++- #address-cells: set to <3>
++- #size-cells: set to <2>
++- ranges: ranges for the PCI memory and I/O regions
++- interrupt-map-mask and interrupt-map: standard PCI
++ properties to define the mapping of the PCIe interface to interrupt
++ numbers.
++- #interrupt-cells: set to <1>
++- interrupt-parent: phandle to the MIPS IRQ controller
++
++Optional properties:
++- interrupt-controller: define to enable the builtin IRQ cascade.
++
++* Example for qca9557
++ pcie@180c0000 {
++ compatible = "qcom,ar7240-pci";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ bus-range = <0x0 0x0>;
++ reg = <0x180c0000 0x1000>,
++ <0x180f0000 0x100>,
++ <0x14000000 0x1000>;
++ reg-names = "crp_base", "ctrl_base", "cfg_base";
++ ranges = <0x2000000 0 0x10000000 0x10000000 0 0x04000000
++ 0x1000000 0 0x00000000 0x00000000 0 0x00000001>;
++ interrupt-parent = <&intc2>;
++ interrupts = <1>;
++
++ interrupt-controller;
++ #interrupt-cells = <1>;
++
++ interrupt-map-mask = <0 0 0 1>;
++ interrupt-map = <0 0 0 0 &pcie0 0>;
++ };
--- /dev/null
+From a522ee0199d5d3ea114ca2e211f6ac398d3e8e0b Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Sat, 23 Jun 2018 15:07:37 +0200
+Subject: [PATCH 20/33] MIPS: pci-ar724x: convert to OF
+
+With the ath79 target getting converted to pure OF, we can drop all the
+platform data code and add the missing OF bits to the driver. We also add
+a irq domain for the PCI/e controllers cascade, thus making it usable from
+dts files.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ arch/mips/pci/pci-ar724x.c | 88 ++++++++++++++++++++++------------------------
+ 1 file changed, 42 insertions(+), 46 deletions(-)
+
+--- a/arch/mips/pci/pci-ar724x.c
++++ b/arch/mips/pci/pci-ar724x.c
+@@ -11,8 +11,11 @@
+ #include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/platform_device.h>
++#include <linux/irqchip/chained_irq.h>
+ #include <asm/mach-ath79/ath79.h>
+ #include <asm/mach-ath79/ar71xx_regs.h>
++#include <linux/of_irq.h>
++#include <linux/of_pci.h>
+
+ #define AR724X_PCI_REG_APP 0x00
+ #define AR724X_PCI_REG_RESET 0x18
+@@ -42,17 +45,20 @@ struct ar724x_pci_controller {
+ void __iomem *crp_base;
+
+ int irq;
+- int irq_base;
+
+ bool link_up;
+ bool bar0_is_cached;
+ u32 bar0_value;
+
++ struct device_node *np;
+ struct pci_controller pci_controller;
++ struct irq_domain *domain;
+ struct resource io_res;
+ struct resource mem_res;
+ };
+
++static struct irq_chip ar724x_pci_irq_chip;
++
+ static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
+ {
+ u32 reset;
+@@ -228,35 +234,31 @@ static struct pci_ops ar724x_pci_ops = {
+
+ static void ar724x_pci_irq_handler(struct irq_desc *desc)
+ {
+- struct ar724x_pci_controller *apc;
+- void __iomem *base;
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct ar724x_pci_controller *apc = irq_desc_get_handler_data(desc);
+ u32 pending;
+
+- apc = irq_desc_get_handler_data(desc);
+- base = apc->ctrl_base;
+-
+- pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
+- __raw_readl(base + AR724X_PCI_REG_INT_MASK);
++ chained_irq_enter(chip, desc);
++ pending = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_INT_STATUS) &
++ __raw_readl(apc->ctrl_base + AR724X_PCI_REG_INT_MASK);
+
+ if (pending & AR724X_PCI_INT_DEV0)
+- generic_handle_irq(apc->irq_base + 0);
+-
++ generic_handle_irq(irq_linear_revmap(apc->domain, 1));
+ else
+ spurious_interrupt();
++ chained_irq_exit(chip, desc);
+ }
+
+ static void ar724x_pci_irq_unmask(struct irq_data *d)
+ {
+ struct ar724x_pci_controller *apc;
+ void __iomem *base;
+- int offset;
+ u32 t;
+
+ apc = irq_data_get_irq_chip_data(d);
+ base = apc->ctrl_base;
+- offset = apc->irq_base - d->irq;
+
+- switch (offset) {
++ switch (irq_linear_revmap(apc->domain, d->irq)) {
+ case 0:
+ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
+ __raw_writel(t | AR724X_PCI_INT_DEV0,
+@@ -270,14 +272,12 @@ static void ar724x_pci_irq_mask(struct i
+ {
+ struct ar724x_pci_controller *apc;
+ void __iomem *base;
+- int offset;
+ u32 t;
+
+ apc = irq_data_get_irq_chip_data(d);
+ base = apc->ctrl_base;
+- offset = apc->irq_base - d->irq;
+
+- switch (offset) {
++ switch (irq_linear_revmap(apc->domain, d->irq)) {
+ case 0:
+ t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
+ __raw_writel(t & ~AR724X_PCI_INT_DEV0,
+@@ -302,26 +302,34 @@ static struct irq_chip ar724x_pci_irq_ch
+ .irq_mask_ack = ar724x_pci_irq_mask,
+ };
+
++static int ar724x_pci_irq_map(struct irq_domain *d,
++ unsigned int irq, irq_hw_number_t hw)
++{
++ struct ar724x_pci_controller *apc = d->host_data;
++
++ irq_set_chip_and_handler(irq, &ar724x_pci_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, apc);
++
++ return 0;
++}
++
++static const struct irq_domain_ops ar724x_pci_domain_ops = {
++ .xlate = irq_domain_xlate_onecell,
++ .map = ar724x_pci_irq_map,
++};
++
+ static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc,
+ int id)
+ {
+ void __iomem *base;
+- int i;
+
+ base = apc->ctrl_base;
+
+ __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
+ __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
+
+- apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT);
+-
+- for (i = apc->irq_base;
+- i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) {
+- irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
+- handle_level_irq);
+- irq_set_chip_data(i, apc);
+- }
+-
++ apc->domain = irq_domain_add_linear(apc->np, 2,
++ &ar724x_pci_domain_ops, apc);
+ irq_set_chained_handler_and_data(apc->irq, ar724x_pci_irq_handler,
+ apc);
+ }
+@@ -360,7 +368,6 @@ static void ar724x_pci_hw_init(struct ar
+ static int ar724x_pci_probe(struct platform_device *pdev)
+ {
+ struct ar724x_pci_controller *apc;
+- struct resource *res;
+ int id;
+
+ id = pdev->id;
+@@ -388,29 +395,11 @@ static int ar724x_pci_probe(struct platf
+ if (apc->irq < 0)
+ return -EINVAL;
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
+- if (!res)
+- return -EINVAL;
+-
+- apc->io_res.parent = res;
+- apc->io_res.name = "PCI IO space";
+- apc->io_res.start = res->start;
+- apc->io_res.end = res->end;
+- apc->io_res.flags = IORESOURCE_IO;
+-
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
+- if (!res)
+- return -EINVAL;
+-
+- apc->mem_res.parent = res;
+- apc->mem_res.name = "PCI memory space";
+- apc->mem_res.start = res->start;
+- apc->mem_res.end = res->end;
+- apc->mem_res.flags = IORESOURCE_MEM;
+-
++ apc->np = pdev->dev.of_node;
+ apc->pci_controller.pci_ops = &ar724x_pci_ops;
+ apc->pci_controller.io_resource = &apc->io_res;
+ apc->pci_controller.mem_resource = &apc->mem_res;
++ pci_load_of_ranges(&apc->pci_controller, pdev->dev.of_node);
+
+ /*
+ * Do the full PCIE Root Complex Initialization Sequence if the PCIe
+@@ -432,10 +421,16 @@ static int ar724x_pci_probe(struct platf
+ return 0;
+ }
+
++static const struct of_device_id ar724x_pci_ids[] = {
++ { .compatible = "qcom,ar7240-pci" },
++ {},
++};
++
+ static struct platform_driver ar724x_pci_driver = {
+ .probe = ar724x_pci_probe,
+ .driver = {
+ .name = "ar724x-pci",
++ .of_match_table = of_match_ptr(ar724x_pci_ids),
+ },
+ };
+
--- /dev/null
+From: John Crispin <john@phrozen.org>
+Subject: ath79: fix remove irq code from pci driver patch
+
+This patch got mangled in the void while rebasing it.
+
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ arch/mips/pci/pci-ar71xx.c | 107 ------------------
+ 1 file changed, 141 deletions(-)
+
+--- a/arch/mips/pci/pci-ar71xx.c
++++ b/arch/mips/pci/pci-ar71xx.c
+@@ -51,11 +51,9 @@
+ struct ar71xx_pci_controller {
+ struct device_node *np;
+ void __iomem *cfg_base;
+- int irq;
+ struct pci_controller pci_ctrl;
+ struct resource io_res;
+ struct resource mem_res;
+- struct irq_domain *domain;
+ };
+
+ /* Byte lane enable bits */
+@@ -227,104 +225,6 @@ static struct pci_ops ar71xx_pci_ops = {
+ .write = ar71xx_pci_write_config,
+ };
+
+-static void ar71xx_pci_irq_handler(struct irq_desc *desc)
+-{
+- void __iomem *base = ath79_reset_base;
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct ar71xx_pci_controller *apc = irq_desc_get_handler_data(desc);
+- u32 pending;
+-
+- chained_irq_enter(chip, desc);
+- pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
+- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+-
+- if (pending & AR71XX_PCI_INT_DEV0)
+- generic_handle_irq(irq_linear_revmap(apc->domain, 1));
+-
+- else if (pending & AR71XX_PCI_INT_DEV1)
+- generic_handle_irq(irq_linear_revmap(apc->domain, 2));
+-
+- else if (pending & AR71XX_PCI_INT_DEV2)
+- generic_handle_irq(irq_linear_revmap(apc->domain, 3));
+-
+- else if (pending & AR71XX_PCI_INT_CORE)
+- generic_handle_irq(irq_linear_revmap(apc->domain, 4));
+-
+- else
+- spurious_interrupt();
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void ar71xx_pci_irq_unmask(struct irq_data *d)
+-{
+- struct ar71xx_pci_controller *apc;
+- unsigned int irq;
+- void __iomem *base = ath79_reset_base;
+- u32 t;
+-
+- apc = irq_data_get_irq_chip_data(d);
+- irq = irq_linear_revmap(apc->domain, d->irq);
+-
+- t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+- __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+-
+- /* flush write */
+- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+-}
+-
+-static void ar71xx_pci_irq_mask(struct irq_data *d)
+-{
+- struct ar71xx_pci_controller *apc;
+- unsigned int irq;
+- void __iomem *base = ath79_reset_base;
+- u32 t;
+-
+- apc = irq_data_get_irq_chip_data(d);
+- irq = irq_linear_revmap(apc->domain, d->irq);
+-
+- t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+- __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+-
+- /* flush write */
+- __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+-}
+-
+-static struct irq_chip ar71xx_pci_irq_chip = {
+- .name = "AR71XX PCI",
+- .irq_mask = ar71xx_pci_irq_mask,
+- .irq_unmask = ar71xx_pci_irq_unmask,
+- .irq_mask_ack = ar71xx_pci_irq_mask,
+-};
+-
+-static int ar71xx_pci_irq_map(struct irq_domain *d,
+- unsigned int irq, irq_hw_number_t hw)
+-{
+- struct ar71xx_pci_controller *apc = d->host_data;
+-
+- irq_set_chip_and_handler(irq, &ar71xx_pci_irq_chip, handle_level_irq);
+- irq_set_chip_data(irq, apc);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops ar71xx_pci_domain_ops = {
+- .xlate = irq_domain_xlate_onecell,
+- .map = ar71xx_pci_irq_map,
+-};
+-
+-static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc)
+-{
+- void __iomem *base = ath79_reset_base;
+-
+- __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
+- __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
+-
+- apc->domain = irq_domain_add_linear(apc->np, AR71XX_PCI_IRQ_COUNT,
+- &ar71xx_pci_domain_ops, apc);
+- irq_set_chained_handler_and_data(apc->irq, ar71xx_pci_irq_handler,
+- apc);
+-}
+-
+ static void ar71xx_pci_reset(void)
+ {
+ ath79_device_reset_set(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE);
+@@ -357,10 +257,6 @@ static int ar71xx_pci_probe(struct platf
+ if (IS_ERR(apc->cfg_base))
+ return PTR_ERR(apc->cfg_base);
+
+- apc->irq = platform_get_irq(pdev, 0);
+- if (apc->irq < 0)
+- return -EINVAL;
+-
+ ar71xx_pci_reset();
+
+ /* setup COMMAND register */
+@@ -371,8 +267,6 @@ static int ar71xx_pci_probe(struct platf
+ /* clear bus errors */
+ ar71xx_pci_check_error(apc, 1);
+
+- ar71xx_pci_irq_init(apc);
+-
+ apc->np = pdev->dev.of_node;
+ apc->pci_ctrl.pci_ops = &ar71xx_pci_ops;
+ apc->pci_ctrl.mem_resource = &apc->mem_res;
--- /dev/null
+From: David Bauer <mail@david-bauer.net>
+Date: Sat, 11 Apr 2020 14:03:12 +0200
+Subject: MIPS: pci-ar724x: add QCA9550 reset sequence
+
+The QCA9550 family of SoCs have a slightly different reset
+sequence compared to older chips.
+
+Normally the bootloader performs this sequence, however
+some bootloader implementation expect the operating system
+to clear the reset.
+
+Also get the resets from OF to support handling of the second
+PCIe root-complex on the QCA9558.
+
+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
+@@ -390,6 +390,7 @@
+ #define QCA955X_PLL_CPU_CONFIG_REG 0x00
+ #define QCA955X_PLL_DDR_CONFIG_REG 0x04
+ #define QCA955X_PLL_CLK_CTRL_REG 0x08
++#define QCA955X_PLL_PCIE_CONFIG_REG 0x0c
+ #define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28
+ #define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48
+ #define QCA955X_PLL_ETH_SGMII_SERDES_REG 0x4c
+@@ -475,6 +476,9 @@
+ #define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL BIT(21)
+ #define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+
++#define QCA955X_PLL_PCIE_CONFIG_PLL_PWD BIT(30)
++#define QCA955X_PLL_PCIE_CONFIG_PLL_BYPASS BIT(16)
++
+ #define QCA956X_PLL_SWITCH_CLOCK_SPARE_I2C_CLK_SELB BIT(5)
+ #define QCA956X_PLL_SWITCH_CLOCK_SPARE_MDIO_CLK_SEL0_1 BIT(6)
+ #define QCA956X_PLL_SWITCH_CLOCK_SPARE_UART1_CLK_SEL BIT(7)
+--- a/arch/mips/pci/pci-ar724x.c
++++ b/arch/mips/pci/pci-ar724x.c
+@@ -8,6 +8,7 @@
+
+ #include <linux/irq.h>
+ #include <linux/pci.h>
++#include <linux/reset.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/platform_device.h>
+@@ -55,6 +56,9 @@ struct ar724x_pci_controller {
+ struct irq_domain *domain;
+ struct resource io_res;
+ struct resource mem_res;
++
++ struct reset_control *hc_reset;
++ struct reset_control *phy_reset;
+ };
+
+ static struct irq_chip ar724x_pci_irq_chip;
+@@ -340,18 +344,30 @@ static void ar724x_pci_hw_init(struct ar
+ int wait = 0;
+
+ /* deassert PCIe host controller and PCIe PHY reset */
+- ath79_device_reset_clear(AR724X_RESET_PCIE);
+- ath79_device_reset_clear(AR724X_RESET_PCIE_PHY);
++ reset_control_deassert(apc->hc_reset);
++ reset_control_deassert(apc->phy_reset);
+
+- /* remove the reset of the PCIE PLL */
+- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
+- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET;
+- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
+-
+- /* deassert bypass for the PCIE PLL */
+- ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
+- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS;
+- ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
++ if (of_device_is_compatible(apc->np, "qcom,qca9550-pci")) {
++ /* remove the reset of the PCIE PLL */
++ ppl = ath79_pll_rr(QCA955X_PLL_PCIE_CONFIG_REG);
++ ppl &= ~QCA955X_PLL_PCIE_CONFIG_PLL_PWD;
++ ath79_pll_wr(QCA955X_PLL_PCIE_CONFIG_REG, ppl);
++
++ /* deassert bypass for the PCIE PLL */
++ ppl = ath79_pll_rr(QCA955X_PLL_PCIE_CONFIG_REG);
++ ppl &= ~QCA955X_PLL_PCIE_CONFIG_PLL_BYPASS;
++ ath79_pll_wr(QCA955X_PLL_PCIE_CONFIG_REG, ppl);
++ } 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;
++ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
++
++ /* deassert bypass for the PCIE PLL */
++ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
++ ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS;
++ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
++ }
+
+ /* set PCIE Application Control to ready */
+ app = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_APP);
+@@ -395,6 +411,14 @@ static int ar724x_pci_probe(struct platf
+ if (apc->irq < 0)
+ return -EINVAL;
+
++ apc->hc_reset = devm_reset_control_get_exclusive(&pdev->dev, "hc");
++ if (IS_ERR(apc->hc_reset))
++ return PTR_ERR(apc->hc_reset);
++
++ apc->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, "phy");
++ if (IS_ERR(apc->phy_reset))
++ return PTR_ERR(apc->phy_reset);
++
+ apc->np = pdev->dev.of_node;
+ apc->pci_controller.pci_ops = &ar724x_pci_ops;
+ apc->pci_controller.io_resource = &apc->io_res;
+@@ -405,7 +429,7 @@ static int ar724x_pci_probe(struct platf
+ * Do the full PCIE Root Complex Initialization Sequence if the PCIe
+ * host controller is in reset.
+ */
+- if (ath79_reset_rr(AR724X_RESET_REG_RESET_MODULE) & AR724X_RESET_PCIE)
++ if (reset_control_status(apc->hc_reset))
+ ar724x_pci_hw_init(apc);
+
+ apc->link_up = ar724x_pci_check_link(apc);
+@@ -423,6 +447,7 @@ static int ar724x_pci_probe(struct platf
+
+ static const struct of_device_id ar724x_pci_ids[] = {
+ { .compatible = "qcom,ar7240-pci" },
++ { .compatible = "qcom,qca9550-pci" },
+ {},
+ };
+
--- /dev/null
+From: Gabor Juhos <juhosg@openwrt.org>
+Subject: [PATCH] ar71xx: swizzle address for PCI byte/word access on AR71xx
+
+Closes #11683.
+
+SVN-Revision: 32639
+---
+ .../mips/include/asm/mach-ath79/mangle-port.h | 111 ++++++++++++++++++
+ 1 file changed, 111 insertions(+)
+ create mode 100644 arch/mips/include/asm/mach-ath79/mangle-port.h
+
+--- /dev/null
++++ b/arch/mips/include/asm/mach-ath79/mangle-port.h
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
++ *
++ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h
++ * Copyright (C) 2003, 2004 Ralf Baechle
++ *
++ * 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_ATH79_MANGLE_PORT_H
++#define __ASM_MACH_ATH79_MANGLE_PORT_H
++
++#ifdef CONFIG_PCI_AR71XX
++extern unsigned long (ath79_pci_swizzle_b)(unsigned long port);
++extern unsigned long (ath79_pci_swizzle_w)(unsigned long port);
++#else
++#define ath79_pci_swizzle_b(port) (port)
++#define ath79_pci_swizzle_w(port) (port)
++#endif
++
++#define __swizzle_addr_b(port) ath79_pci_swizzle_b(port)
++#define __swizzle_addr_w(port) ath79_pci_swizzle_w(port)
++#define __swizzle_addr_l(port) (port)
++#define __swizzle_addr_q(port) (port)
++
++# define ioswabb(a, x) (x)
++# define __mem_ioswabb(a, x) (x)
++# define ioswabw(a, x) (x)
++# define __mem_ioswabw(a, x) cpu_to_le16(x)
++# define ioswabl(a, x) (x)
++# define __mem_ioswabl(a, x) cpu_to_le32(x)
++# define ioswabq(a, x) (x)
++# define __mem_ioswabq(a, x) cpu_to_le64(x)
++
++#endif /* __ASM_MACH_ATH79_MANGLE_PORT_H */
+--- a/arch/mips/pci/pci-ar71xx.c
++++ b/arch/mips/pci/pci-ar71xx.c
+@@ -68,6 +68,45 @@ static const u32 ar71xx_pci_read_mask[8]
+ 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0
+ };
+
++static unsigned long (*__ath79_pci_swizzle_b)(unsigned long port);
++static unsigned long (*__ath79_pci_swizzle_w)(unsigned long port);
++
++static inline bool ar71xx_is_pci_addr(unsigned long port)
++{
++ unsigned long phys = CPHYSADDR(port);
++
++ return (phys >= AR71XX_PCI_MEM_BASE &&
++ phys < AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE);
++}
++
++static unsigned long ar71xx_pci_swizzle_b(unsigned long port)
++{
++ return ar71xx_is_pci_addr(port) ? port ^ 3 : port;
++}
++
++static unsigned long ar71xx_pci_swizzle_w(unsigned long port)
++{
++ return ar71xx_is_pci_addr(port) ? port ^ 2 : port;
++}
++
++unsigned long ath79_pci_swizzle_b(unsigned long port)
++{
++ if (__ath79_pci_swizzle_b)
++ return __ath79_pci_swizzle_b(port);
++
++ return port;
++}
++EXPORT_SYMBOL(ath79_pci_swizzle_b);
++
++unsigned long ath79_pci_swizzle_w(unsigned long port)
++{
++ if (__ath79_pci_swizzle_w)
++ return __ath79_pci_swizzle_w(port);
++
++ return port;
++}
++EXPORT_SYMBOL(ath79_pci_swizzle_w);
++
+ static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
+ {
+ u32 t;
+@@ -275,6 +314,9 @@ static int ar71xx_pci_probe(struct platf
+
+ register_pci_controller(&apc->pci_ctrl);
+
++ __ath79_pci_swizzle_b = ar71xx_pci_swizzle_b;
++ __ath79_pci_swizzle_w = ar71xx_pci_swizzle_w;
++
+ return 0;
+ }
+
--- /dev/null
+From: Christian Lamparter <chunkeey@gmail.com>
+Subject: [PATCH] ath79: gmac: add parsers for rxd(v)- and tx(d|en)-delay for
+
+ ath79: gmac: add parsers for rxd(v)- and tx(d|en)-delay for AR9344
+
+ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+
+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+@@ -1231,6 +1231,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
++#define AR934X_ETH_CFG_TXD_DELAY_MASK 0x3
++#define AR934X_ETH_CFG_TXD_DELAY_SHIFT 18
++#define AR934X_ETH_CFG_TXE_DELAY_MASK 0x3
++#define AR934X_ETH_CFG_TXE_DELAY_SHIFT 20
+
+ /*
+ * QCA953X GMAC Interface
--- /dev/null
+From 60efe35257b063ce584968f9f80b437030ce6ba6 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+Date: Mon, 18 Mar 2019 00:54:06 +0100
+Subject: [PATCH] MIPS: ath79: add missing QCA955x GMAC registers
+
+This adds missing GMAC register definitions for the Qualcomm Atheros
+QCA955X series MIPS SoCs.
+
+They originate from the platforms U-Boot code and the AVM FRITZ!WLAN
+Repeater 450E's GPL tarball.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+---
+ .../mips/include/asm/mach-ath79/ar71xx_regs.h | 54 +++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+
+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+@@ -1251,7 +1251,12 @@
+ */
+
+ #define QCA955X_GMAC_REG_ETH_CFG 0x00
++#define QCA955X_GMAC_REG_SGMII_RESET 0x14
+ #define QCA955X_GMAC_REG_SGMII_SERDES 0x18
++#define QCA955X_GMAC_REG_MR_AN_CONTROL 0x1c
++#define QCA955X_GMAC_REG_MR_AN_STATUS 0x20
++#define QCA955X_GMAC_REG_SGMII_CONFIG 0x34
++#define QCA955X_GMAC_REG_SGMII_DEBUG 0x58
+
+ #define QCA955X_ETH_CFG_RGMII_EN BIT(0)
+ #define QCA955X_ETH_CFG_MII_GE0 BIT(1)
+@@ -1273,9 +1278,58 @@
+ #define QCA955X_ETH_CFG_TXE_DELAY_MASK 0x3
+ #define QCA955X_ETH_CFG_TXE_DELAY_SHIFT 20
+
++#define QCA955X_SGMII_RESET_RX_CLK_N_RESET 0
++#define QCA955X_SGMII_RESET_RX_CLK_N BIT(0)
++#define QCA955X_SGMII_RESET_TX_CLK_N BIT(1)
++#define QCA955X_SGMII_RESET_RX_125M_N BIT(2)
++#define QCA955X_SGMII_RESET_TX_125M_N BIT(3)
++#define QCA955X_SGMII_RESET_HW_RX_125M_N BIT(4)
++
+ #define QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS BIT(15)
+ #define QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT 23
+ #define QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK 0xf
++
++#define QCA955X_MR_AN_CONTROL_SPEED_SEL1 BIT(6)
++#define QCA955X_MR_AN_CONTROL_DUPLEX_MODE BIT(8)
++#define QCA955X_MR_AN_CONTROL_RESTART_AN BIT(9)
++#define QCA955X_MR_AN_CONTROL_POWER_DOWN BIT(11)
++#define QCA955X_MR_AN_CONTROL_AN_ENABLE BIT(12)
++#define QCA955X_MR_AN_CONTROL_SPEED_SEL0 BIT(13)
++#define QCA955X_MR_AN_CONTROL_LOOPBACK BIT(14)
++#define QCA955X_MR_AN_CONTROL_PHY_RESET BIT(15)
++
++#define QCA955X_MR_AN_STATUS_EXT_CAP BIT(0)
++#define QCA955X_MR_AN_STATUS_LINK_UP BIT(2)
++#define QCA955X_MR_AN_STATUS_AN_ABILITY BIT(3)
++#define QCA955X_MR_AN_STATUS_REMOTE_FAULT BIT(4)
++#define QCA955X_MR_AN_STATUS_AN_COMPLETE BIT(5)
++#define QCA955X_MR_AN_STATUS_NO_PREAMBLE BIT(6)
++#define QCA955X_MR_AN_STATUS_BASE_PAGE BIT(7)
++
++#define QCA955X_SGMII_CONFIG_MODE_CTRL_SHIFT 0
++#define QCA955X_SGMII_CONFIG_MODE_CTRL_MASK 0x7
++#define QCA955X_SGMII_CONFIG_ENABLE_SGMII_TX_PAUSE BIT(3)
++#define QCA955X_SGMII_CONFIG_MR_REG4_CHANGED BIT(4)
++#define QCA955X_SGMII_CONFIG_FORCE_SPEED BIT(5)
++#define QCA955X_SGMII_CONFIG_SPEED_SHIFT 6
++#define QCA955X_SGMII_CONFIG_SPEED_MASK 0xc0
++#define QCA955X_SGMII_CONFIG_REMOTE_PHY_LOOPBACK BIT(8)
++#define QCA955X_SGMII_CONFIG_NEXT_PAGE_LOADED BIT(9)
++#define QCA955X_SGMII_CONFIG_MDIO_ENABLE BIT(10)
++#define QCA955X_SGMII_CONFIG_MDIO_PULSE BIT(11)
++#define QCA955X_SGMII_CONFIG_MDIO_COMPLETE BIT(12)
++#define QCA955X_SGMII_CONFIG_PRBS_ENABLE BIT(13)
++#define QCA955X_SGMII_CONFIG_BERT_ENABLE BIT(14)
++
++#define QCA955X_SGMII_DEBUG_TX_STATE_MASK 0xff
++#define QCA955X_SGMII_DEBUG_TX_STATE_SHIFT 0
++#define QCA955X_SGMII_DEBUG_RX_STATE_MASK 0xff00
++#define QCA955X_SGMII_DEBUG_RX_STATE_SHIFT 8
++#define QCA955X_SGMII_DEBUG_RX_SYNC_STATE_MASK 0xff0000
++#define QCA955X_SGMII_DEBUG_RX_SYNC_STATE_SHIFT 16
++#define QCA955X_SGMII_DEBUG_ARB_STATE_MASK 0xf000000
++#define QCA955X_SGMII_DEBUG_ARB_STATE_SHIFT 24
++
+ /*
+ * QCA956X GMAC Interface
+ */
--- /dev/null
+From: David Bauer <mail@david-bauer.net>
+Subject: [PATCH] ath79: force SGMII SerDes mode to MAC operation
+
+The mode on the SGMII SerDes on the QCA9563 is 1000 Base-X by default.
+This only allows for 1000 Mbit/s links, however when used with an SGMII
+PHY in 100 Mbit/s link mode, the link remains dead.
+
+This strictly has nothing to do with the SerDes calibration, however it
+is done at the same point in the QCA reference U-Boot which is the
+blueprint for everything happening here. As the current state is more or
+less a hack, this should be fine.
+
+This fixes the issues outlined above on a TP-Link EAP-225 Outdoor.
+
+Reported-by: Tom Herbers <freifunk@tomherbers.de>
+Tested-by: Tom Herbers <freifunk@tomherbers.de>
+Submitted-by: David Bauer <mail@david-bauer.net>
+---
+ arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 1 +
+ 1 files changed, 1 insertion(+)
+
+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+@@ -1380,5 +1380,6 @@
+
+ #define QCA956X_SGMII_CONFIG_MODE_CTRL_SHIFT 0
+ #define QCA956X_SGMII_CONFIG_MODE_CTRL_MASK 0x7
++#define QCA956X_SGMII_CONFIG_MODE_CTRL_SGMII_MAC 0x2
+
+ #endif /* __ASM_MACH_AR71XX_REGS_H */
--- /dev/null
+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
+@@ -302,7 +302,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");
--- /dev/null
+From: John Crispin <john@phrozen.org>
+Subject: [PATCH] ath79: make ahb wifi work
+
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ arch/mips/ath79/common.c | 3 +++
+ mips/include/asm/mach-ath79/ath79.h | 1+
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/mips/ath79/common.c
++++ b/arch/mips/ath79/common.c
+@@ -31,11 +31,13 @@ EXPORT_SYMBOL_GPL(ath79_ddr_freq);
+
+ enum ath79_soc_type ath79_soc;
+ unsigned int ath79_soc_rev;
++EXPORT_SYMBOL_GPL(ath79_soc_rev);
+
+ void __iomem *ath79_pll_base;
+ void __iomem *ath79_reset_base;
+ EXPORT_SYMBOL_GPL(ath79_reset_base);
+-static void __iomem *ath79_ddr_base;
++void __iomem *ath79_ddr_base;
++EXPORT_SYMBOL_GPL(ath79_ddr_base);
+ static void __iomem *ath79_ddr_wb_flush_base;
+ static void __iomem *ath79_ddr_pci_win_base;
+
+--- a/arch/mips/include/asm/mach-ath79/ath79.h
++++ b/arch/mips/include/asm/mach-ath79/ath79.h
+@@ -149,6 +149,7 @@ void ath79_ddr_wb_flush(unsigned int reg
+ void ath79_ddr_set_pci_windows(void);
+
+ extern void __iomem *ath79_pll_base;
++extern void __iomem *ath79_ddr_base;
+ extern void __iomem *ath79_reset_base;
+
+ static inline void ath79_pll_wr(unsigned reg, u32 val)
--- /dev/null
+From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
+Subject: [PATCH] ath79: export ath79_pll_base
+
+This symbol is declared as extern but nobody exported it.
+Any module including arch/mips/include/asm/mach-ath79/ath79.h
+will not build. Without this export, ag71xx.ko will not build
+as a module and the build will fail like this:
+
+ERROR: modpost: "ath79_pll_base" [drivers/net/ethernet/atheros/ag71xx/ag71xx.ko] undefined!
+
+The ath79_pll_base symbol is accessed in the ath79_pll_wr() inline function.
+
+---
+ arch/mips/ath79/common.c | 1 +
+ 1 file changed, 1 insertions(+)
+
+--- a/arch/mips/ath79/common.c
++++ b/arch/mips/ath79/common.c
+@@ -34,6 +34,7 @@ unsigned int ath79_soc_rev;
+ EXPORT_SYMBOL_GPL(ath79_soc_rev);
+
+ void __iomem *ath79_pll_base;
++EXPORT_SYMBOL_GPL(ath79_pll_base);
+ void __iomem *ath79_reset_base;
+ EXPORT_SYMBOL_GPL(ath79_reset_base);
+ void __iomem *ath79_ddr_base;
--- /dev/null
+From: Daniel Golle <daniel@makrotopia.org>
+Subject: [PATCH] ath79: add support for Atheros AR934x HS UART
+
+AR934x chips also got the 'old' qca,ar9330-uart in addition to the
+'new' ns16550a compatible one. Add support for UART1 clock selector as
+well as device-tree bindings in ar934x.dtsi to make use of that uart.
+
+Reported-by: Piotr Dymacz <pepe2k@gmail.com>
+Submitted-by: Daniel Golle <daniel@makrotopia.org>
+---
+ arch/mips/ath79/clock.c | 7 +++++++
+ .../mips/include/asm/mach-ath79/ar71xx_regs.h | 1 +
+ include/dt-bindings/clock/ath79-clk.h | 3 ++-
+ 3 files changed, 10 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/ath79/clock.c
++++ b/arch/mips/ath79/clock.c
+@@ -40,6 +40,7 @@ static const char * const clk_names[ATH7
+ [ATH79_CLK_AHB] = "ahb",
+ [ATH79_CLK_REF] = "ref",
+ [ATH79_CLK_MDIO] = "mdio",
++ [ATH79_CLK_UART1] = "uart1",
+ };
+
+ static const char * __init ath79_clk_name(int type)
+@@ -344,6 +345,9 @@ static void __init ar934x_clocks_init(vo
+ if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL)
+ ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000);
+
++ if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL)
++ ath79_set_clk(ATH79_CLK_UART1, 100 * 1000 * 1000);
++
+ iounmap(dpll_base);
+ }
+
+@@ -649,6 +653,9 @@ static void __init ath79_clocks_init_dt(
+ if (!clks[ATH79_CLK_MDIO])
+ clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF];
+
++ if (!clks[ATH79_CLK_UART1])
++ clks[ATH79_CLK_UART1] = clks[ATH79_CLK_REF];
++
+ if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) {
+ pr_err("%pOF: could not register clk provider\n", np);
+ 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)
+
+ #define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
++#define AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL BIT(7)
+
+ #define QCA953X_PLL_CPU_CONFIG_REG 0x00
+ #define QCA953X_PLL_DDR_CONFIG_REG 0x04
+--- a/include/dt-bindings/clock/ath79-clk.h
++++ b/include/dt-bindings/clock/ath79-clk.h
+@@ -11,7 +11,8 @@
+ #define ATH79_CLK_AHB 2
+ #define ATH79_CLK_REF 3
+ #define ATH79_CLK_MDIO 4
++#define ATH79_CLK_UART1 5
+
+-#define ATH79_CLK_END 5
++#define ATH79_CLK_END 6
+
+ #endif /* __DT_BINDINGS_ATH79_CLK_H */
--- /dev/null
+From 3fc8585cf76022dba7496627074d42af88c30718 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Sat, 23 Jun 2018 15:16:55 +0200
+Subject: [PATCH 32/33] MIPS: ath79: sanitize symbols
+
+We no longer need to select which SoCs are supported as the whole arch
+code is always built. So lets drop all the SoC symbols
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ arch/mips/Kconfig | 2 ++
+ arch/mips/ath79/Kconfig | 44 +++++---------------------------------------
+ arch/mips/pci/Makefile | 2 +-
+ 3 files changed, 8 insertions(+), 40 deletions(-)
+
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -255,6 +255,8 @@ config ATH79
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_MIPS16
+ select SYS_SUPPORTS_ZBOOT_UART_PROM
++ select HAVE_PCI
++ select USB_ARCH_HAS_EHCI
+ select USE_OF
+ select USB_EHCI_ROOT_HUB_TT if USB_EHCI_HCD_PLATFORM
+ help
+--- a/arch/mips/ath79/Kconfig
++++ b/arch/mips/ath79/Kconfig
+@@ -1,32 +1,14 @@
+ # SPDX-License-Identifier: GPL-2.0
+ if ATH79
+
+-config SOC_AR71XX
+- select HAVE_PCI
+- def_bool n
+-
+-config SOC_AR724X
+- select HAVE_PCI
+- select PCI_AR724X if PCI
+- def_bool n
+-
+-config SOC_AR913X
+- def_bool n
+-
+-config SOC_AR933X
+- def_bool n
+-
+-config SOC_AR934X
+- select HAVE_PCI
+- select PCI_AR724X if PCI
+- def_bool n
+-
+-config SOC_QCA955X
+- select HAVE_PCI
+- select PCI_AR724X if PCI
++config PCI_AR71XX
++ bool "PCI support for AR7100 type SoCs"
++ depends on PCI
+ def_bool n
+
+ config PCI_AR724X
++ bool "PCI support for AR724x type SoCs"
++ depends on PCI
+ def_bool n
+
+ endif
+--- a/arch/mips/pci/Makefile
++++ b/arch/mips/pci/Makefile
+@@ -19,7 +19,7 @@ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o
+ ops-bcm63xx.o
+ obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
+ obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o
+-obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
++obj-$(CONFIG_PCI_AR71XX) += pci-ar71xx.o
+ obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
+ obj-$(CONFIG_PCI_XTALK_BRIDGE) += pci-xtalk-bridge.o
+ #
--- /dev/null
+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
+@@ -3420,12 +3420,19 @@ 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
+@@ -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;
--- /dev/null
+From: Christian Lamparter <chunkeey@gmail.com>
+Subject: [PATCH] ath79: port cybertan_part from ar71xx
+
+This patch ports the cybertan_part code from ar71xx and converts the
+driver to a DT-supported mtd parser. As a result, it will no longer
+add the u-boot, nvram and art partitions, which were never part of
+the special Cybertan header.
+
+Instead these partitions have to be specified in the DT, which has the
+upside of making it possible to add properties (i.e.: read-only), labels
+and references to these important partitions.
+
+Submitted-by: Christian Lamparter <chunkeey@gmail.com>
+---
+ drivers/mtd/parsers/Makefile | 1 +
+ drivers/mtd/parsers/Kconfig | 8 ++++++++
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/mtd/parsers/Makefile
++++ b/drivers/mtd/parsers/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
+ ofpart-y += ofpart_core.o
+ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o
+ ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o
++obj-$(CONFIG_MTD_PARSER_CYBERTAN) += parser_cybertan.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
+--- a/drivers/mtd/parsers/Kconfig
++++ b/drivers/mtd/parsers/Kconfig
+@@ -112,6 +112,14 @@ config MTD_OF_PARTS_LINKSYS_NS
+ two "firmware" partitions. Currently used firmware has to be detected
+ using CFE environment variable.
+
++config MTD_PARSER_CYBERTAN
++ tristate "Parser for Cybertan format partitions"
++ depends on MTD && (ATH79 || COMPILE_TEST)
++ help
++ Cybertan has a proprietory header than encompasses a Broadcom trx
++ header. This driver will parse the header and take care of the
++ special offsets that result in the extra headers.
++
+ config MTD_PARSER_IMAGETAG
+ tristate "Parser for BCM963XX Image Tag format partitions"
+ depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST
--- /dev/null
+From: Gabor Juhos <juhosg@openwrt.org>
+Subject: [PATCH] ar71xx: Link SPI before MTD
+
+SVN-Revision: 22863
+---
+ drivers/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -87,8 +87,8 @@ obj-y += scsi/
+ obj-y += nvme/
+ obj-$(CONFIG_ATA) += ata/
+ obj-$(CONFIG_TARGET_CORE) += target/
+-obj-$(CONFIG_MTD) += mtd/
+ obj-$(CONFIG_SPI) += spi/
++obj-$(CONFIG_MTD) += mtd/
+ obj-$(CONFIG_SPMI) += spmi/
+ obj-$(CONFIG_HSI) += hsi/
+ obj-$(CONFIG_SLIMBUS) += slimbus/
--- /dev/null
+From: Gabor Juhos <juhosg@openwrt.org>
+Subject: ar71xx: ar934x_nfc: experimental NAND Flash Controller driver for AR934x
+
+SVN-Revision: 33385
+---
+ drivers/mtd/nand/raw/Kconfig | 8 ++++++++
+ drivers/mtd/nand/raw/Makefile | 1 +
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/mtd/nand/raw/Kconfig
++++ b/drivers/mtd/nand/raw/Kconfig
+@@ -543,4 +543,12 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
+ load time (assuming you build diskonchip as a module) with the module
+ parameter "inftl_bbt_write=1".
+
++config MTD_NAND_AR934X
++ tristate "Support for NAND controller on Qualcomm Atheros AR934x/QCA955x SoCs"
++ depends on ATH79 || COMPILE_TEST
++ depends on HAS_IOMEM
++ help
++ Enables support for NAND controller on Qualcomm Atheros SoCs.
++ This controller is found on AR934x and QCA955x SoCs.
++
+ endif # MTD_RAW_NAND
+--- a/drivers/mtd/nand/raw/Makefile
++++ b/drivers/mtd/nand/raw/Makefile
+@@ -57,6 +57,7 @@ obj-$(CONFIG_MTD_NAND_INTEL_LGM) += inte
+ obj-$(CONFIG_MTD_NAND_ROCKCHIP) += rockchip-nand-controller.o
+ obj-$(CONFIG_MTD_NAND_PL35X) += pl35x-nand-controller.o
+ obj-$(CONFIG_MTD_NAND_RENESAS) += renesas-nand-controller.o
++obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nand.o
+
+ nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
+ nand-objs += nand_onfi.o
--- /dev/null
+From 08c9d6ceef01893678a5d2e8a15517c745417f21 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Tue, 6 Mar 2018 10:04:05 +0100
+Subject: [PATCH 04/27] phy: add ath79 usb phys
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/phy/Kconfig | 16 ++++++
+ drivers/phy/Makefile | 2 +
+ drivers/phy/phy-ar7100-usb.c | 124 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/phy/phy-ar7200-usb.c | 108 +++++++++++++++++++++++++++++++++++++
+ 4 files changed, 250 insertions(+)
+ create mode 100644 drivers/phy/phy-ar7100-usb.c
+ create mode 100644 drivers/phy/phy-ar7200-usb.c
+
+--- a/drivers/phy/Kconfig
++++ b/drivers/phy/Kconfig
+@@ -25,6 +25,22 @@ config GENERIC_PHY_MIPI_DPHY
+ Provides a number of helpers a core functions for MIPI D-PHY
+ drivers to us.
+
++config PHY_AR7100_USB
++ tristate "Atheros AR7100 USB PHY driver"
++ depends on ATH79 || COMPILE_TEST
++ default y if USB_EHCI_HCD_PLATFORM
++ select GENERIC_PHY
++ help
++ Enable this to support the USB PHY on Atheros AR7100 SoCs.
++
++config PHY_AR7200_USB
++ tristate "Atheros AR7200 USB PHY driver"
++ depends on ATH79 || COMPILE_TEST
++ default y if USB_EHCI_HCD_PLATFORM
++ select GENERIC_PHY
++ help
++ Enable this to support the USB PHY on Atheros AR7200 SoCs.
++
+ config PHY_LPC18XX_USB_OTG
+ tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver"
+ depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
+--- a/drivers/phy/Makefile
++++ b/drivers/phy/Makefile
+@@ -4,6 +4,8 @@
+ #
+
+ obj-$(CONFIG_GENERIC_PHY) += phy-core.o
++obj-$(CONFIG_PHY_AR7100_USB) += phy-ar7100-usb.o
++obj-$(CONFIG_PHY_AR7200_USB) += phy-ar7200-usb.o
+ obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o
+ obj-$(CONFIG_PHY_CAN_TRANSCEIVER) += phy-can-transceiver.o
+ obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
+--- /dev/null
++++ b/drivers/phy/phy-ar7100-usb.c
+@@ -0,0 +1,140 @@
++/*
++ * Copyright (C) 2018 John Crispin <john@phrozen.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.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/phy/phy.h>
++#include <linux/delay.h>
++#include <linux/reset.h>
++#include <linux/of_gpio.h>
++
++#include <asm/mach-ath79/ath79.h>
++#include <asm/mach-ath79/ar71xx_regs.h>
++
++struct ar7100_usb_phy {
++ struct reset_control *rst_phy;
++ struct reset_control *rst_host;
++ struct reset_control *rst_ohci_dll;
++ void __iomem *io_base;
++ struct phy *phy;
++ int gpio;
++};
++
++static int ar7100_usb_phy_power_off(struct phy *phy)
++{
++ struct ar7100_usb_phy *priv = phy_get_drvdata(phy);
++ int err = 0;
++
++ err |= reset_control_assert(priv->rst_host);
++ err |= reset_control_assert(priv->rst_phy);
++ err |= reset_control_assert(priv->rst_ohci_dll);
++
++ return err;
++}
++
++static int ar7100_usb_phy_power_on(struct phy *phy)
++{
++ struct ar7100_usb_phy *priv = phy_get_drvdata(phy);
++ int err = 0;
++
++ err |= ar7100_usb_phy_power_off(phy);
++ mdelay(100);
++ err |= reset_control_deassert(priv->rst_ohci_dll);
++ err |= reset_control_deassert(priv->rst_phy);
++ err |= reset_control_deassert(priv->rst_host);
++ mdelay(500);
++ iowrite32(0xf0000, priv->io_base + AR71XX_USB_CTRL_REG_CONFIG);
++ iowrite32(0x20c00, priv->io_base + AR71XX_USB_CTRL_REG_FLADJ);
++
++ return err;
++}
++
++static const struct phy_ops ar7100_usb_phy_ops = {
++ .power_on = ar7100_usb_phy_power_on,
++ .power_off = ar7100_usb_phy_power_off,
++ .owner = THIS_MODULE,
++};
++
++static int ar7100_usb_phy_probe(struct platform_device *pdev)
++{
++ struct phy_provider *phy_provider;
++ struct resource *res;
++ struct ar7100_usb_phy *priv;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ priv->io_base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(priv->io_base))
++ return PTR_ERR(priv->io_base);
++
++ priv->rst_phy = devm_reset_control_get(&pdev->dev, "usb-phy");
++ if (IS_ERR(priv->rst_phy)) {
++ dev_err(&pdev->dev, "phy reset is missing\n");
++ return PTR_ERR(priv->rst_phy);
++ }
++
++ priv->rst_host = devm_reset_control_get(&pdev->dev, "usb-host");
++ if (IS_ERR(priv->rst_host)) {
++ dev_err(&pdev->dev, "host reset is missing\n");
++ return PTR_ERR(priv->rst_host);
++ }
++
++ priv->rst_ohci_dll = devm_reset_control_get(&pdev->dev, "usb-ohci-dll");
++ if (IS_ERR(priv->rst_ohci_dll)) {
++ dev_err(&pdev->dev, "ohci-dll reset is missing\n");
++ return PTR_ERR(priv->rst_host);
++ }
++
++ priv->phy = devm_phy_create(&pdev->dev, NULL, &ar7100_usb_phy_ops);
++ if (IS_ERR(priv->phy)) {
++ dev_err(&pdev->dev, "failed to create PHY\n");
++ return PTR_ERR(priv->phy);
++ }
++
++ priv->gpio = of_get_named_gpio(pdev->dev.of_node, "gpios", 0);
++ if (gpio_is_valid(priv->gpio)) {
++ int ret = devm_gpio_request(&pdev->dev, priv->gpio, dev_name(&pdev->dev));
++
++ if (ret) {
++ dev_err(&pdev->dev, "failed to request gpio\n");
++ return ret;
++ }
++ gpio_export_with_name(gpio_to_desc(priv->gpio), 0, dev_name(&pdev->dev));
++ gpio_set_value(priv->gpio, 1);
++ }
++
++ phy_set_drvdata(priv->phy, priv);
++
++ 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 ar7100_usb_phy_of_match[] = {
++ { .compatible = "qca,ar7100-usb-phy" },
++ {}
++};
++MODULE_DEVICE_TABLE(of, ar7100_usb_phy_of_match);
++
++static struct platform_driver ar7100_usb_phy_driver = {
++ .probe = ar7100_usb_phy_probe,
++ .driver = {
++ .of_match_table = ar7100_usb_phy_of_match,
++ .name = "ar7100-usb-phy",
++ }
++};
++module_platform_driver(ar7100_usb_phy_driver);
++
++MODULE_DESCRIPTION("ATH79 USB PHY driver");
++MODULE_AUTHOR("Alban Bedel <albeu@free.fr>");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/phy/phy-ar7200-usb.c
+@@ -0,0 +1,136 @@
++/*
++ * Copyright (C) 2015 Alban Bedel <albeu@free.fr>
++ *
++ * 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/module.h>
++#include <linux/platform_device.h>
++#include <linux/phy/phy.h>
++#include <linux/reset.h>
++#include <linux/of_gpio.h>
++
++struct ar7200_usb_phy {
++ struct reset_control *rst_phy;
++ struct reset_control *rst_phy_analog;
++ struct reset_control *suspend_override;
++ struct phy *phy;
++ int gpio;
++};
++
++static int ar7200_usb_phy_power_on(struct phy *phy)
++{
++ struct ar7200_usb_phy *priv = phy_get_drvdata(phy);
++ int err = 0;
++
++ if (priv->suspend_override)
++ err = reset_control_assert(priv->suspend_override);
++ if (priv->rst_phy)
++ err |= reset_control_deassert(priv->rst_phy);
++ if (priv->rst_phy_analog)
++ err |= reset_control_deassert(priv->rst_phy_analog);
++
++ return err;
++}
++
++static int ar7200_usb_phy_power_off(struct phy *phy)
++{
++ struct ar7200_usb_phy *priv = phy_get_drvdata(phy);
++ int err = 0;
++
++ if (priv->suspend_override)
++ err = reset_control_deassert(priv->suspend_override);
++ if (priv->rst_phy)
++ err |= reset_control_assert(priv->rst_phy);
++ if (priv->rst_phy_analog)
++ err |= reset_control_assert(priv->rst_phy_analog);
++
++ return err;
++}
++
++static const struct phy_ops ar7200_usb_phy_ops = {
++ .power_on = ar7200_usb_phy_power_on,
++ .power_off = ar7200_usb_phy_power_off,
++ .owner = THIS_MODULE,
++};
++
++static int ar7200_usb_phy_probe(struct platform_device *pdev)
++{
++ struct phy_provider *phy_provider;
++ struct ar7200_usb_phy *priv;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ priv->rst_phy = devm_reset_control_get(&pdev->dev, "usb-phy");
++ if (IS_ERR(priv->rst_phy)) {
++ if (PTR_ERR(priv->rst_phy) != -EPROBE_DEFER)
++ dev_err(&pdev->dev, "phy reset is missing\n");
++ return PTR_ERR(priv->rst_phy);
++ }
++
++ priv->rst_phy_analog = devm_reset_control_get_optional(
++ &pdev->dev, "usb-phy-analog");
++ if (IS_ERR(priv->rst_phy_analog)) {
++ if (PTR_ERR(priv->rst_phy_analog) == -ENOENT)
++ priv->rst_phy_analog = NULL;
++ else
++ return PTR_ERR(priv->rst_phy_analog);
++ }
++
++ priv->suspend_override = devm_reset_control_get_optional(
++ &pdev->dev, "usb-suspend-override");
++ if (IS_ERR(priv->suspend_override)) {
++ if (PTR_ERR(priv->suspend_override) == -ENOENT)
++ priv->suspend_override = NULL;
++ else
++ return PTR_ERR(priv->suspend_override);
++ }
++
++ priv->phy = devm_phy_create(&pdev->dev, NULL, &ar7200_usb_phy_ops);
++ if (IS_ERR(priv->phy)) {
++ dev_err(&pdev->dev, "failed to create PHY\n");
++ return PTR_ERR(priv->phy);
++ }
++
++ priv->gpio = of_get_named_gpio(pdev->dev.of_node, "gpios", 0);
++ if (gpio_is_valid(priv->gpio)) {
++ int ret = devm_gpio_request(&pdev->dev, priv->gpio, dev_name(&pdev->dev));
++
++ if (ret) {
++ dev_err(&pdev->dev, "failed to request gpio\n");
++ return ret;
++ }
++ gpio_export_with_name(gpio_to_desc(priv->gpio), 0, dev_name(&pdev->dev));
++ gpio_set_value(priv->gpio, 1);
++ }
++
++ phy_set_drvdata(priv->phy, priv);
++
++ 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 ar7200_usb_phy_of_match[] = {
++ { .compatible = "qca,ar7200-usb-phy" },
++ {}
++};
++MODULE_DEVICE_TABLE(of, ar7200_usb_phy_of_match);
++
++static struct platform_driver ar7200_usb_phy_driver = {
++ .probe = ar7200_usb_phy_probe,
++ .driver = {
++ .of_match_table = ar7200_usb_phy_of_match,
++ .name = "ar7200-usb-phy",
++ }
++};
++module_platform_driver(ar7200_usb_phy_driver);
++
++MODULE_DESCRIPTION("ATH79 USB PHY driver");
++MODULE_AUTHOR("Alban Bedel <albeu@free.fr>");
++MODULE_LICENSE("GPL");
--- /dev/null
+From 2201818e5bd33f389beceb3943fdfcf5a698fc5b Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Tue, 6 Mar 2018 10:01:43 +0100
+Subject: [PATCH 05/27] usb: add more OF/quirk properties
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/usb/host/ehci-platform.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/host/ehci-platform.c
++++ b/drivers/usb/host/ehci-platform.c
+@@ -274,6 +274,11 @@ static int ehci_platform_probe(struct pl
+ ehci = hcd_to_ehci(hcd);
+
+ if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
++ of_property_read_u32(dev->dev.of_node, "caps-offset", &pdata->caps_offset);
++
++ if (of_property_read_bool(dev->dev.of_node, "has-synopsys-hc-bug"))
++ pdata->has_synopsys_hc_bug = 1;
++
+ if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
+ ehci->big_endian_mmio = 1;
+
--- /dev/null
+From: John Crispin <john@phrozen.org>
+Subject: [PATCH] ath79: add new OF only target for QCA MIPS silicon
+
+This target aims to replace ar71xx mid-term. The big part that is still
+missing is making the MMIO/AHB wifi work using OF. NAND and mikrotik
+subtargets will follow.
+
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ drivers/net/ethernet/atheros/Kconfig | 8 +-------
+ drivers/net/ethernet/atheros/Makefile | 2 +-
+ 2 files changed, 2 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/atheros/Kconfig
++++ b/drivers/net/ethernet/atheros/Kconfig
+@@ -17,14 +17,7 @@ config NET_VENDOR_ATHEROS
+
+ 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"
+--- a/drivers/net/ethernet/atheros/Makefile
++++ b/drivers/net/ethernet/atheros/Makefile
+@@ -3,7 +3,7 @@
+ # Makefile for the Atheros network device drivers.
+ #
+
+-obj-$(CONFIG_AG71XX) += ag71xx.o
++obj-$(CONFIG_AG71XX) += ag71xx/
+ obj-$(CONFIG_ATL1) += atlx/
+ obj-$(CONFIG_ATL2) += atlx/
+ obj-$(CONFIG_ATL1E) += atl1e/
--- /dev/null
+From: Jonas Gorski <jogo@openwrt.org>
+Subject: ar71xx: add a workaround for ar8316 not always driving the TA bit to low
+
+AR8316 behind a GPIO bitbanged MDIO bus fails to drive the turnaround bit
+to low despite returning a valid value. Ignore it and just use the
+returned value anyway.
+
+SVN-Revision: 28422
+---
+ drivers/net/mdio/mdio-bitbang.c | 16 ++-----------------
+ 1 file changed, 2 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/mdio/mdio-bitbang.c
++++ b/drivers/net/mdio/mdio-bitbang.c
+@@ -148,23 +148,11 @@ static void mdiobb_cmd_addr(struct mdiob
+ static int mdiobb_read_common(struct mii_bus *bus, int phy)
+ {
+ struct mdiobb_ctrl *ctrl = bus->priv;
+- int ret, i;
++ int ret;
+
+ ctrl->ops->set_mdio_dir(ctrl, 0);
+
+- /* check the turnaround bit: the PHY should be driving it to zero, if this
+- * PHY is listed in phy_ignore_ta_mask as having broken TA, skip that
+- */
+- if (mdiobb_get_bit(ctrl) != 0 &&
+- !(bus->phy_ignore_ta_mask & (1 << phy))) {
+- /* PHY didn't drive TA low -- flush any bits it
+- * may be trying to send.
+- */
+- for (i = 0; i < 32; i++)
+- mdiobb_get_bit(ctrl);
+-
+- return 0xffff;
+- }
++ mdiobb_get_bit(ctrl);
+
+ ret = mdiobb_get_num(ctrl, 16);
+ mdiobb_get_bit(ctrl);
--- /dev/null
+From 66e584435ac0de6e0abeb6d7166fe4fe25d6bb73 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo@openwrt.org>
+Date: Tue, 16 Jun 2015 13:15:08 +0200
+Subject: [PATCH] phy/mdio-bitbang: prevent rescheduling during command
+
+It seems some phys have some maximum timings for accessing the MDIO line,
+resulting in bit errors under cpu stress. Prevent this from happening by
+disabling interrupts when sending commands.
+
+Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+---
+ drivers/net/mdio/mdio-bitbang.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/net/mdio/mdio-bitbang.c
++++ b/drivers/net/mdio/mdio-bitbang.c
+@@ -14,6 +14,7 @@
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ */
+
++#include <linux/irqflags.h>
+ #include <linux/delay.h>
+ #include <linux/mdio-bitbang.h>
+ #include <linux/module.h>
+@@ -161,22 +162,32 @@ static int mdiobb_read_common(struct mii
+
+ int mdiobb_read_c22(struct mii_bus *bus, int phy, int reg)
+ {
++ int ret;
++ unsigned long flags;
+ struct mdiobb_ctrl *ctrl = bus->priv;
+
++ local_irq_save(flags);
+ mdiobb_cmd(ctrl, ctrl->op_c22_read, phy, reg);
+
+- return mdiobb_read_common(bus, phy);
++ ret = mdiobb_read_common(bus, phy);
++ local_irq_restore(flags);
++ return ret;
+ }
+ EXPORT_SYMBOL(mdiobb_read_c22);
+
+ int mdiobb_read_c45(struct mii_bus *bus, int phy, int devad, int reg)
+ {
++ int ret;
++ unsigned long flags;
+ struct mdiobb_ctrl *ctrl = bus->priv;
+
++ local_irq_save(flags);
+ mdiobb_cmd_addr(ctrl, phy, devad, reg);
+ mdiobb_cmd(ctrl, MDIO_C45_READ, phy, devad);
+
+- return mdiobb_read_common(bus, phy);
++ ret = mdiobb_read_common(bus, phy);
++ local_irq_restore(flags);
++ return ret;
+ }
+ EXPORT_SYMBOL(mdiobb_read_c45);
+
+@@ -197,22 +208,32 @@ static int mdiobb_write_common(struct mi
+
+ int mdiobb_write_c22(struct mii_bus *bus, int phy, int reg, u16 val)
+ {
++ int ret;
++ unsigned long flags;
+ struct mdiobb_ctrl *ctrl = bus->priv;
+
++ local_irq_save(flags);
+ mdiobb_cmd(ctrl, ctrl->op_c22_write, phy, reg);
+
+- return mdiobb_write_common(bus, val);
++ ret = mdiobb_write_common(bus, val);
++ local_irq_restore(flags);
++ return ret;
+ }
+ EXPORT_SYMBOL(mdiobb_write_c22);
+
+ int mdiobb_write_c45(struct mii_bus *bus, int phy, int devad, int reg, u16 val)
+ {
++ int ret;
++ unsigned long flags;
+ struct mdiobb_ctrl *ctrl = bus->priv;
+
++ local_irq_save(flags);
+ mdiobb_cmd_addr(ctrl, phy, devad, reg);
+ mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, devad);
+
+- return mdiobb_write_common(bus, val);
++ ret = mdiobb_write_common(bus, val);
++ local_irq_restore(flags);
++ return ret;
+ }
+ EXPORT_SYMBOL(mdiobb_write_c45);
+
--- /dev/null
+From b3797d1a92afe97c173b00fdb7824cedba24eef0 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Sun, 20 Sep 2020 01:00:45 +0800
+Subject: [PATCH] ath79: ar8216: make switch register access atomic
+
+due to some unknown reason these register accesses sometimes fail
+on the integrated switch without this patch.
+
+THIS ONLY WORKS ON ATH79 AND MAY BREAK THE DRIVER ON OTHER PLATFORMS!
+The mdio bus on ath79 works in polling mode and doesn't rely on
+any interrupt. This patch breaks the driver on any mdio master
+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
+ u32
+ ar8xxx_read(struct ar8xxx_priv *priv, int reg)
+ {
++ unsigned long flags;
+ struct mii_bus *bus = priv->mii_bus;
+ u16 r1, r2, page;
+ u32 val;
+@@ -259,11 +260,13 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
+ split_addr((u32) reg, &r1, &r2, &page);
+
+ mutex_lock(&bus->mdio_lock);
++ local_irq_save(flags);
+
+ bus->write(bus, 0x18, 0, page);
+ wait_for_page_switch();
+ val = ar8xxx_mii_read32(priv, 0x10 | r2, r1);
+
++ local_irq_restore(flags);
+ mutex_unlock(&bus->mdio_lock);
+
+ return val;
+@@ -272,17 +275,20 @@ ar8xxx_read(struct ar8xxx_priv *priv, in
+ void
+ ar8xxx_write(struct ar8xxx_priv *priv, int reg, u32 val)
+ {
++ unsigned long flags;
+ struct mii_bus *bus = priv->mii_bus;
+ u16 r1, r2, page;
+
+ split_addr((u32) reg, &r1, &r2, &page);
+
+ mutex_lock(&bus->mdio_lock);
++ local_irq_save(flags);
+
+ bus->write(bus, 0x18, 0, page);
+ wait_for_page_switch();
+ ar8xxx_mii_write32(priv, 0x10 | r2, r1, val);
+
++ local_irq_restore(flags);
+ mutex_unlock(&bus->mdio_lock);
+ }
+
--- /dev/null
+From ecbd9c87f073f097d9fe56390353e64e963e866a Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Tue, 6 Mar 2018 10:03:03 +0100
+Subject: [PATCH 03/27] leds: add reset-controller based driver
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/leds/Kconfig | 11 ++++
+ drivers/leds/Makefile | 1 +
+ drivers/leds/leds-reset.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 149 insertions(+)
+ create mode 100644 drivers/leds/leds-reset.c
+
+--- a/drivers/leds/Kconfig
++++ b/drivers/leds/Kconfig
+@@ -901,6 +901,17 @@ source "drivers/leds/flash/Kconfig"
+ comment "RGB LED drivers"
+ source "drivers/leds/rgb/Kconfig"
+
++config LEDS_RESET
++ tristate "LED support for reset-controller API"
++ depends on LEDS_CLASS
++ depends on RESET_CONTROLLER
++ help
++ This option enables support for LEDs connected to pins driven by reset
++ controllers. Yes, DNI actual built HW like that.
++
++ To compile this driver as a module, choose M here: the module
++ will be called leds-reset.
++
+ comment "LED Triggers"
+ source "drivers/leds/trigger/Kconfig"
+
+--- /dev/null
++++ b/drivers/leds/leds-reset.c
+@@ -0,0 +1,140 @@
++/*
++ * Copyright (C) 2018 John Crispin <john@phrozen.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/err.h>
++#include <linux/reset.h>
++#include <linux/kernel.h>
++#include <linux/leds.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/reset.h>
++
++struct reset_led_data {
++ struct led_classdev cdev;
++ struct reset_control *rst;
++};
++
++static inline struct reset_led_data *
++ cdev_to_reset_led_data(struct led_classdev *led_cdev)
++{
++ return container_of(led_cdev, struct reset_led_data, cdev);
++}
++
++static void reset_led_set(struct led_classdev *led_cdev,
++ enum led_brightness value)
++{
++ struct reset_led_data *led_dat = cdev_to_reset_led_data(led_cdev);
++
++ if (value == LED_OFF)
++ reset_control_assert(led_dat->rst);
++ else
++ reset_control_deassert(led_dat->rst);
++}
++
++struct reset_leds_priv {
++ int num_leds;
++ struct reset_led_data leds[];
++};
++
++static inline int sizeof_reset_leds_priv(int num_leds)
++{
++ return sizeof(struct reset_leds_priv) +
++ (sizeof(struct reset_led_data) * num_leds);
++}
++
++static struct reset_leds_priv *reset_leds_create(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct fwnode_handle *child;
++ struct reset_leds_priv *priv;
++ int count, ret;
++
++ count = device_get_child_node_count(dev);
++ if (!count)
++ return ERR_PTR(-ENODEV);
++
++ priv = devm_kzalloc(dev, sizeof_reset_leds_priv(count), GFP_KERNEL);
++ if (!priv)
++ return ERR_PTR(-ENOMEM);
++
++ device_for_each_child_node(dev, child) {
++ struct reset_led_data *led = &priv->leds[priv->num_leds];
++ struct device_node *np = to_of_node(child);
++
++ ret = fwnode_property_read_string(child, "label", &led->cdev.name);
++ if (!led->cdev.name) {
++ fwnode_handle_put(child);
++ return ERR_PTR(-EINVAL);
++ }
++ led->rst = __of_reset_control_get(np, NULL, 0, 0, 0, true);
++ if (IS_ERR(led->rst))
++ return ERR_PTR(-EINVAL);
++
++ fwnode_property_read_string(child, "linux,default-trigger",
++ &led->cdev.default_trigger);
++
++ led->cdev.brightness_set = reset_led_set;
++ ret = devm_led_classdev_register(&pdev->dev, &led->cdev);
++ if (ret < 0)
++ return ERR_PTR(ret);
++ led->cdev.dev->of_node = np;
++ priv->num_leds++;
++ }
++
++ return priv;
++}
++
++static const struct of_device_id of_reset_leds_match[] = {
++ { .compatible = "reset-leds", },
++ {},
++};
++
++MODULE_DEVICE_TABLE(of, of_reset_leds_match);
++
++static int reset_led_probe(struct platform_device *pdev)
++{
++ struct reset_leds_priv *priv;
++
++ priv = reset_leds_create(pdev);
++ if (IS_ERR(priv))
++ return PTR_ERR(priv);
++
++ platform_set_drvdata(pdev, priv);
++
++ return 0;
++}
++
++static void reset_led_shutdown(struct platform_device *pdev)
++{
++ struct reset_leds_priv *priv = platform_get_drvdata(pdev);
++ int i;
++
++ for (i = 0; i < priv->num_leds; i++) {
++ struct reset_led_data *led = &priv->leds[i];
++
++ if (!(led->cdev.flags & LED_RETAIN_AT_SHUTDOWN))
++ reset_led_set(&led->cdev, LED_OFF);
++ }
++}
++
++static struct platform_driver reset_led_driver = {
++ .probe = reset_led_probe,
++ .shutdown = reset_led_shutdown,
++ .driver = {
++ .name = "leds-reset",
++ .of_match_table = of_reset_leds_match,
++ },
++};
++
++module_platform_driver(reset_led_driver);
++
++MODULE_AUTHOR("John Crispin <john@phrozen.org>");
++MODULE_DESCRIPTION("reset controller LED driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:leds-reset");
+--- a/drivers/leds/Makefile
++++ b/drivers/leds/Makefile
+@@ -88,6 +88,7 @@ obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds
+ obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
+ obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
+ obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
++obj-$(CONFIG_LEDS_RESET) += leds-reset.o
+
+ # LED SPI Drivers
+ obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o
--- /dev/null
+From: Shiji Yang <yangshiji66@outlook.com>
+Date: Wed, 31 May 2023 00:15:23 +0000
+Subject: [PATCH] ath79: ignore the abused interrupt-map on pcie node
+
+ath79 PCIe interrupt controller has stopped working correctly. This
+is because the DT exposing a non-sensical interrupt-map property,
+and their drivers relying on the kernel ignoring this property[1].
+
+This patch fix the pcie init error:
+ath9k 0000:00:00.0: of_irq_parse_pci: failed with rc=-14
+
+Notice:
+This is just a workaround, not a fix. PCIe driver and related dts
+node need to be rewritten.
+
+[1] https://lore.kernel.org/all/20211201114102.13446-1-maz@kernel.org/
+
+Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
+---
+ drivers/of/irq.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -86,6 +86,8 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
+ * drawing board.
+ */
+ static const char * const of_irq_imap_abusers[] = {
++ "qca,ar7100-pci",
++ "qcom,ar7240-pci",
+ "CBEA,platform-spider-pic",
+ "sti,platform-spider-pic",
+ "realtek,rtl-intc",
--- /dev/null
+From: Shiji Yang <yangshiji66@outlook.com>
+Date: Wed, 13 Mar 2024 22:36:31 +0800
+Subject: [PATCH] mfd: syscon: support skip reset control for syscon devices
+
+Some platform device drivers(e.g. ag71xx) expect exclusive reset
+control. Fetching reset controller for syscon[1] will break these
+drivers. This patch introduces a new property 'syscon-no-reset'
+to skip it.
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit?id=7d1e3bd94828ad9fc86f55253cd6fec8edd65394
+
+Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
+---
+ drivers/mfd/syscon.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/mfd/syscon.c
++++ b/drivers/mfd/syscon.c
+@@ -52,7 +52,7 @@ static struct syscon *of_syscon_register
+ int ret;
+ struct regmap_config syscon_config = syscon_regmap_config;
+ struct resource res;
+- struct reset_control *reset;
++ struct reset_control *reset = NULL;
+
+ syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
+ if (!syscon)
+@@ -134,7 +134,8 @@ static struct syscon *of_syscon_register
+ goto err_attach_clk;
+ }
+
+- reset = of_reset_control_get_optional_exclusive(np, NULL);
++ if (!of_property_read_bool(np, "syscon-no-reset"))
++ reset = of_reset_control_get_optional_exclusive(np, NULL);
+ if (IS_ERR(reset)) {
+ ret = PTR_ERR(reset);
+ goto err_attach_clk;
--- /dev/null
+From: Felix Fietkau <nbd@openwrt.org>
+Subject: [PATCH] ar71xx: fix unaligned access in a few more places
+
+SVN-Revision: 35130
+---
+ arch/mips/include/asm/checksum.h | 83 +++---------------
+ include/uapi/linux/ip.h | 2 +-
+ include/uapi/linux/ipv6.h | 2 +-
+ include/uapi/linux/tcp.h | 4 ++--
+ include/uapi/linux/udp.h | 2 +-
+ net/netfilter/nf_conntrack_core.c | 4 ++--
+ include/uapi/linux/icmp.h | 2 +-
+ include/uapi/linux/in6.h | 2 +-
+ net/ipv6/tcp_ipv6.c | 9 +++--
+ net/ipv6/datagram.c | 6 ++--
+ net/ipv6/exthdrs.c | 2 +-
+ include/linux/types.h | 5 +++
+ net/ipv4/af_inet.c | 4 ++--
+ net/ipv4/tcp_output.c | 69 +++++++++--------
+ include/uapi/linux/igmp.h | 8 +++---
+ net/core/flow_dissector.c | 2 +-
+ include/uapi/linux/icmpv6.h | 2 +-
+ include/net/ndisc.h | 10 ++++----
+ net/sched/cls_u32.c | 6 +++---
+ net/ipv6/ip6_offload.c | 2 +-
+ include/net/addrconf.h | 2 +-
+ include/net/inet_ecn.h | 4 ++--
+ include/net/ipv6.h | 23 +++++----
+ include/net/secure_seq.h | 1 +
+ include/uapi/linux/in.h | 2 +-
+ net/ipv6/ip6_fib.h | 2 +-
+ net/netfilter/nf_conntrack_proto_tcp.c | 2 +-
+ net/xfrm/xfrm_input.c | 4 ++--
+ net/ipv4/tcp_input.c | 12 ++++---
+ include/uapi/linux/if_pppox.h | 1 +
+ net/ipv6/netfilter/nf_log_ipv6.c | 4 ++--
+ include/net/neighbour.h | 6 +++--
+ include/uapi/linux/netfilter_arp/arp_tables.h | 2 +-
+ net/core/utils.c | 10 +++++--
+ include/linux/etherdevice.h | 11 ++++---
+ net/ipv4/tcp_offload.c | 6 +++---
+ net/ipv6/netfilter/ip6table_mangle.c | 4 ++--
+ 37 file changed, 171 insertions(+), 141 deletions(-)
+
+--- a/arch/mips/include/asm/checksum.h
++++ b/arch/mips/include/asm/checksum.h
+@@ -100,26 +100,30 @@ static inline __sum16 ip_fast_csum(const
+ const unsigned int *stop = word + ihl;
+ unsigned int csum;
+ int carry;
++ unsigned int w;
+
+- csum = word[0];
+- csum += word[1];
+- carry = (csum < word[1]);
++ csum = net_hdr_word(word++);
++
++ w = net_hdr_word(word++);
++ csum += w;
++ carry = (csum < w);
+ csum += carry;
+
+- csum += word[2];
+- carry = (csum < word[2]);
++ w = net_hdr_word(word++);
++ csum += w;
++ carry = (csum < w);
+ csum += carry;
+
+- csum += word[3];
+- carry = (csum < word[3]);
++ w = net_hdr_word(word++);
++ csum += w;
++ carry = (csum < w);
+ csum += carry;
+
+- word += 4;
+ do {
+- csum += *word;
+- carry = (csum < *word);
++ w = net_hdr_word(word++);
++ csum += w;
++ carry = (csum < w);
+ csum += carry;
+- word++;
+ } while (word != stop);
+
+ return csum_fold(csum);
+@@ -179,74 +183,6 @@ static inline __sum16 ip_compute_csum(co
+ return csum_fold(csum_partial(buff, len, 0));
+ }
+
+-#define _HAVE_ARCH_IPV6_CSUM
+-static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+- const struct in6_addr *daddr,
+- __u32 len, __u8 proto,
+- __wsum sum)
+-{
+- __wsum tmp;
+-
+- __asm__(
+- " .set push # csum_ipv6_magic\n"
+- " .set noreorder \n"
+- " .set noat \n"
+- " addu %0, %5 # proto (long in network byte order)\n"
+- " sltu $1, %0, %5 \n"
+- " addu %0, $1 \n"
+-
+- " addu %0, %6 # csum\n"
+- " sltu $1, %0, %6 \n"
+- " lw %1, 0(%2) # four words source address\n"
+- " addu %0, $1 \n"
+- " addu %0, %1 \n"
+- " sltu $1, %0, %1 \n"
+-
+- " lw %1, 4(%2) \n"
+- " addu %0, $1 \n"
+- " addu %0, %1 \n"
+- " sltu $1, %0, %1 \n"
+-
+- " lw %1, 8(%2) \n"
+- " addu %0, $1 \n"
+- " addu %0, %1 \n"
+- " sltu $1, %0, %1 \n"
+-
+- " lw %1, 12(%2) \n"
+- " addu %0, $1 \n"
+- " addu %0, %1 \n"
+- " sltu $1, %0, %1 \n"
+-
+- " lw %1, 0(%3) \n"
+- " addu %0, $1 \n"
+- " addu %0, %1 \n"
+- " sltu $1, %0, %1 \n"
+-
+- " lw %1, 4(%3) \n"
+- " addu %0, $1 \n"
+- " addu %0, %1 \n"
+- " sltu $1, %0, %1 \n"
+-
+- " lw %1, 8(%3) \n"
+- " addu %0, $1 \n"
+- " addu %0, %1 \n"
+- " sltu $1, %0, %1 \n"
+-
+- " lw %1, 12(%3) \n"
+- " addu %0, $1 \n"
+- " addu %0, %1 \n"
+- " sltu $1, %0, %1 \n"
+-
+- " addu %0, $1 # Add final carry\n"
+- " .set pop"
+- : "=&r" (sum), "=&r" (tmp)
+- : "r" (saddr), "r" (daddr),
+- "0" (htonl(len)), "r" (htonl(proto)), "r" (sum)
+- : "memory");
+-
+- return csum_fold(sum);
+-}
+-
+ #include <asm-generic/checksum.h>
+ #endif /* CONFIG_GENERIC_CSUM */
+
+--- a/include/uapi/linux/ip.h
++++ b/include/uapi/linux/ip.h
+@@ -106,7 +106,7 @@ struct iphdr {
+ __be32 daddr;
+ );
+ /*The options start here. */
+-};
++} __attribute__((packed, aligned(2)));
+
+
+ struct ip_auth_hdr {
+--- a/include/uapi/linux/ipv6.h
++++ b/include/uapi/linux/ipv6.h
+@@ -135,7 +135,7 @@ struct ipv6hdr {
+ struct in6_addr saddr;
+ struct in6_addr daddr;
+ );
+-};
++} __attribute__((packed, aligned(2)));
+
+
+ /* index values for the variables in ipv6_devconf */
+--- a/include/uapi/linux/tcp.h
++++ b/include/uapi/linux/tcp.h
+@@ -55,7 +55,7 @@ struct tcphdr {
+ __be16 window;
+ __sum16 check;
+ __be16 urg_ptr;
+-};
++} __attribute__((packed, aligned(2)));
+
+ /*
+ * The union cast uses a gcc extension to avoid aliasing problems
+@@ -65,7 +65,7 @@ struct tcphdr {
+ union tcp_word_hdr {
+ struct tcphdr hdr;
+ __be32 words[5];
+-};
++} __attribute__((packed, aligned(2)));
+
+ #define tcp_flag_word(tp) (((union tcp_word_hdr *)(tp))->words[3])
+
+--- a/include/uapi/linux/udp.h
++++ b/include/uapi/linux/udp.h
+@@ -25,7 +25,7 @@ struct udphdr {
+ __be16 dest;
+ __be16 len;
+ __sum16 check;
+-};
++} __attribute__((packed, aligned(2)));
+
+ /* UDP socket options */
+ #define UDP_CORK 1 /* Never send partially complete segments */
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -298,8 +298,8 @@ nf_ct_get_tuple(const struct sk_buff *sk
+
+ switch (l3num) {
+ case NFPROTO_IPV4:
+- tuple->src.u3.ip = ap[0];
+- tuple->dst.u3.ip = ap[1];
++ tuple->src.u3.ip = net_hdr_word(ap++);
++ tuple->dst.u3.ip = net_hdr_word(ap);
+ break;
+ case NFPROTO_IPV6:
+ memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6));
+--- a/include/uapi/linux/icmp.h
++++ b/include/uapi/linux/icmp.h
+@@ -102,7 +102,7 @@ struct icmphdr {
+ } frag;
+ __u8 reserved[4];
+ } un;
+-};
++} __attribute__((packed, aligned(2)));
+
+
+ /*
+--- a/include/uapi/linux/in6.h
++++ b/include/uapi/linux/in6.h
+@@ -43,7 +43,7 @@ struct in6_addr {
+ #define s6_addr16 in6_u.u6_addr16
+ #define s6_addr32 in6_u.u6_addr32
+ #endif
+-};
++} __attribute__((packed, aligned(2)));
+ #endif /* __UAPI_DEF_IN6_ADDR */
+
+ #if __UAPI_DEF_SOCKADDR_IN6
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -35,6 +35,7 @@
+ #include <linux/ipsec.h>
+ #include <linux/times.h>
+ #include <linux/slab.h>
++#include <asm/unaligned.h>
+ #include <linux/uaccess.h>
+ #include <linux/ipv6.h>
+ #include <linux/icmpv6.h>
+@@ -897,10 +898,10 @@ static void tcp_v6_send_response(const s
+ topt = (__be32 *)(t1 + 1);
+
+ if (tsecr) {
+- *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+- (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+- *topt++ = htonl(tsval);
+- *topt++ = htonl(tsecr);
++ put_unaligned_be32((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
++ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP, topt++);
++ put_unaligned_be32(tsval, topt++);
++ put_unaligned_be32(tsecr, topt++);
+ }
+
+ if (mrst)
+--- a/include/linux/ipv6.h
++++ b/include/linux/ipv6.h
+@@ -6,6 +6,7 @@
+
+ #define ipv6_optlen(p) (((p)->hdrlen+1) << 3)
+ #define ipv6_authlen(p) (((p)->hdrlen+2) << 2)
++
+ /*
+ * This structure contains configuration options per IPv6 link.
+ */
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -499,7 +499,7 @@ int ipv6_recv_error(struct sock *sk, str
+ ipv6_iface_scope_id(&sin->sin6_addr,
+ IP6CB(skb)->iif);
+ } else {
+- ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),
++ ipv6_addr_set_v4mapped(net_hdr_word(nh + serr->addr_offset),
+ &sin->sin6_addr);
+ sin->sin6_scope_id = 0;
+ }
+@@ -853,12 +853,12 @@ int ip6_datagram_send_ctl(struct net *ne
+ }
+
+ if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
+- if ((fl6->flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
++ if ((fl6->flowlabel^net_hdr_word(CMSG_DATA(cmsg)))&~IPV6_FLOWINFO_MASK) {
+ err = -EINVAL;
+ goto exit_f;
+ }
+ }
+- fl6->flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
++ fl6->flowlabel = IPV6_FLOWINFO_MASK & net_hdr_word(CMSG_DATA(cmsg));
+ break;
+
+ case IPV6_2292HOPOPTS:
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -982,7 +982,7 @@ static bool ipv6_hop_jumbo(struct sk_buf
+ goto drop;
+ }
+
+- pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
++ pkt_len = ntohl(net_hdr_word(nh + optoff + 2));
+ if (pkt_len <= IPV6_MAXPLEN) {
+ icmpv6_param_prob_reason(skb, ICMPV6_HDR_FIELD, optoff + 2,
+ SKB_DROP_REASON_IP_INHDR);
+--- a/include/linux/types.h
++++ b/include/linux/types.h
+@@ -244,5 +244,11 @@ typedef void (*swap_func_t)(void *a, voi
+ typedef int (*cmp_r_func_t)(const void *a, const void *b, const void *priv);
+ typedef int (*cmp_func_t)(const void *a, const void *b);
+
++struct net_hdr_word {
++ u32 words[1];
++} __attribute__((packed, aligned(2)));
++
++#define net_hdr_word(_p) (((struct net_hdr_word *) (_p))->words[0])
++
+ #endif /* __ASSEMBLY__ */
+ #endif /* _LINUX_TYPES_H */
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -1506,8 +1506,8 @@ struct sk_buff *inet_gro_receive(struct
+ goto out;
+
+ NAPI_GRO_CB(skb)->proto = proto;
+- id = ntohl(*(__be32 *)&iph->id);
+- flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id & ~IP_DF));
++ id = ntohl(net_hdr_word(&iph->id));
++ flush = (u16)((ntohl(net_hdr_word(iph)) ^ skb_gro_len(skb)) | (id & ~IP_DF));
+ id >>= 16;
+
+ 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
+ u16 options = opts->options; /* mungable copy */
+
+ if (unlikely(OPTION_MD5 & options)) {
+- *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+- (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
++ net_hdr_word(ptr++) =
++ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
++ (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
+ /* overload cookie hash location */
+ opts->hash_location = (__u8 *)ptr;
+ ptr += 4;
+ }
+
+ if (unlikely(opts->mss)) {
+- *ptr++ = htonl((TCPOPT_MSS << 24) |
+- (TCPOLEN_MSS << 16) |
+- opts->mss);
++ net_hdr_word(ptr++) =
++ htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) |
++ opts->mss);
+ }
+
+ if (likely(OPTION_TS & options)) {
+ if (unlikely(OPTION_SACK_ADVERTISE & options)) {
+- *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
+- (TCPOLEN_SACK_PERM << 16) |
+- (TCPOPT_TIMESTAMP << 8) |
+- TCPOLEN_TIMESTAMP);
++ net_hdr_word(ptr++) =
++ htonl((TCPOPT_SACK_PERM << 24) |
++ (TCPOLEN_SACK_PERM << 16) |
++ (TCPOPT_TIMESTAMP << 8) |
++ TCPOLEN_TIMESTAMP);
+ options &= ~OPTION_SACK_ADVERTISE;
+ } else {
+- *ptr++ = htonl((TCPOPT_NOP << 24) |
+- (TCPOPT_NOP << 16) |
+- (TCPOPT_TIMESTAMP << 8) |
+- TCPOLEN_TIMESTAMP);
++ net_hdr_word(ptr++) =
++ htonl((TCPOPT_NOP << 24) |
++ (TCPOPT_NOP << 16) |
++ (TCPOPT_TIMESTAMP << 8) |
++ TCPOLEN_TIMESTAMP);
+ }
+- *ptr++ = htonl(opts->tsval);
+- *ptr++ = htonl(opts->tsecr);
++ net_hdr_word(ptr++) = htonl(opts->tsval);
++ net_hdr_word(ptr++) = htonl(opts->tsecr);
+ }
+
+ if (unlikely(OPTION_SACK_ADVERTISE & options)) {
+- *ptr++ = htonl((TCPOPT_NOP << 24) |
+- (TCPOPT_NOP << 16) |
+- (TCPOPT_SACK_PERM << 8) |
+- TCPOLEN_SACK_PERM);
++ net_hdr_word(ptr++) =
++ htonl((TCPOPT_NOP << 24) |
++ (TCPOPT_NOP << 16) |
++ (TCPOPT_SACK_PERM << 8) |
++ TCPOLEN_SACK_PERM);
+ }
+
+ if (unlikely(OPTION_WSCALE & options)) {
+- *ptr++ = htonl((TCPOPT_NOP << 24) |
+- (TCPOPT_WINDOW << 16) |
+- (TCPOLEN_WINDOW << 8) |
+- opts->ws);
++ net_hdr_word(ptr++) =
++ htonl((TCPOPT_NOP << 24) |
++ (TCPOPT_WINDOW << 16) |
++ (TCPOLEN_WINDOW << 8) |
++ opts->ws);
+ }
+
+ if (unlikely(opts->num_sack_blocks)) {
+@@ -669,16 +674,17 @@ static void tcp_options_write(struct tcp
+ tp->duplicate_sack : tp->selective_acks;
+ int this_sack;
+
+- *ptr++ = htonl((TCPOPT_NOP << 24) |
+- (TCPOPT_NOP << 16) |
+- (TCPOPT_SACK << 8) |
+- (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
++ net_hdr_word(ptr++) =
++ htonl((TCPOPT_NOP << 24) |
++ (TCPOPT_NOP << 16) |
++ (TCPOPT_SACK << 8) |
++ (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
+ TCPOLEN_SACK_PERBLOCK)));
+
+ for (this_sack = 0; this_sack < opts->num_sack_blocks;
+ ++this_sack) {
+- *ptr++ = htonl(sp[this_sack].start_seq);
+- *ptr++ = htonl(sp[this_sack].end_seq);
++ net_hdr_word(ptr++) = htonl(sp[this_sack].start_seq);
++ net_hdr_word(ptr++) = htonl(sp[this_sack].end_seq);
+ }
+
+ tp->rx_opt.dsack = 0;
+@@ -691,13 +697,14 @@ static void tcp_options_write(struct tcp
+
+ if (foc->exp) {
+ len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
+- *ptr = htonl((TCPOPT_EXP << 24) | (len << 16) |
++ net_hdr_word(ptr) =
++ htonl((TCPOPT_EXP << 24) | (len << 16) |
+ TCPOPT_FASTOPEN_MAGIC);
+ p += TCPOLEN_EXP_FASTOPEN_BASE;
+ } else {
+ len = TCPOLEN_FASTOPEN_BASE + foc->len;
+- *p++ = TCPOPT_FASTOPEN;
+- *p++ = len;
++ net_hdr_word(p++) = TCPOPT_FASTOPEN;
++ net_hdr_word(p++) = len;
+ }
+
+ memcpy(p, foc->val, foc->len);
+--- a/include/uapi/linux/igmp.h
++++ b/include/uapi/linux/igmp.h
+@@ -33,7 +33,7 @@ struct igmphdr {
+ __u8 code; /* For newer IGMP */
+ __sum16 csum;
+ __be32 group;
+-};
++} __attribute__((packed, aligned(2)));
+
+ /* V3 group record types [grec_type] */
+ #define IGMPV3_MODE_IS_INCLUDE 1
+@@ -49,7 +49,7 @@ struct igmpv3_grec {
+ __be16 grec_nsrcs;
+ __be32 grec_mca;
+ __be32 grec_src[];
+-};
++} __attribute__((packed, aligned(2)));
+
+ struct igmpv3_report {
+ __u8 type;
+@@ -58,7 +58,7 @@ struct igmpv3_report {
+ __be16 resv2;
+ __be16 ngrec;
+ struct igmpv3_grec grec[];
+-};
++} __attribute__((packed, aligned(2)));
+
+ struct igmpv3_query {
+ __u8 type;
+@@ -79,7 +79,7 @@ struct igmpv3_query {
+ __u8 qqic;
+ __be16 nsrcs;
+ __be32 srcs[];
+-};
++} __attribute__((packed, aligned(2)));
+
+ #define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */
+ #define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -132,7 +132,7 @@ __be32 __skb_flow_get_ports(const struct
+ ports = __skb_header_pointer(skb, thoff + poff,
+ sizeof(_ports), data, hlen, &_ports);
+ if (ports)
+- return *ports;
++ return (__be32)net_hdr_word(ports);
+ }
+
+ return 0;
+--- a/include/uapi/linux/icmpv6.h
++++ b/include/uapi/linux/icmpv6.h
+@@ -78,7 +78,7 @@ struct icmp6hdr {
+ #define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other
+ #define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime
+ #define icmp6_router_pref icmp6_dataun.u_nd_ra.router_pref
+-};
++} __attribute__((packed, aligned(2)));
+
+
+ #define ICMPV6_ROUTER_PREF_LOW 0x3
+--- a/include/net/ndisc.h
++++ b/include/net/ndisc.h
+@@ -93,7 +93,7 @@ struct ra_msg {
+ struct icmp6hdr icmph;
+ __be32 reachable_time;
+ __be32 retrans_timer;
+-};
++} __attribute__((packed, aligned(2)));
+
+ struct rd_msg {
+ struct icmp6hdr icmph;
+@@ -372,10 +372,10 @@ static inline u32 ndisc_hashfn(const voi
+ {
+ const u32 *p32 = pkey;
+
+- return (((p32[0] ^ hash32_ptr(dev)) * hash_rnd[0]) +
+- (p32[1] * hash_rnd[1]) +
+- (p32[2] * hash_rnd[2]) +
+- (p32[3] * hash_rnd[3]));
++ return (((net_hdr_word(&p32[0]) ^ hash32_ptr(dev)) * hash_rnd[0]) +
++ (net_hdr_word(&p32[1]) * hash_rnd[1]) +
++ (net_hdr_word(&p32[2]) * hash_rnd[2]) +
++ (net_hdr_word(&p32[3]) * hash_rnd[3]));
+ }
+
+ static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
+--- a/net/sched/cls_u32.c
++++ b/net/sched/cls_u32.c
+@@ -157,7 +157,7 @@ next_knode:
+ data = skb_header_pointer(skb, toff, 4, &hdata);
+ if (!data)
+ goto out;
+- if ((*data ^ key->val) & key->mask) {
++ if ((net_hdr_word(data) ^ key->val) & key->mask) {
+ n = rcu_dereference_bh(n->next);
+ goto next_knode;
+ }
+@@ -208,8 +208,8 @@ check_terminal:
+ &hdata);
+ if (!data)
+ goto out;
+- sel = ht->divisor & u32_hash_fold(*data, &n->sel,
+- n->fshift);
++ sel = ht->divisor & u32_hash_fold(net_hdr_word(data),
++ &n->sel, n->fshift);
+ }
+ if (!(n->sel.flags & (TC_U32_VAROFFSET | TC_U32_OFFSET | TC_U32_EAT)))
+ goto next_ht;
+--- a/net/ipv6/ip6_offload.c
++++ b/net/ipv6/ip6_offload.c
+@@ -273,7 +273,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *
+ continue;
+
+ iph2 = (struct ipv6hdr *)(p->data + off);
+- first_word = *(__be32 *)iph ^ *(__be32 *)iph2;
++ first_word = net_hdr_word(iph) ^ net_hdr_word(iph2);
+
+ /* All fields must match except length and Traffic Class.
+ * XXX skbs on the gro_list have all been parsed and pulled
+--- a/include/net/addrconf.h
++++ b/include/net/addrconf.h
+@@ -52,7 +52,7 @@ struct prefix_info {
+ __be32 reserved2;
+
+ struct in6_addr prefix;
+-};
++} __attribute__((packed, aligned(2)));
+
+ /* rfc4861 4.6.2: IPv6 PIO is 32 bytes in size */
+ static_assert(sizeof(struct prefix_info) == 32);
+--- a/include/net/inet_ecn.h
++++ b/include/net/inet_ecn.h
+@@ -138,9 +138,9 @@ static inline int IP6_ECN_set_ce(struct
+ if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
+ return 0;
+
+- from = *(__be32 *)iph;
++ from = net_hdr_word(iph);
+ to = from | htonl(INET_ECN_CE << 20);
+- *(__be32 *)iph = to;
++ net_hdr_word(iph) = to;
+ if (skb->ip_summed == CHECKSUM_COMPLETE)
+ skb->csum = csum_add(csum_sub(skb->csum, (__force __wsum)from),
+ (__force __wsum)to);
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -149,7 +149,7 @@ struct frag_hdr {
+ __u8 reserved;
+ __be16 frag_off;
+ __be32 identification;
+-};
++} __attribute__((packed, aligned(2)));
+
+ /*
+ * Jumbo payload option, as described in RFC 2675 2.
+@@ -649,8 +649,8 @@ static inline void __ipv6_addr_set_half(
+ }
+ #endif
+ #endif
+- addr[0] = wh;
+- addr[1] = wl;
++ net_hdr_word(&addr[0]) = wh;
++ net_hdr_word(&addr[1]) = wl;
+ }
+
+ static inline void ipv6_addr_set(struct in6_addr *addr,
+@@ -709,6 +709,8 @@ static inline bool ipv6_prefix_equal(con
+ const __be32 *a1 = addr1->s6_addr32;
+ const __be32 *a2 = addr2->s6_addr32;
+ unsigned int pdw, pbi;
++ /* Used for last <32-bit fraction of prefix */
++ u32 pbia1, pbia2;
+
+ /* check complete u32 in prefix */
+ pdw = prefixlen >> 5;
+@@ -717,7 +719,9 @@ static inline bool ipv6_prefix_equal(con
+
+ /* check incomplete u32 in prefix */
+ pbi = prefixlen & 0x1f;
+- if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi))))
++ pbia1 = net_hdr_word(&a1[pdw]);
++ pbia2 = net_hdr_word(&a2[pdw]);
++ if (pbi && ((pbia1 ^ pbia2) & htonl((0xffffffff) << (32 - pbi))))
+ return false;
+
+ return true;
+@@ -839,13 +843,13 @@ static inline void ipv6_addr_set_v4mappe
+ */
+ static inline int __ipv6_addr_diff32(const void *token1, const void *token2, int addrlen)
+ {
+- const __be32 *a1 = token1, *a2 = token2;
++ const struct in6_addr *a1 = token1, *a2 = token2;
+ int i;
+
+ addrlen >>= 2;
+
+ for (i = 0; i < addrlen; i++) {
+- __be32 xb = a1[i] ^ a2[i];
++ __be32 xb = a1->s6_addr32[i] ^ a2->s6_addr32[i];
+ if (xb)
+ return i * 32 + 31 - __fls(ntohl(xb));
+ }
+@@ -1040,17 +1044,18 @@ static inline u32 ip6_multipath_hash_fie
+ static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass,
+ __be32 flowlabel)
+ {
+- *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | flowlabel;
++ net_hdr_word((__be32 *)hdr) =
++ htonl(0x60000000 | (tclass << 20)) | flowlabel;
+ }
+
+ static inline __be32 ip6_flowinfo(const struct ipv6hdr *hdr)
+ {
+- return *(__be32 *)hdr & IPV6_FLOWINFO_MASK;
++ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWINFO_MASK;
+ }
+
+ static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr)
+ {
+- return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK;
++ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWLABEL_MASK;
+ }
+
+ static inline u8 ip6_tclass(__be32 flowinfo)
+--- a/include/net/secure_seq.h
++++ b/include/net/secure_seq.h
+@@ -3,6 +3,7 @@
+ #define _NET_SECURE_SEQ
+
+ #include <linux/types.h>
++#include <linux/in6.h>
+
+ struct net;
+
+--- a/include/uapi/linux/in.h
++++ b/include/uapi/linux/in.h
+@@ -91,7 +91,7 @@ enum {
+ /* Internet address. */
+ struct in_addr {
+ __be32 s_addr;
+-};
++} __attribute__((packed, aligned(2)));
+ #endif
+
+ #define IP_TOS 1
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -141,7 +141,7 @@ static __be32 addr_bit_set(const void *t
+ * See include/asm-generic/bitops/le.h.
+ */
+ return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) &
+- addr[fn_bit >> 5];
++ net_hdr_word(&addr[fn_bit >> 5]);
+ }
+
+ struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh)
+--- a/net/netfilter/nf_conntrack_proto_tcp.c
++++ b/net/netfilter/nf_conntrack_proto_tcp.c
+@@ -406,7 +406,7 @@ static void tcp_sack(const struct sk_buf
+
+ /* Fast path for timestamp-only option */
+ if (length == TCPOLEN_TSTAMP_ALIGNED
+- && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
++ && net_hdr_word(ptr) == htonl((TCPOPT_NOP << 24)
+ | (TCPOPT_NOP << 16)
+ | (TCPOPT_TIMESTAMP << 8)
+ | TCPOLEN_TIMESTAMP))
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -168,8 +168,8 @@ int xfrm_parse_spi(struct sk_buff *skb,
+ if (!pskb_may_pull(skb, hlen))
+ return -EINVAL;
+
+- *spi = *(__be32 *)(skb_transport_header(skb) + offset);
+- *seq = *(__be32 *)(skb_transport_header(skb) + offset_seq);
++ *spi = net_hdr_word(skb_transport_header(skb) + offset);
++ *seq = net_hdr_word(skb_transport_header(skb) + offset_seq);
+ return 0;
+ }
+ 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(
+ {
+ const __be32 *ptr = (const __be32 *)(th + 1);
+
+- if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
+- | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
++ if (net_hdr_word(ptr) ==
++ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
++ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
+ tp->rx_opt.saw_tstamp = 1;
+ ++ptr;
+- tp->rx_opt.rcv_tsval = ntohl(*ptr);
++ tp->rx_opt.rcv_tsval = get_unaligned_be32(ptr);
+ ++ptr;
+- if (*ptr)
+- tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset;
++ if (net_hdr_word(ptr))
++ tp->rx_opt.rcv_tsecr = get_unaligned_be32(ptr) -
++ tp->tsoffset;
+ else
+ tp->rx_opt.rcv_tsecr = 0;
+ return true;
+--- a/include/uapi/linux/if_pppox.h
++++ b/include/uapi/linux/if_pppox.h
+@@ -51,6 +51,7 @@ struct pppoe_addr {
+ */
+ struct pptp_addr {
+ __u16 call_id;
++ __u16 pad;
+ struct in_addr sin_addr;
+ };
+
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -286,8 +286,10 @@ static inline bool neigh_key_eq128(const
+ const u32 *n32 = (const u32 *)n->primary_key;
+ const u32 *p32 = pkey;
+
+- return ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) |
+- (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0;
++ return ((n32[0] ^ net_hdr_word(&p32[0])) |
++ (n32[1] ^ net_hdr_word(&p32[1])) |
++ (n32[2] ^ net_hdr_word(&p32[2])) |
++ (n32[3] ^ net_hdr_word(&p32[3]))) == 0;
+ }
+
+ static inline struct neighbour *___neigh_lookup_noref(
+--- a/include/uapi/linux/netfilter_arp/arp_tables.h
++++ b/include/uapi/linux/netfilter_arp/arp_tables.h
+@@ -70,7 +70,7 @@ struct arpt_arp {
+ __u8 flags;
+ /* Inverse flags */
+ __u16 invflags;
+-};
++} __attribute__((aligned(4)));
+
+ /* Values for "flag" field in struct arpt_ip (general arp structure).
+ * No flags defined yet.
+--- a/net/core/utils.c
++++ b/net/core/utils.c
+@@ -460,8 +460,14 @@ void inet_proto_csum_replace16(__sum16 *
+ bool pseudohdr)
+ {
+ __be32 diff[] = {
+- ~from[0], ~from[1], ~from[2], ~from[3],
+- to[0], to[1], to[2], to[3],
++ ~net_hdr_word(&from[0]),
++ ~net_hdr_word(&from[1]),
++ ~net_hdr_word(&from[2]),
++ ~net_hdr_word(&from[3]),
++ net_hdr_word(&to[0]),
++ net_hdr_word(&to[1]),
++ net_hdr_word(&to[2]),
++ net_hdr_word(&to[3]),
+ };
+ if (skb->ip_summed != CHECKSUM_PARTIAL) {
+ *sum = csum_fold(csum_partial(diff, sizeof(diff),
+--- a/include/linux/etherdevice.h
++++ b/include/linux/etherdevice.h
+@@ -555,7 +555,7 @@ static inline bool is_etherdev_addr(cons
+ * @b: Pointer to Ethernet header
+ *
+ * Compare two Ethernet headers, returns 0 if equal.
+- * This assumes that the network header (i.e., IP header) is 4-byte
++ * This assumes that the network header (i.e., IP header) is 2-byte
+ * aligned OR the platform can handle unaligned access. This is the
+ * case for all packets coming into netif_receive_skb or similar
+ * entry points.
+@@ -578,11 +578,12 @@ static inline unsigned long compare_ethe
+ fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
+ return fold;
+ #else
+- u32 *a32 = (u32 *)((u8 *)a + 2);
+- u32 *b32 = (u32 *)((u8 *)b + 2);
++ const u16 *a16 = a;
++ const u16 *b16 = b;
+
+- return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
+- (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
++ return (a16[0] ^ b16[0]) | (a16[1] ^ b16[1]) | (a16[2] ^ b16[2]) |
++ (a16[3] ^ b16[3]) | (a16[4] ^ b16[4]) | (a16[5] ^ b16[5]) |
++ (a16[6] ^ b16[6]);
+ #endif
+ }
+
+--- a/net/ipv4/tcp_offload.c
++++ b/net/ipv4/tcp_offload.c
+@@ -63,7 +63,7 @@ static struct sk_buff *__tcpv4_gso_segme
+ th2 = tcp_hdr(seg->next);
+ iph2 = ip_hdr(seg->next);
+
+- if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) &&
++ if (!(net_hdr_word(&th->source) ^ net_hdr_word(&th2->source)) &&
+ iph->daddr == iph2->daddr && iph->saddr == iph2->saddr)
+ return segs;
+
+@@ -255,7 +255,7 @@ struct sk_buff *tcp_gro_lookup(struct li
+ continue;
+
+ th2 = tcp_hdr(p);
+- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
++ if (net_hdr_word(&th->source) ^ net_hdr_word(&th2->source)) {
+ NAPI_GRO_CB(p)->same_flow = 0;
+ continue;
+ }
+@@ -321,8 +321,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)
+- flush |= *(u32 *)((u8 *)th + i) ^
+- *(u32 *)((u8 *)th2 + i);
++ flush |= net_hdr_word((u8 *)th + i) ^
++ net_hdr_word((u8 *)th2 + i);
+
+ /* When we receive our second frame we can made a decision on if we
+ * continue this flow as an atomic flow with a fixed ID or if we use
+--- a/net/ipv6/netfilter/ip6table_mangle.c
++++ b/net/ipv6/netfilter/ip6table_mangle.c
+@@ -44,7 +44,7 @@ ip6t_mangle_out(void *priv, struct sk_bu
+ hop_limit = ipv6_hdr(skb)->hop_limit;
+
+ /* flowlabel and prio (includes version, which shouldn't change either */
+- flowlabel = *((u_int32_t *)ipv6_hdr(skb));
++ flowlabel = net_hdr_word(ipv6_hdr(skb));
+
+ ret = ip6t_do_table(priv, skb, state);
+
+@@ -53,7 +53,7 @@ ip6t_mangle_out(void *priv, struct sk_bu
+ !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
+ skb->mark != mark ||
+ ipv6_hdr(skb)->hop_limit != hop_limit ||
+- flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
++ flowlabel != net_hdr_word(ipv6_hdr(skb)))) {
+ err = ip6_route_me_harder(state->net, state->sk, skb);
+ if (err < 0)
+ ret = NF_DROP_ERR(err);
--- /dev/null
+From: Christopher Hill <ch6574@gmail.com>
+Subject: [PATCH] ath79: add Mikrotik rb4xx series drivers
+
+This adds 3 Mikrotik rb4xx series drivers as follows:
+
+rb4xx-cpld: This is in the mfd subsystem, and is the parent CPLD device
+that interfaces between the SoC SPI bus and its two children below.
+rb4xx-gpio: This is the GPIO expander.
+rb4xx-nand: This is the NAND driver.
+
+The history of this code comes in three phases.
+
+1. The first is a May 2015 attempt to push the equivalient ar71xx rb4xx
+drivers upstream. See https://lore.kernel.org/patchwork/patch/940880/.
+
+Module-author: Gabor Juhos <juhosg@openwrt.org>
+Module-author: Imre Kaloz <kaloz@openwrt.org>
+Module-author: Bert Vermeulen <bert@biot.com>
+
+2. Next several ar71xx patches were applied bringing the code current.
+
+commit 7bbf4117c6fe4b764d9d7c62fb2bcf6dd93bff2c
+Submitted-by: Hauke Mehrtens <hauke@hauke-m.de>
+
+commit af79fdbe4af32a287798b579141204bda056b8aa
+commit 889272d92db689fd9c910243635e44c9d8323095
+commit e21cb649a235180563363b8af5ba8296b9ac0baa
+commit 7c09fa4a7492ca436f2c94bd9a465b7c5bbeed6f
+Submitted-by: Felix Fietkau <nbd@nbd.name>
+
+3. Finally a heavy refactor to split the driver into the three new
+subsystems, and updated to work with the device tree configuration, plus
+updates and review feedback incorporated
+
+Reviewed-by: Thibaut VARÈNE <hacks@slashdirt.org>
+Submitted-by: Christopher Hill <ch6574@gmail.com>
+---
+ drivers/mfd/Kconfig | 8 ++++++++
+ drivers/mfd/Makefile | 1 +
+ drivers/gpio/Kconfig | 6 ++++++
+ drivers/gpio/Makefile | 1 +
+ drivers/mtd/nand/raw/Kconfig | 7 +++++++
+ drivers/mtd/nand/raw/Makefile | 1 +
+ 6 files changed, 24 insertions(+)
+
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -2261,6 +2261,14 @@ config RAVE_SP_CORE
+ Select this to get support for the Supervisory Processor
+ device found on several devices in RAVE line of hardware.
+
++config MFD_RB4XX_CPLD
++ tristate "CPLD driver for Mikrotik RB4xx series boards"
++ select MFD_CORE
++ depends on ATH79 || COMPILE_TEST
++ help
++ Enables support for the CPLD chip (NAND & GPIO) on Mikrotik
++ Routerboard RB4xx series.
++
+ config SGI_MFD_IOC3
+ bool "SGI IOC3 core driver"
+ depends on PCI && MIPS && 64BIT
+--- a/drivers/mfd/Makefile
++++ b/drivers/mfd/Makefile
+@@ -269,6 +269,7 @@ obj-$(CONFIG_MFD_KHADAS_MCU) += khadas-
+ obj-$(CONFIG_MFD_ACER_A500_EC) += acer-ec-a500.o
+ obj-$(CONFIG_MFD_QCOM_PM8008) += qcom-pm8008.o
+
++obj-$(CONFIG_MFD_RB4XX_CPLD) += rb4xx-cpld.o
+ obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o
+ obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o
+ obj-$(CONFIG_MFD_SMPRO) += smpro-core.o
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -1696,6 +1696,12 @@ config GPIO_SODAVILLE
+ help
+ Say Y here to support Intel Sodaville GPIO.
+
++config GPIO_RB4XX
++ tristate "GPIO expander for Mikrotik RB4xx series boards"
++ depends on MFD_RB4XX_CPLD
++ help
++ GPIO driver for Mikrotik Routerboard RB4xx series.
++
+ endmenu
+
+ menu "SPI GPIO expanders"
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -131,6 +131,7 @@ obj-$(CONFIG_GPIO_PL061) += gpio-pl061.
+ obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o
+ obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
+ obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
++obj-$(CONFIG_GPIO_RB4XX) += gpio-rb4xx.o
+ obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
+ obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
+ 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
+ Enables support for NAND controller on Qualcomm Atheros SoCs.
+ This controller is found on AR934x and QCA955x SoCs.
+
++config MTD_NAND_RB4XX
++ tristate "Support for NAND driver for Mikrotik RB4xx series boards"
++ depends on MFD_RB4XX_CPLD
++ help
++ Enables support for the NAND flash chip on Mikrotik Routerboard
++ RB4xx series.
++
+ endif # MTD_RAW_NAND
+--- a/drivers/mtd/nand/raw/Makefile
++++ b/drivers/mtd/nand/raw/Makefile
+@@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_ROCKCHIP) += rock
+ obj-$(CONFIG_MTD_NAND_PL35X) += pl35x-nand-controller.o
+ obj-$(CONFIG_MTD_NAND_RENESAS) += renesas-nand-controller.o
+ obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nand.o
++obj-$(CONFIG_MTD_NAND_RB4XX) += nand_rb4xx.o
+
+ nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
+ nand-objs += nand_onfi.o
--- /dev/null
+From: Denis Kalashnikov <denis281089@gmail.com>
+Subject: [PATCH] ath79: add support for reset key on MikroTik RB912UAG-2HPnD
+
+On MikroTik RB91x board series a reset key shares SoC gpio
+line #15 with NAND ALE and NAND IO7. So we need a custom
+gpio driver to manage this non-trivial connection schema.
+Also rb91x-nand needs to have an ability to disable a polling
+of the key while it works with NAND.
+
+While we've been integrating rb91x-key into a firmware, we've
+figured out that:
+* In the gpio-latch driver we need to add a "cansleep" suffix to
+several gpiolib calls,
+* When gpio-latch and rb91x-nand fail to get a gpio and an error
+is -EPROBE_DEFER, they shouldn't report about this, since this
+actually is not an error and occurs when the gpio-latch probe
+function is called before the rb91x-key probe.
+We fix these related things here too.
+
+Submitted-by: Denis Kalashnikov <denis281089@gmail.com>
+Reviewed-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
+Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
+---
+ drivers/gpio/Kconfig | 11 +++++++++++
+ drivers/gpio/Makefile | 2 ++
+ drivers/mtd/nand/raw/Kconfig | 6 ++++++
+ drivers/mtd/nand/raw/Makefile | 1 +
+ 7 files changed, 20 insertions(+)
+
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -371,6 +371,12 @@ config GPIO_IXP4XX
+
+ If unsure, say N.
+
++config GPIO_LATCH_MIKROTIK
++ tristate "MikroTik RouterBOARD GPIO latch support"
++ depends on ATH79
++ help
++ GPIO driver for latch on some MikroTik RouterBOARDs.
++
+ config GPIO_LOGICVC
+ tristate "Xylon LogiCVC GPIO support"
+ depends on MFD_SYSCON && OF
+@@ -553,6 +559,10 @@ config GPIO_ROCKCHIP
+ help
+ Say yes here to support GPIO on Rockchip SoCs.
+
++config GPIO_RB91X_KEY
++ tristate "MikroTik RB91x board series reset key support"
++ depends on ATH79
++
+ config GPIO_SAMA5D2_PIOBU
+ tristate "SAMA5D2 PIOBU GPIO support"
+ depends on MFD_SYSCON
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -81,6 +81,7 @@ obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4x
+ obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
+ obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
+ obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o
++obj-$(CONFIG_GPIO_LATCH_MIKROTIK) += gpio-latch-mikrotik.o
+ obj-$(CONFIG_GPIO_LJCA) += gpio-ljca.o
+ obj-$(CONFIG_GPIO_LOGICVC) += gpio-logicvc.o
+ obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
+@@ -132,6 +133,7 @@ obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio
+ obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
+ obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
+ obj-$(CONFIG_GPIO_RB4XX) += gpio-rb4xx.o
++obj-$(CONFIG_GPIO_RB91X_KEY) += gpio-rb91x-key.o
+ obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
+ obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
+ 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
+ Enables support for the NAND flash chip on Mikrotik Routerboard
+ RB4xx series.
+
++config MTD_NAND_RB91X
++ tristate "MikroTik RB91x NAND driver support"
++ depends on ATH79 && MTD_RAW_NAND
++ help
++ Enables support for the NAND flash chip on MikroTik RB91x series.
++
+ endif # MTD_RAW_NAND
+--- a/drivers/mtd/nand/raw/Makefile
++++ b/drivers/mtd/nand/raw/Makefile
+@@ -59,6 +59,7 @@ obj-$(CONFIG_MTD_NAND_PL35X) += pl35x-n
+ obj-$(CONFIG_MTD_NAND_RENESAS) += renesas-nand-controller.o
+ obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nand.o
+ obj-$(CONFIG_MTD_NAND_RB4XX) += nand_rb4xx.o
++obj-$(CONFIG_MTD_NAND_RB91X) += rb91x_nand.o
+
+ nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
+ nand-objs += nand_onfi.o
-console=serial0,115200 console=tty1 root=@ROOT@ rootfstype=squashfs,ext4 rootwait
+console=tty1 console=serial0,115200 root=@ROOT@ rootfstype=squashfs,ext4 rootwait
}
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
-@@ -5686,7 +5686,7 @@ static void port_event(struct usb_hub *h
+@@ -5697,7 +5697,7 @@ static void port_event(struct usb_hub *h
port_dev->over_current_count++;
port_over_current_notify(port_dev);
+ */
+ void (*fixup_endpoint)(struct usb_hcd *hcd, struct usb_device *udev,
+ struct usb_host_endpoint *ep, int interval);
- /* Returns the hardware-chosen device address */
- int (*address_device)(struct usb_hcd *, struct usb_device *udev);
- /* prepares the hardware to send commands to the device */
-@@ -435,6 +440,8 @@ extern void usb_hcd_unmap_urb_setup_for_
+ /* Set the hardware-chosen device address */
+ int (*address_device)(struct usb_hcd *, struct usb_device *udev,
+ unsigned int timeout_ms);
+@@ -436,6 +441,8 @@ extern void usb_hcd_unmap_urb_setup_for_
extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *);
extern void usb_hcd_flush_endpoint(struct usb_device *udev,
struct usb_host_endpoint *ep);
* non-error returns are a promise to giveback() the urb later
* we drop ownership so next owner (or urb unlink) can get it
*/
-@@ -5471,6 +5574,7 @@ static const struct hc_driver xhci_hc_dr
+@@ -5480,6 +5583,7 @@ static const struct hc_driver xhci_hc_dr
.endpoint_reset = xhci_endpoint_reset,
.check_bandwidth = xhci_check_bandwidth,
.reset_bandwidth = xhci_reset_bandwidth,
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
-@@ -2522,9 +2522,11 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+@@ -2524,9 +2524,11 @@ int xhci_mem_init(struct xhci_hcd *xhci,
* Event ring setup: Allocate a normal ring, but also setup
* the event ring segment table (ERST). Section 4.9.3.
*/
if (!xhci->event_ring)
goto fail;
if (xhci_check_trb_in_td_math(xhci) < 0)
-@@ -2537,7 +2539,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+@@ -2539,7 +2541,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
/* set ERST count with the number of entries in the segment table */
val = readl(&xhci->ir_set->erst_size);
val &= ERST_SIZE_MASK;
val);
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
-@@ -1672,8 +1672,8 @@ struct urb_priv {
+@@ -1677,8 +1677,8 @@ struct urb_priv {
* Each segment table entry is 4*32bits long. 1K seems like an ok size:
* (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
* meaning 64 ring segments.
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
-@@ -674,9 +674,9 @@ deq_found:
+@@ -675,9 +675,9 @@ deq_found:
}
if ((ep->ep_state & SET_DEQ_PENDING)) {
pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) {
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
-@@ -664,6 +664,15 @@ static int xhci_move_dequeue_past_td(str
+@@ -665,6 +665,15 @@ static int xhci_move_dequeue_past_td(str
} while (!cycle_found || !td_last_trb_found);
deq_found:
addr = xhci_trb_virt_to_dma(new_seg, new_deq);
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
-@@ -1902,6 +1902,7 @@ struct xhci_hcd {
+@@ -1907,6 +1907,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)
if (ret)
return -ENOMEM;
-@@ -1811,7 +1815,7 @@ int xhci_alloc_erst(struct xhci_hcd *xhc
+@@ -1813,7 +1817,7 @@ int xhci_alloc_erst(struct xhci_hcd *xhc
for (val = 0; val < evt_ring->num_segs; val++) {
entry = &erst->entries[val];
entry->seg_addr = cpu_to_le64(seg->dma);
xhci_err(xhci, "Tried to move enqueue past ring segment\n");
return;
}
-@@ -3150,7 +3153,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd
+@@ -3151,7 +3154,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd
* that clears the EHB.
*/
while (xhci_handle_event(xhci) > 0) {
continue;
xhci_update_erst_dequeue(xhci, event_ring_deq);
event_ring_deq = xhci->event_ring->dequeue;
-@@ -3292,7 +3295,8 @@ static int prepare_ring(struct xhci_hcd
+@@ -3293,7 +3296,8 @@ static int prepare_ring(struct xhci_hcd
}
}
* when the cycle bit is set to 1.
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
-@@ -1634,6 +1634,7 @@ struct xhci_ring {
+@@ -1639,6 +1639,7 @@ struct xhci_ring {
unsigned int num_trbs_free;
unsigned int num_trbs_free_temp;
unsigned int bounce_buf_len;
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
-@@ -1904,6 +1904,7 @@ struct xhci_hcd {
+@@ -1909,6 +1909,7 @@ struct xhci_hcd {
#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
#define XHCI_ZHAOXIN_HOST BIT_ULL(46)
#define XHCI_AVOID_DQ_ON_LINK BIT_ULL(47)
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
-@@ -3605,14 +3605,15 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+@@ -3606,14 +3606,15 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
unsigned int num_trbs;
unsigned int start_cycle, num_sgs = 0;
unsigned int enqd_len, block_len, trb_buff_len, full_len;
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)) {
-@@ -3649,6 +3650,17 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+@@ -3650,6 +3651,17 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
start_cycle = ring->cycle_state;
send_addr = addr;
/* Queue the TRBs, even if they are zero-length */
for (enqd_len = 0; first_trb || enqd_len < full_len;
enqd_len += trb_buff_len) {
-@@ -3661,6 +3673,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+@@ -3662,6 +3674,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
if (enqd_len + trb_buff_len > full_len)
trb_buff_len = full_len - enqd_len;
first_trb = false;
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
-@@ -1905,6 +1905,7 @@ struct xhci_hcd {
+@@ -1910,6 +1910,7 @@ struct xhci_hcd {
#define XHCI_ZHAOXIN_HOST BIT_ULL(46)
#define XHCI_AVOID_DQ_ON_LINK BIT_ULL(47)
#define XHCI_VLI_TRB_CACHE_BUG BIT_ULL(48)
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
-@@ -3605,7 +3605,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+@@ -3606,7 +3606,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
unsigned int num_trbs;
unsigned int start_cycle, num_sgs = 0;
unsigned int enqd_len, block_len, trb_buff_len, full_len;
u32 field, length_field, remainder, maxpacket;
u64 addr, send_addr;
-@@ -3651,14 +3651,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+@@ -3652,14 +3652,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
send_addr = addr;
if (xhci->quirks & XHCI_VLI_SS_BULK_OUT_BUG &&
}
/* Queue the TRBs, even if they are zero-length */
-@@ -3673,7 +3668,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+@@ -3674,7 +3669,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
if (enqd_len + trb_buff_len > full_len)
trb_buff_len = full_len - enqd_len;
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
-@@ -1012,11 +1012,13 @@ static int xhci_invalidate_cancelled_tds
+@@ -1013,11 +1013,13 @@ static int xhci_invalidate_cancelled_tds
td->urb->stream_id, td->urb,
cached_td->urb->stream_id, cached_td->urb);
cached_td = td;
}
}
-@@ -1264,10 +1266,7 @@ static void update_ring_for_set_deq_comp
+@@ -1265,10 +1267,7 @@ static void update_ring_for_set_deq_comp
unsigned int ep_index)
{
union xhci_trb *dequeue_temp;
dequeue_temp = ep_ring->dequeue;
/* If we get two back-to-back stalls, and the first stalled transfer
-@@ -1282,8 +1281,6 @@ static void update_ring_for_set_deq_comp
+@@ -1283,8 +1282,6 @@ static void update_ring_for_set_deq_comp
}
while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) {
ep_ring->dequeue++;
if (trb_is_link(ep_ring->dequeue)) {
if (ep_ring->dequeue ==
-@@ -1293,15 +1290,10 @@ static void update_ring_for_set_deq_comp
+@@ -1294,15 +1291,10 @@ static void update_ring_for_set_deq_comp
ep_ring->dequeue = ep_ring->deq_seg->trbs;
}
if (ep_ring->dequeue == dequeue_temp) {
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
-@@ -3582,6 +3582,48 @@ static int xhci_align_td(struct xhci_hcd
+@@ -3583,6 +3583,48 @@ static int xhci_align_td(struct xhci_hcd
return 1;
}
/* This is very similar to what ehci-q.c qtd_fill() does */
int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
struct urb *urb, int slot_id, unsigned int ep_index)
-@@ -3750,6 +3792,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+@@ -3751,6 +3793,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
}
check_trb_math(urb, enqd_len);
giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
start_cycle, start_trb);
return 0;
-@@ -3885,6 +3929,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+@@ -3886,6 +3930,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
/* Event on completion */
field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state);
return 0;
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
-@@ -1906,6 +1906,7 @@ struct xhci_hcd {
+@@ -1911,6 +1911,7 @@ struct xhci_hcd {
#define XHCI_AVOID_DQ_ON_LINK BIT_ULL(47)
#define XHCI_VLI_TRB_CACHE_BUG BIT_ULL(48)
#define XHCI_VLI_SS_BULK_OUT_BUG BIT_ULL(49)
#include <linux/uaccess.h>
#include <asm/io.h>
-@@ -2245,6 +2247,69 @@ static void b44_adjust_link(struct net_d
+@@ -2247,6 +2249,69 @@ static void b44_adjust_link(struct net_d
}
}
static int b44_register_phy_one(struct b44 *bp)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-@@ -2281,6 +2346,9 @@ static int b44_register_phy_one(struct b
+@@ -2283,6 +2348,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))) {
dev_info(sdev->dev,
"could not find PHY at %i, use fixed one\n",
bp->phy_addr);
-@@ -2475,6 +2543,7 @@ static void b44_remove_one(struct ssb_de
+@@ -2477,6 +2545,7 @@ static void b44_remove_one(struct ssb_de
unregister_netdev(dev);
if (bp->flags & B44_FLAG_EXTERNAL_PHY)
b44_unregister_phy_one(bp);
if (bp->flags & B44_FLAG_EXTERNAL_PHY)
return 0;
-@@ -2175,6 +2200,8 @@ static int b44_get_invariants(struct b44
+@@ -2177,6 +2202,8 @@ static int b44_get_invariants(struct b44
* valid PHY address. */
bp->phy_addr &= 0x1F;
if (xhci->quirks & XHCI_NEC_HOST)
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
-@@ -1902,6 +1902,7 @@ struct xhci_hcd {
+@@ -1907,6 +1907,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)
ucidef_set_bridge_device switch
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan"
;;
+inteno,xg6846)
+ ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan ext1"
+ ;;
comtrend,ar-5381u |\
comtrend,ar-5387un |\
innacomm,w3400v6 |\
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_BCM63XX_FW=y
CONFIG_MTD_SPLIT_BCM_WFI_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+/*
+ * Devicetree for the Inteno XG6846 router, mostly used as a
+ * media converter from fiber to twisted pair ethernet
+ * "fiber modem" in many households in Sweden. The Marvell
+ * switch has one of its ports connected to an SFP (Small Form
+ * Factor pluggable) optical fiber receiver, which is bridged
+ * to the twisted pair connector LAN1.
+ *
+ * This device tree is inspired by research from the OpenWrt
+ * and Sweclockers forums, including contributions from
+ * NPeca75, mrhaav and csom.
+ *
+ * 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";
+ };
+
+ /*
+ * This I2C port is connected to the SFP and reflects the EEPROM etc
+ * inside the SFP module. If the module is not plugged in, consequently
+ * nothing will be found on the bus.
+ */
+ i2c0: i2c-sfp {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ /* This I2C bus is used for the external CATV connector (usually unused) */
+ i2c1: i2c-catv {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ #address-cells = <1>;
+ #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>;
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ debounce-interval = <60>;
+ };
+ };
+};
+
+&hsspi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ /*
+ * HW 1.0-1.1: Spansion S25FL128S1
+ * HW 1.3: Winbond W25Q128
+ *
+ * Fast Read Data max speed is 50MHz, see the Winbond W25Q128
+ * datasheet table 9.5 "AC Electrical Characteristics", we can
+ * use this speed because the chip supports fast reads. Older
+ * HW has different NOR chips, I assume they can all do fast
+ * reads.
+ */
+ spi-max-frequency = <104000000>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ m25p,fast-read;
+ reg = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cfe: partition@0 {
+ label = "cfe";
+ reg = <0x0000000 0x0010000>;
+ read-only;
+ };
+
+ partition@10000 {
+ compatible = "openwrt,uimage", "denx,uimage";
+ reg = <0x010000 0xfe0000>;
+ label = "firmware";
+ openwrt,offset = <0x30000>;
+ };
+
+ partition@ff0000 {
+ reg = <0xff0000 0x010000>;
+ label = "nvram";
+ };
+ };
+ };
+};
+
+&cfe {
+ compatible = "nvmem-cells";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_cfe_6a0: macaddr@6a0 {
+ reg = <0x6a0 0x6>;
+ };
+};
+
+ðernet {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_cfe_6a0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&switch0 {
+ dsa,member = <0 0>;
+
+ ports {
+ switch0port4: port@4 {
+ reg = <4>;
+ label = "extsw";
+
+ phy-mode = "rgmii";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+};
+
+&mdio_ext {
+ switch1: switch@0 {
+ /* The switch is not using any external IRQ, sadly */
+ compatible = "marvell,mv88e6085";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ dsa,member = <1 0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+ phy-handle = <&lan1phy>;
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ phy-handle = <&lan2phy>;
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ phy-handle = <&lan3phy>;
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+ phy-handle = <&lan4phy>;
+ };
+
+ port@4 {
+ reg = <4>;
+ label = "ext1";
+ phy-handle = <&ext1phy>;
+ };
+
+ port@5 {
+ reg = <5>;
+ phy-mode = "rgmii-id";
+ label = "wan";
+ sfp = <&sfp0>;
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ port@6 {
+ reg = <6>;
+ phy-mode = "rgmii-id";
+ label = "cpu";
+ ethernet = <&switch0port4>;
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ lan1phy: ethernet-phy@0 {
+ reg = <0>;
+ 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>;
+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&pinctrl {
+ pinctrl_xg6846_usb_spd_led: xg6846_usb_spd_led-pins {
+ function = "led";
+ pins = "gpio17";
+ };
+};
+
+&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 */
+
+ /* 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";
+ };
+
+ /*
+ * 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";
+ };
+
+ led_pwr_green: led@20 {
+ reg = <20>;
+ active-low;
+ label = "green:pwr";
+ default-state = "off";
+ };
+
+};
include $(INCLUDE_DIR)/image.mk
KERNEL_LOADADDR := 0x80010000 # RAM start + 64K
+UBOOT_ENTRY := 0x81c00000
LOADER_ENTRY := 0x81000000 # RAM start + 16M, for relocate
LZMA_TEXT_START := 0x82000000 # RAM start + 32M
$(CFE_EXTRAS) $(1)
endef
+# Build a CFE image with just U-Boot
+define Build/cfe-bin-uboot
+ cp $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-u-boot.bin $@
+ $(call Build/lzma)
+ mv $@ $@.uboot.lzma
+ echo "dummy" > $@.dummyfs
+ $(STAGING_DIR_HOST)/bin/imagetag -i $@.uboot.lzma -f $@.dummyfs \
+ --output $@ --boardid $(CFE_BOARD_ID) --chipid $(CHIP_ID) \
+ --entry $(UBOOT_ENTRY) --load-addr $(UBOOT_ENTRY) \
+ --info1 "$(call ModelNameLimit16,$(DEVICE_NAME))" \
+ $(CFE_EXTRAS) $(1)
+ rm $@.uboot.lzma
+ rm $@.dummyfs
+endef
+
define Build/cfe-jffs2
$(STAGING_DIR_HOST)/bin/mkfs.jffs2 \
--big-endian \
KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma-cfe
endef
+# CFE images with U-Boot in front of the kernel, these will execute
+# U-Boot instead of the kernel and U-Boot will then proceed to load
+# the kernel. The reason to do this is that CFE is sometimes unable to
+# load big kernels even with the lzma loader tricks.
+define Device/bcm63xx-cfe-uboot
+ $(Device/bcm63xx-cfe)
+ KERNEL := kernel-bin | append-dtb | lzma | uImage lzma
+ IMAGE/cfe.bin := cfe-bin-uboot | pad-to $$$$$$$$(($$(BLOCKSIZE))) | \
+ append-kernel | pad-to $$$$$$$$(($$(BLOCKSIZE))) | \
+ append-rootfs $$$$(if $$$$(FLASH_MB),--pad $$$$(shell expr $$$$(FLASH_MB) / 2))
+ IMAGE/sysupgrade.bin := cfe-bin-uboot | pad-to $$$$$$$$(($$(BLOCKSIZE))) | \
+ append-kernel | pad-to $$$$$$$$(($$(BLOCKSIZE))) | \
+ append-rootfs | append-metadata
+endef
+
# CFE expects a single JFFS2 partition with cferam and kernel. However,
# it's possible to fool CFE into properly loading both cferam and kernel
# from two different JFFS2 partitions by adding dummy files (see
endef
TARGET_DEVICES += innacomm_w3400v6
+define Device/inteno_xg6846
+ $(Device/bcm63xx-cfe-uboot)
+ DEVICE_VENDOR := Inteno
+ DEVICE_MODEL := XG6846
+ CHIP_ID := 6328
+ CFE_BOARD_ID := 96328avng
+ FLASH_MB := 16
+ DEVICE_PACKAGES := $(USB2_PACKAGES) \
+ kmod-i2c-core kmod-i2c-gpio \
+ kmod-leds-bcm6328 kmod-dsa-mv88e6xxx \
+ kmod-sfp
+endef
+TARGET_DEVICES += inteno_xg6846
+
define Device/nucom_r5010unv2
$(Device/bcm63xx-cfe)
DEVICE_VENDOR := NuCom
CPU_TYPE:=fa526
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for the StorLink/Cortina Gemini CS351x ARM FA526 CPU
+++ /dev/null
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_AMBA_PL08X=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_GEMINI=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-# CONFIG_ARCH_MOXART is not set
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V4=y
-# CONFIG_ARCH_MULTI_V4T is not set
-CONFIG_ARCH_MULTI_V4_V5=y
-# CONFIG_ARCH_MULTI_V5 is not set
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_APPENDED_DTB=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_L1_CACHE_SHIFT=5
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-# CONFIG_ARM_SMMU is not set
-CONFIG_ARM_UNWIND=y
-CONFIG_ATA=y
-CONFIG_ATAGS=y
-CONFIG_ATA_FORCE=y
-CONFIG_ATA_VERBOSE_ERROR=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_PM=y
-CONFIG_BOUNCE=y
-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_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_PERCENTAGE=10
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-# CONFIG_CMA_SIZE_SEL_MBYTES is not set
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-CONFIG_CMA_SIZE_SEL_PERCENTAGE=y
-# CONFIG_CMA_SYSFS is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_GEMINI=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=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_CPU_32v4=y
-CONFIG_CPU_ABRT_EV4=y
-CONFIG_CPU_CACHE_FA=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_FA=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-CONFIG_CPU_FA526=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_NO_EFFICIENT_FFS=y
-CONFIG_CPU_PABRT_LEGACY=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPU_TLB_FA=y
-CONFIG_CPU_USE_DOMAINS=y
-CONFIG_CRASH_CORE=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_CMAC=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEV_SL3516=y
-# CONFIG_CRYPTO_DEV_SL3516_DEBUG is not set
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ECHAINIV=y
-CONFIG_CRYPTO_ENGINE=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_MD4=y
-CONFIG_CRYPTO_MD5=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_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_LZ4=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_DECOMPRESS_LZO=y
-CONFIG_DECOMPRESS_XZ=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_DMA_SHARED_BUFFER=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DRM=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_ILITEK_IL9322=y
-CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
-CONFIG_DRM_TVE200=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_93CX6=y
-CONFIG_ELF_CORE=y
-# CONFIG_EMBEDDED is not set
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-# CONFIG_EXPERT is not set
-CONFIG_EXT4_FS=y
-CONFIG_EXTCON=y
-CONFIG_FARADAY_FTINTC010=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_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_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FTTMR010_TIMER=y
-CONFIG_FTWDT010_WATCHDOG=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_GEMINI_ETHERNET=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_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_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_FTGPIO010=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HDMI=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HWMON=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_GPIO=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_INPUT_KEYBOARD=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_IO_URING=y
-CONFIG_IPC_NS=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-# CONFIG_ISDN is not set
-CONFIG_JBD2=y
-CONFIG_KALLSYMS=y
-CONFIG_KCMP=y
-CONFIG_KERNEL_LZMA=y
-# CONFIG_KERNEL_XZ is not set
-CONFIG_KEXEC=y
-CONFIG_KEXEC_CORE=y
-CONFIG_KEYBOARD_DLINK_DIR685=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-# CONFIG_LDM_DEBUG is not set
-CONFIG_LDM_PARTITION=y
-CONFIG_LEDS_TRIGGER_DISK=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_LOGO_LINUX_MONO is not set
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LZ4_DECOMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BITBANG=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MDIO_GPIO=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MODULE_UNLOAD is not set
-CONFIG_MQ_IOSCHED_DEADLINE=y
-CONFIG_MQ_IOSCHED_KYBER=y
-CONFIG_MTD_CFI_STAA=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_GEMINI=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_WRGG_FW=y
-CONFIG_NAMESPACES=y
-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_REALTEK=y
-# CONFIG_NET_DSA_REALTEK_MDIO is not set
-# CONFIG_NET_DSA_REALTEK_RTL8365MB is not set
-CONFIG_NET_DSA_REALTEK_RTL8366RB=y
-CONFIG_NET_DSA_REALTEK_SMI=y
-CONFIG_NET_DSA_TAG_RTL4_A=y
-CONFIG_NET_NS=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=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_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_PATA_FTIDE010=y
-CONFIG_PCI=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_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_FTPCI100=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PID_NS=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_GEMINI=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GEMINI_POWEROFF=y
-CONFIG_POWER_RESET_SYSCON=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_PROC_PAGE_MONITOR=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_GZIP=y
-CONFIG_RD_LZ4=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_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RELAY=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RSEQ=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_FTRTC010=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-CONFIG_RTC_NVMEM=y
-CONFIG_SATA_GEMINI=y
-CONFIG_SATA_HOST=y
-CONFIG_SATA_PMP=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_SENSORS_DRIVETEMP=y
-CONFIG_SENSORS_GPIO_FAN=y
-CONFIG_SENSORS_LM75=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_EXAR=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_RUNTIME_UARTS=1
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIO=y
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SG_POOL=y
-CONFIG_SLUB_DEBUG=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPLIT_PTLOCK_CPUS=999999
-CONFIG_SRCU=y
-CONFIG_STACKDEPOT=y
-CONFIG_STACKTRACE=y
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_SWPHY=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_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_TMPFS_POSIX_ACL=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB_COMMON=y
-# CONFIG_USB_FOTG210 is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_GPIO_VBUS=y
-CONFIG_USB_PHY=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USER_NS=y
-CONFIG_USE_OF=y
-CONFIG_UTS_NS=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_HW_CONSOLE_BINDING=y
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-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_INFLATE=y
--- /dev/null
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_AMBA_PL08X=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_GEMINI=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+# CONFIG_ARCH_MOXART is not set
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V4=y
+# CONFIG_ARCH_MULTI_V4T is not set
+CONFIG_ARCH_MULTI_V4_V5=y
+# CONFIG_ARCH_MULTI_V5 is not set
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_APPENDED_DTB=y
+# CONFIG_ARM_ATAG_DTB_COMPAT is not set
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ATA=y
+CONFIG_ATAGS=y
+CONFIG_ATA_FORCE=y
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BOUNCE=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CACHESTAT_SYSCALL=y
+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_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_PERCENTAGE=10
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+# CONFIG_CMA_SIZE_SEL_MBYTES is not set
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+CONFIG_CMA_SIZE_SEL_PERCENTAGE=y
+# CONFIG_CMA_SYSFS is not set
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_GEMINI=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=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_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_CACHE_FA=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_FA=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+CONFIG_CPU_FA526=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_NO_EFFICIENT_FFS=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_TLB_FA=y
+CONFIG_CPU_USE_DOMAINS=y
+CONFIG_CRASH_CORE=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_DEV_JH7110 is not set
+CONFIG_CRYPTO_DEV_SL3516=y
+# CONFIG_CRYPTO_DEV_SL3516_DEBUG is not set
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_ENGINE=y
+CONFIG_CRYPTO_GENIV=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_MANAGER_DISABLE_TESTS is not set
+# CONFIG_CRYPTO_MANAGER_EXTRA_TESTS is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=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_SIG2=y
+CONFIG_CRYPTO_USER=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_LZ4=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_DECOMPRESS_XZ=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_DMA_SHARED_BUFFER=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DRM=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_ILITEK_IL9322=y
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+CONFIG_DRM_TVE200=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_93CX6=y
+CONFIG_ELF_CORE=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+# CONFIG_EXPERT is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXTCON=y
+CONFIG_FARADAY_FTINTC010=y
+CONFIG_FB=y
+CONFIG_FB_CORE=y
+CONFIG_FB_DEFERRED_IO=y
+CONFIG_FB_DMAMEM_HELPERS=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_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_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FTTMR010_TIMER=y
+CONFIG_FTWDT010_WATCHDOG=y
+CONFIG_FUNCTION_ALIGNMENT=0
+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_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
+CONFIG_GEMINI_ETHERNET=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_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_GLOB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_FTGPIO010=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GRO_CELLS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HDMI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HWMON=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_IO_URING=y
+CONFIG_IPC_NS=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQSTACKS=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_ISDN is not set
+CONFIG_JBD2=y
+CONFIG_KALLSYMS=y
+CONFIG_KCMP=y
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_XZ is not set
+CONFIG_KEXEC=y
+CONFIG_KEXEC_CORE=y
+CONFIG_KEYBOARD_DLINK_DIR685=y
+CONFIG_KMAP_LOCAL=y
+CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
+# CONFIG_LDM_DEBUG is not set
+CONFIG_LDM_PARTITION=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO_LINUX_MONO is not set
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LZ4_DECOMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MDIO_GPIO=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_MQ_IOSCHED_DEADLINE=y
+CONFIG_MQ_IOSCHED_KYBER=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_GEMINI=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_WRGG_FW=y
+CONFIG_NAMESPACES=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_KUSER_HELPERS=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_REALTEK=y
+# CONFIG_NET_DSA_REALTEK_MDIO is not set
+# CONFIG_NET_DSA_REALTEK_RTL8365MB is not set
+CONFIG_NET_DSA_REALTEK_RTL8366RB=y
+CONFIG_NET_DSA_REALTEK_SMI=y
+CONFIG_NET_DSA_TAG_RTL4_A=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_NS=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=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_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_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_PATA_FTIDE010=y
+CONFIG_PCI=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_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_FTPCI100=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PID_NS=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_GEMINI=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GEMINI_POWEROFF=y
+CONFIG_POWER_RESET_SYSCON=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_PROC_PAGE_MONITOR=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_GZIP=y
+CONFIG_RD_LZ4=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_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_RELAY=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RSEQ=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_FTRTC010=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_RTC_NVMEM=y
+CONFIG_SATA_GEMINI=y
+CONFIG_SATA_HOST=y
+CONFIG_SATA_PMP=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_SENSORS_DRIVETEMP=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_EXAR=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PCILIB=y
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIO=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_STACKDEPOT=y
+CONFIG_STACKTRACE=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_SWPHY=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_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_TMPFS_POSIX_ACL=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB_COMMON=y
+# CONFIG_USB_FOTG210 is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_GPIO_VBUS=y
+CONFIG_USB_PHY=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USER_NS=y
+CONFIG_USE_OF=y
+CONFIG_UTS_NS=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_HW_CONSOLE_BINDING=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+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_INFLATE=y
# All DTB files are prefixed with "gemini-"
define Device/Default
PROFILES := Default
+ DEVICE_DTS_DIR = $$(DTS_DIR)/gemini
KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
KERNEL_NAME := zImage
KERNEL := kernel-bin | append-dtb
+++ /dev/null
-From d5a026cc8306ccd3e99e1455c87e38f8e6fa18df Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 7 Nov 2022 00:05:06 +0100
-Subject: [PATCH 01/29] usb: phy: phy-gpio-vbus-usb: Add device tree probing
-
-Make it possible to probe the GPIO VBUS detection driver
-from the device tree compatible for GPIO USB B connectors.
-
-Since this driver is using the "gpio-usb-b-connector"
-compatible, it is important to discern it from the role
-switch connector driver (which does not provide a phy),
-so we add some Kconfig text and depend on !USB_CONN_GPIO.
-
-Cc: Rob Herring <robh@kernel.org>
-Cc: Prashant Malani <pmalani@chromium.org>
-Cc: Felipe Balbi <balbi@kernel.org>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221106230506.1646101-1-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/phy/Kconfig
-+++ b/drivers/usb/phy/Kconfig
-@@ -93,12 +93,16 @@ config USB_GPIO_VBUS
- tristate "GPIO based peripheral-only VBUS sensing 'transceiver'"
- depends on GPIOLIB || COMPILE_TEST
- depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y'
-+ depends on !USB_CONN_GPIO
- select USB_PHY
- help
- Provides simple GPIO VBUS sensing for controllers with an
- internal transceiver via the usb_phy interface, and
- optionally control of a D+ pullup GPIO as well as a VBUS
-- current limit regulator.
-+ current limit regulator. This driver is for devices that do
-+ NOT support role switch. OTG devices that can do role switch
-+ (master/peripheral) shall use the USB based connection
-+ detection driver USB_CONN_GPIO.
-
- config OMAP_OTG
- tristate "OMAP USB OTG controller driver"
---- a/drivers/usb/phy/phy-gpio-vbus-usb.c
-+++ b/drivers/usb/phy/phy-gpio-vbus-usb.c
-@@ -366,12 +366,24 @@ static const struct dev_pm_ops gpio_vbus
-
- MODULE_ALIAS("platform:gpio-vbus");
-
-+/*
-+ * NOTE: this driver matches against "gpio-usb-b-connector" for
-+ * devices that do NOT support role switch.
-+ */
-+static const struct of_device_id gpio_vbus_of_match[] = {
-+ {
-+ .compatible = "gpio-usb-b-connector",
-+ },
-+ {},
-+};
-+
- static struct platform_driver gpio_vbus_driver = {
- .driver = {
- .name = "gpio-vbus",
- #ifdef CONFIG_PM
- .pm = &gpio_vbus_dev_pm_ops,
- #endif
-+ .of_match_table = gpio_vbus_of_match,
- },
- .probe = gpio_vbus_probe,
- .remove = gpio_vbus_remove,
+++ /dev/null
-From 30367636930864f71b2bd462adedcf8484313864 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 23 Oct 2022 16:47:06 +0200
-Subject: [PATCH 02/29] usb: fotg210: Collect pieces of dual mode controller
-
-The Faraday FOTG210 is a dual-mode OTG USB controller that can
-act as host, peripheral or both. To be able to probe from one
-hardware description and to follow the pattern of other dual-
-mode controllers such as MUSB or MTU3 we need to collect the
-two, currently completely separate drivers in the same
-directory.
-
-After this, users need to select the main symbol USB_FOTG210
-and then each respective subdriver. We pave the road to
-compile both drivers into the same kernel and select the
-one we want to use at probe() time, and possibly add OTG
-support in the end.
-
-This patch doesn't do much more than create the new symbol
-and collect the drivers in one place. We also add a comment
-for the section of dual-mode controllers in the Kconfig
-file so people can see what these selections are about.
-
-Also add myself as maintainer as there has been little
-response on my patches to these drivers.
-
-Cc: Fabian Vogt <fabian@ritter-vogt.de>
-Cc: Yuan-Hsin Chen <yhchen@faraday-tech.com>
-Cc: Felipe Balbi <balbi@kernel.org>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221023144708.3596563-1-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/Kconfig
-+++ b/drivers/usb/Kconfig
-@@ -111,8 +111,12 @@ source "drivers/usb/usbip/Kconfig"
-
- endif
-
-+comment "USB dual-mode controller drivers"
-+
- source "drivers/usb/cdns3/Kconfig"
-
-+source "drivers/usb/fotg210/Kconfig"
-+
- source "drivers/usb/mtu3/Kconfig"
-
- source "drivers/usb/musb/Kconfig"
---- a/drivers/usb/Makefile
-+++ b/drivers/usb/Makefile
-@@ -17,6 +17,8 @@ obj-$(CONFIG_USB_CDNS_SUPPORT) += cdns3/
- obj-$(CONFIG_USB_CDNS3) += cdns3/
- obj-$(CONFIG_USB_CDNSP_PCI) += cdns3/
-
-+obj-$(CONFIG_USB_FOTG210) += fotg210/
-+
- obj-$(CONFIG_USB_MON) += mon/
- obj-$(CONFIG_USB_MTU3) += mtu3/
-
---- /dev/null
-+++ b/drivers/usb/fotg210/Kconfig
-@@ -0,0 +1,36 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+config USB_FOTG210
-+ tristate "Faraday FOTG210 USB2 Dual Role controller"
-+ depends on USB || USB_GADGET
-+ depends on HAS_DMA && HAS_IOMEM
-+ default ARCH_GEMINI
-+ help
-+ Faraday FOTG210 is a dual-mode USB controller that can act
-+ in both host controller and peripheral controller mode.
-+
-+if USB_FOTG210
-+
-+config USB_FOTG210_HCD
-+ tristate "Faraday FOTG210 USB Host Controller support"
-+ depends on USB
-+ help
-+ Faraday FOTG210 is an OTG controller which can be configured as
-+ an USB2.0 host. It is designed to meet USB2.0 EHCI specification
-+ with minor modification.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called fotg210-hcd.
-+
-+config USB_FOTG210_UDC
-+ depends on USB_GADGET
-+ tristate "Faraday FOTG210 USB Peripheral Controller support"
-+ help
-+ Faraday USB2.0 OTG controller which can be configured as
-+ high speed or full speed USB device. This driver suppports
-+ Bulk Transfer so far.
-+
-+ Say "y" to link the driver statically, or "m" to build a
-+ dynamically linked module called "fotg210-udc".
-+
-+endif
---- /dev/null
-+++ b/drivers/usb/fotg210/Makefile
-@@ -0,0 +1,3 @@
-+# SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o
-+obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o
---- a/drivers/usb/host/fotg210-hcd.c
-+++ /dev/null
-@@ -1,5724 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0+
--/* Faraday FOTG210 EHCI-like driver
-- *
-- * Copyright (c) 2013 Faraday Technology Corporation
-- *
-- * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com>
-- * Feng-Hsin Chiang <john453@faraday-tech.com>
-- * Po-Yu Chuang <ratbert.chuang@gmail.com>
-- *
-- * Most of code borrowed from the Linux-3.7 EHCI driver
-- */
--#include <linux/module.h>
--#include <linux/of.h>
--#include <linux/device.h>
--#include <linux/dmapool.h>
--#include <linux/kernel.h>
--#include <linux/delay.h>
--#include <linux/ioport.h>
--#include <linux/sched.h>
--#include <linux/vmalloc.h>
--#include <linux/errno.h>
--#include <linux/init.h>
--#include <linux/hrtimer.h>
--#include <linux/list.h>
--#include <linux/interrupt.h>
--#include <linux/usb.h>
--#include <linux/usb/hcd.h>
--#include <linux/moduleparam.h>
--#include <linux/dma-mapping.h>
--#include <linux/debugfs.h>
--#include <linux/slab.h>
--#include <linux/uaccess.h>
--#include <linux/platform_device.h>
--#include <linux/io.h>
--#include <linux/iopoll.h>
--#include <linux/clk.h>
--
--#include <asm/byteorder.h>
--#include <asm/irq.h>
--#include <asm/unaligned.h>
--
--#define DRIVER_AUTHOR "Yuan-Hsin Chen"
--#define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
--static const char hcd_name[] = "fotg210_hcd";
--
--#undef FOTG210_URB_TRACE
--#define FOTG210_STATS
--
--/* magic numbers that can affect system performance */
--#define FOTG210_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */
--#define FOTG210_TUNE_RL_HS 4 /* nak throttle; see 4.9 */
--#define FOTG210_TUNE_RL_TT 0
--#define FOTG210_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
--#define FOTG210_TUNE_MULT_TT 1
--
--/* Some drivers think it's safe to schedule isochronous transfers more than 256
-- * ms into the future (partly as a result of an old bug in the scheduling
-- * code). In an attempt to avoid trouble, we will use a minimum scheduling
-- * length of 512 frames instead of 256.
-- */
--#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
--
--/* Initial IRQ latency: faster than hw default */
--static int log2_irq_thresh; /* 0 to 6 */
--module_param(log2_irq_thresh, int, S_IRUGO);
--MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
--
--/* initial park setting: slower than hw default */
--static unsigned park;
--module_param(park, uint, S_IRUGO);
--MODULE_PARM_DESC(park, "park setting; 1-3 back-to-back async packets");
--
--/* for link power management(LPM) feature */
--static unsigned int hird;
--module_param(hird, int, S_IRUGO);
--MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
--
--#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
--
--#include "fotg210.h"
--
--#define fotg210_dbg(fotg210, fmt, args...) \
-- dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
--#define fotg210_err(fotg210, fmt, args...) \
-- dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
--#define fotg210_info(fotg210, fmt, args...) \
-- dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
--#define fotg210_warn(fotg210, fmt, args...) \
-- dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
--
--/* check the values in the HCSPARAMS register (host controller _Structural_
-- * parameters) see EHCI spec, Table 2-4 for each value
-- */
--static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
--{
-- u32 params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
--
-- fotg210_dbg(fotg210, "%s hcs_params 0x%x ports=%d\n", label, params,
-- HCS_N_PORTS(params));
--}
--
--/* check the values in the HCCPARAMS register (host controller _Capability_
-- * parameters) see EHCI Spec, Table 2-5 for each value
-- */
--static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
--{
-- u32 params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
--
-- fotg210_dbg(fotg210, "%s hcc_params %04x uframes %s%s\n", label,
-- params,
-- HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-- HCC_CANPARK(params) ? " park" : "");
--}
--
--static void __maybe_unused
--dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
--{
-- fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-- hc32_to_cpup(fotg210, &qtd->hw_next),
-- hc32_to_cpup(fotg210, &qtd->hw_alt_next),
-- hc32_to_cpup(fotg210, &qtd->hw_token),
-- hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
-- if (qtd->hw_buf[1])
-- fotg210_dbg(fotg210, " p1=%08x p2=%08x p3=%08x p4=%08x\n",
-- hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
-- hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
-- hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
-- hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
--}
--
--static void __maybe_unused
--dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
--{
-- struct fotg210_qh_hw *hw = qh->hw;
--
-- fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
-- hw->hw_next, hw->hw_info1, hw->hw_info2,
-- hw->hw_current);
--
-- dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
--}
--
--static void __maybe_unused
--dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
--{
-- fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n", label,
-- itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
-- itd->urb);
--
-- fotg210_dbg(fotg210,
-- " trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-- hc32_to_cpu(fotg210, itd->hw_transaction[0]),
-- hc32_to_cpu(fotg210, itd->hw_transaction[1]),
-- hc32_to_cpu(fotg210, itd->hw_transaction[2]),
-- hc32_to_cpu(fotg210, itd->hw_transaction[3]),
-- hc32_to_cpu(fotg210, itd->hw_transaction[4]),
-- hc32_to_cpu(fotg210, itd->hw_transaction[5]),
-- hc32_to_cpu(fotg210, itd->hw_transaction[6]),
-- hc32_to_cpu(fotg210, itd->hw_transaction[7]));
--
-- fotg210_dbg(fotg210,
-- " buf: %08x %08x %08x %08x %08x %08x %08x\n",
-- hc32_to_cpu(fotg210, itd->hw_bufp[0]),
-- hc32_to_cpu(fotg210, itd->hw_bufp[1]),
-- hc32_to_cpu(fotg210, itd->hw_bufp[2]),
-- hc32_to_cpu(fotg210, itd->hw_bufp[3]),
-- hc32_to_cpu(fotg210, itd->hw_bufp[4]),
-- hc32_to_cpu(fotg210, itd->hw_bufp[5]),
-- hc32_to_cpu(fotg210, itd->hw_bufp[6]));
--
-- fotg210_dbg(fotg210, " index: %d %d %d %d %d %d %d %d\n",
-- itd->index[0], itd->index[1], itd->index[2],
-- itd->index[3], itd->index[4], itd->index[5],
-- itd->index[6], itd->index[7]);
--}
--
--static int __maybe_unused
--dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
--{
-- return scnprintf(buf, len, "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-- label, label[0] ? " " : "", status,
-- (status & STS_ASS) ? " Async" : "",
-- (status & STS_PSS) ? " Periodic" : "",
-- (status & STS_RECL) ? " Recl" : "",
-- (status & STS_HALT) ? " Halt" : "",
-- (status & STS_IAA) ? " IAA" : "",
-- (status & STS_FATAL) ? " FATAL" : "",
-- (status & STS_FLR) ? " FLR" : "",
-- (status & STS_PCD) ? " PCD" : "",
-- (status & STS_ERR) ? " ERR" : "",
-- (status & STS_INT) ? " INT" : "");
--}
--
--static int __maybe_unused
--dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
--{
-- return scnprintf(buf, len, "%s%sintrenable %02x%s%s%s%s%s%s",
-- label, label[0] ? " " : "", enable,
-- (enable & STS_IAA) ? " IAA" : "",
-- (enable & STS_FATAL) ? " FATAL" : "",
-- (enable & STS_FLR) ? " FLR" : "",
-- (enable & STS_PCD) ? " PCD" : "",
-- (enable & STS_ERR) ? " ERR" : "",
-- (enable & STS_INT) ? " INT" : "");
--}
--
--static const char *const fls_strings[] = { "1024", "512", "256", "??" };
--
--static int dbg_command_buf(char *buf, unsigned len, const char *label,
-- u32 command)
--{
-- return scnprintf(buf, len,
-- "%s%scommand %07x %s=%d ithresh=%d%s%s%s period=%s%s %s",
-- label, label[0] ? " " : "", command,
-- (command & CMD_PARK) ? " park" : "(park)",
-- CMD_PARK_CNT(command),
-- (command >> 16) & 0x3f,
-- (command & CMD_IAAD) ? " IAAD" : "",
-- (command & CMD_ASE) ? " Async" : "",
-- (command & CMD_PSE) ? " Periodic" : "",
-- fls_strings[(command >> 2) & 0x3],
-- (command & CMD_RESET) ? " Reset" : "",
-- (command & CMD_RUN) ? "RUN" : "HALT");
--}
--
--static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
-- u32 status)
--{
-- char *sig;
--
-- /* signaling state */
-- switch (status & (3 << 10)) {
-- case 0 << 10:
-- sig = "se0";
-- break;
-- case 1 << 10:
-- sig = "k";
-- break; /* low speed */
-- case 2 << 10:
-- sig = "j";
-- break;
-- default:
-- sig = "?";
-- break;
-- }
--
-- scnprintf(buf, len, "%s%sport:%d status %06x %d sig=%s%s%s%s%s%s%s%s",
-- label, label[0] ? " " : "", port, status,
-- status >> 25, /*device address */
-- sig,
-- (status & PORT_RESET) ? " RESET" : "",
-- (status & PORT_SUSPEND) ? " SUSPEND" : "",
-- (status & PORT_RESUME) ? " RESUME" : "",
-- (status & PORT_PEC) ? " PEC" : "",
-- (status & PORT_PE) ? " PE" : "",
-- (status & PORT_CSC) ? " CSC" : "",
-- (status & PORT_CONNECT) ? " CONNECT" : "");
--
-- return buf;
--}
--
--/* functions have the "wrong" filename when they're output... */
--#define dbg_status(fotg210, label, status) { \
-- char _buf[80]; \
-- dbg_status_buf(_buf, sizeof(_buf), label, status); \
-- fotg210_dbg(fotg210, "%s\n", _buf); \
--}
--
--#define dbg_cmd(fotg210, label, command) { \
-- char _buf[80]; \
-- dbg_command_buf(_buf, sizeof(_buf), label, command); \
-- fotg210_dbg(fotg210, "%s\n", _buf); \
--}
--
--#define dbg_port(fotg210, label, port, status) { \
-- char _buf[80]; \
-- fotg210_dbg(fotg210, "%s\n", \
-- dbg_port_buf(_buf, sizeof(_buf), label, port, status));\
--}
--
--/* troubleshooting help: expose state in debugfs */
--static int debug_async_open(struct inode *, struct file *);
--static int debug_periodic_open(struct inode *, struct file *);
--static int debug_registers_open(struct inode *, struct file *);
--static int debug_async_open(struct inode *, struct file *);
--
--static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
--static int debug_close(struct inode *, struct file *);
--
--static const struct file_operations debug_async_fops = {
-- .owner = THIS_MODULE,
-- .open = debug_async_open,
-- .read = debug_output,
-- .release = debug_close,
-- .llseek = default_llseek,
--};
--static const struct file_operations debug_periodic_fops = {
-- .owner = THIS_MODULE,
-- .open = debug_periodic_open,
-- .read = debug_output,
-- .release = debug_close,
-- .llseek = default_llseek,
--};
--static const struct file_operations debug_registers_fops = {
-- .owner = THIS_MODULE,
-- .open = debug_registers_open,
-- .read = debug_output,
-- .release = debug_close,
-- .llseek = default_llseek,
--};
--
--static struct dentry *fotg210_debug_root;
--
--struct debug_buffer {
-- ssize_t (*fill_func)(struct debug_buffer *); /* fill method */
-- struct usb_bus *bus;
-- struct mutex mutex; /* protect filling of buffer */
-- size_t count; /* number of characters filled into buffer */
-- char *output_buf;
-- size_t alloc_size;
--};
--
--static inline char speed_char(u32 scratch)
--{
-- switch (scratch & (3 << 12)) {
-- case QH_FULL_SPEED:
-- return 'f';
--
-- case QH_LOW_SPEED:
-- return 'l';
--
-- case QH_HIGH_SPEED:
-- return 'h';
--
-- default:
-- return '?';
-- }
--}
--
--static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
--{
-- __u32 v = hc32_to_cpu(fotg210, token);
--
-- if (v & QTD_STS_ACTIVE)
-- return '*';
-- if (v & QTD_STS_HALT)
-- return '-';
-- if (!IS_SHORT_READ(v))
-- return ' ';
-- /* tries to advance through hw_alt_next */
-- return '/';
--}
--
--static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
-- char **nextp, unsigned *sizep)
--{
-- u32 scratch;
-- u32 hw_curr;
-- struct fotg210_qtd *td;
-- unsigned temp;
-- unsigned size = *sizep;
-- char *next = *nextp;
-- char mark;
-- __le32 list_end = FOTG210_LIST_END(fotg210);
-- struct fotg210_qh_hw *hw = qh->hw;
--
-- if (hw->hw_qtd_next == list_end) /* NEC does this */
-- mark = '@';
-- else
-- mark = token_mark(fotg210, hw->hw_token);
-- if (mark == '/') { /* qh_alt_next controls qh advance? */
-- if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
-- fotg210->async->hw->hw_alt_next)
-- mark = '#'; /* blocked */
-- else if (hw->hw_alt_next == list_end)
-- mark = '.'; /* use hw_qtd_next */
-- /* else alt_next points to some other qtd */
-- }
-- scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
-- hw_curr = (mark == '*') ? hc32_to_cpup(fotg210, &hw->hw_current) : 0;
-- temp = scnprintf(next, size,
-- "qh/%p dev%d %cs ep%d %08x %08x(%08x%c %s nak%d)",
-- qh, scratch & 0x007f,
-- speed_char(scratch),
-- (scratch >> 8) & 0x000f,
-- scratch, hc32_to_cpup(fotg210, &hw->hw_info2),
-- hc32_to_cpup(fotg210, &hw->hw_token), mark,
-- (cpu_to_hc32(fotg210, QTD_TOGGLE) & hw->hw_token)
-- ? "data1" : "data0",
-- (hc32_to_cpup(fotg210, &hw->hw_alt_next) >> 1) & 0x0f);
-- size -= temp;
-- next += temp;
--
-- /* hc may be modifying the list as we read it ... */
-- list_for_each_entry(td, &qh->qtd_list, qtd_list) {
-- scratch = hc32_to_cpup(fotg210, &td->hw_token);
-- mark = ' ';
-- if (hw_curr == td->qtd_dma)
-- mark = '*';
-- else if (hw->hw_qtd_next == cpu_to_hc32(fotg210, td->qtd_dma))
-- mark = '+';
-- else if (QTD_LENGTH(scratch)) {
-- if (td->hw_alt_next == fotg210->async->hw->hw_alt_next)
-- mark = '#';
-- else if (td->hw_alt_next != list_end)
-- mark = '/';
-- }
-- temp = snprintf(next, size,
-- "\n\t%p%c%s len=%d %08x urb %p",
-- td, mark, ({ char *tmp;
-- switch ((scratch>>8)&0x03) {
-- case 0:
-- tmp = "out";
-- break;
-- case 1:
-- tmp = "in";
-- break;
-- case 2:
-- tmp = "setup";
-- break;
-- default:
-- tmp = "?";
-- break;
-- } tmp; }),
-- (scratch >> 16) & 0x7fff,
-- scratch,
-- td->urb);
-- if (size < temp)
-- temp = size;
-- size -= temp;
-- next += temp;
-- }
--
-- temp = snprintf(next, size, "\n");
-- if (size < temp)
-- temp = size;
--
-- size -= temp;
-- next += temp;
--
-- *sizep = size;
-- *nextp = next;
--}
--
--static ssize_t fill_async_buffer(struct debug_buffer *buf)
--{
-- struct usb_hcd *hcd;
-- struct fotg210_hcd *fotg210;
-- unsigned long flags;
-- unsigned temp, size;
-- char *next;
-- struct fotg210_qh *qh;
--
-- hcd = bus_to_hcd(buf->bus);
-- fotg210 = hcd_to_fotg210(hcd);
-- next = buf->output_buf;
-- size = buf->alloc_size;
--
-- *next = 0;
--
-- /* dumps a snapshot of the async schedule.
-- * usually empty except for long-term bulk reads, or head.
-- * one QH per line, and TDs we know about
-- */
-- spin_lock_irqsave(&fotg210->lock, flags);
-- for (qh = fotg210->async->qh_next.qh; size > 0 && qh;
-- qh = qh->qh_next.qh)
-- qh_lines(fotg210, qh, &next, &size);
-- if (fotg210->async_unlink && size > 0) {
-- temp = scnprintf(next, size, "\nunlink =\n");
-- size -= temp;
-- next += temp;
--
-- for (qh = fotg210->async_unlink; size > 0 && qh;
-- qh = qh->unlink_next)
-- qh_lines(fotg210, qh, &next, &size);
-- }
-- spin_unlock_irqrestore(&fotg210->lock, flags);
--
-- return strlen(buf->output_buf);
--}
--
--/* count tds, get ep direction */
--static unsigned output_buf_tds_dir(char *buf, struct fotg210_hcd *fotg210,
-- struct fotg210_qh_hw *hw, struct fotg210_qh *qh, unsigned size)
--{
-- u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
-- struct fotg210_qtd *qtd;
-- char *type = "";
-- unsigned temp = 0;
--
-- /* count tds, get ep direction */
-- list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
-- temp++;
-- switch ((hc32_to_cpu(fotg210, qtd->hw_token) >> 8) & 0x03) {
-- case 0:
-- type = "out";
-- continue;
-- case 1:
-- type = "in";
-- continue;
-- }
-- }
--
-- return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
-- speed_char(scratch), scratch & 0x007f,
-- (scratch >> 8) & 0x000f, type, qh->usecs,
-- qh->c_usecs, temp, (scratch >> 16) & 0x7ff);
--}
--
--#define DBG_SCHED_LIMIT 64
--static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
--{
-- struct usb_hcd *hcd;
-- struct fotg210_hcd *fotg210;
-- unsigned long flags;
-- union fotg210_shadow p, *seen;
-- unsigned temp, size, seen_count;
-- char *next;
-- unsigned i;
-- __hc32 tag;
--
-- seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
-- if (!seen)
-- return 0;
--
-- seen_count = 0;
--
-- hcd = bus_to_hcd(buf->bus);
-- fotg210 = hcd_to_fotg210(hcd);
-- next = buf->output_buf;
-- size = buf->alloc_size;
--
-- temp = scnprintf(next, size, "size = %d\n", fotg210->periodic_size);
-- size -= temp;
-- next += temp;
--
-- /* dump a snapshot of the periodic schedule.
-- * iso changes, interrupt usually doesn't.
-- */
-- spin_lock_irqsave(&fotg210->lock, flags);
-- for (i = 0; i < fotg210->periodic_size; i++) {
-- p = fotg210->pshadow[i];
-- if (likely(!p.ptr))
-- continue;
--
-- tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
--
-- temp = scnprintf(next, size, "%4d: ", i);
-- size -= temp;
-- next += temp;
--
-- do {
-- struct fotg210_qh_hw *hw;
--
-- switch (hc32_to_cpu(fotg210, tag)) {
-- case Q_TYPE_QH:
-- hw = p.qh->hw;
-- temp = scnprintf(next, size, " qh%d-%04x/%p",
-- p.qh->period,
-- hc32_to_cpup(fotg210,
-- &hw->hw_info2)
-- /* uframe masks */
-- & (QH_CMASK | QH_SMASK),
-- p.qh);
-- size -= temp;
-- next += temp;
-- /* don't repeat what follows this qh */
-- for (temp = 0; temp < seen_count; temp++) {
-- if (seen[temp].ptr != p.ptr)
-- continue;
-- if (p.qh->qh_next.ptr) {
-- temp = scnprintf(next, size,
-- " ...");
-- size -= temp;
-- next += temp;
-- }
-- break;
-- }
-- /* show more info the first time around */
-- if (temp == seen_count) {
-- temp = output_buf_tds_dir(next,
-- fotg210, hw,
-- p.qh, size);
--
-- if (seen_count < DBG_SCHED_LIMIT)
-- seen[seen_count++].qh = p.qh;
-- } else
-- temp = 0;
-- tag = Q_NEXT_TYPE(fotg210, hw->hw_next);
-- p = p.qh->qh_next;
-- break;
-- case Q_TYPE_FSTN:
-- temp = scnprintf(next, size,
-- " fstn-%8x/%p",
-- p.fstn->hw_prev, p.fstn);
-- tag = Q_NEXT_TYPE(fotg210, p.fstn->hw_next);
-- p = p.fstn->fstn_next;
-- break;
-- case Q_TYPE_ITD:
-- temp = scnprintf(next, size,
-- " itd/%p", p.itd);
-- tag = Q_NEXT_TYPE(fotg210, p.itd->hw_next);
-- p = p.itd->itd_next;
-- break;
-- }
-- size -= temp;
-- next += temp;
-- } while (p.ptr);
--
-- temp = scnprintf(next, size, "\n");
-- size -= temp;
-- next += temp;
-- }
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- kfree(seen);
--
-- return buf->alloc_size - size;
--}
--#undef DBG_SCHED_LIMIT
--
--static const char *rh_state_string(struct fotg210_hcd *fotg210)
--{
-- switch (fotg210->rh_state) {
-- case FOTG210_RH_HALTED:
-- return "halted";
-- case FOTG210_RH_SUSPENDED:
-- return "suspended";
-- case FOTG210_RH_RUNNING:
-- return "running";
-- case FOTG210_RH_STOPPING:
-- return "stopping";
-- }
-- return "?";
--}
--
--static ssize_t fill_registers_buffer(struct debug_buffer *buf)
--{
-- struct usb_hcd *hcd;
-- struct fotg210_hcd *fotg210;
-- unsigned long flags;
-- unsigned temp, size, i;
-- char *next, scratch[80];
-- static const char fmt[] = "%*s\n";
-- static const char label[] = "";
--
-- hcd = bus_to_hcd(buf->bus);
-- fotg210 = hcd_to_fotg210(hcd);
-- next = buf->output_buf;
-- size = buf->alloc_size;
--
-- spin_lock_irqsave(&fotg210->lock, flags);
--
-- if (!HCD_HW_ACCESSIBLE(hcd)) {
-- size = scnprintf(next, size,
-- "bus %s, device %s\n"
-- "%s\n"
-- "SUSPENDED(no register access)\n",
-- hcd->self.controller->bus->name,
-- dev_name(hcd->self.controller),
-- hcd->product_desc);
-- goto done;
-- }
--
-- /* Capability Registers */
-- i = HC_VERSION(fotg210, fotg210_readl(fotg210,
-- &fotg210->caps->hc_capbase));
-- temp = scnprintf(next, size,
-- "bus %s, device %s\n"
-- "%s\n"
-- "EHCI %x.%02x, rh state %s\n",
-- hcd->self.controller->bus->name,
-- dev_name(hcd->self.controller),
-- hcd->product_desc,
-- i >> 8, i & 0x0ff, rh_state_string(fotg210));
-- size -= temp;
-- next += temp;
--
-- /* FIXME interpret both types of params */
-- i = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
-- temp = scnprintf(next, size, "structural params 0x%08x\n", i);
-- size -= temp;
-- next += temp;
--
-- i = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
-- temp = scnprintf(next, size, "capability params 0x%08x\n", i);
-- size -= temp;
-- next += temp;
--
-- /* Operational Registers */
-- temp = dbg_status_buf(scratch, sizeof(scratch), label,
-- fotg210_readl(fotg210, &fotg210->regs->status));
-- temp = scnprintf(next, size, fmt, temp, scratch);
-- size -= temp;
-- next += temp;
--
-- temp = dbg_command_buf(scratch, sizeof(scratch), label,
-- fotg210_readl(fotg210, &fotg210->regs->command));
-- temp = scnprintf(next, size, fmt, temp, scratch);
-- size -= temp;
-- next += temp;
--
-- temp = dbg_intr_buf(scratch, sizeof(scratch), label,
-- fotg210_readl(fotg210, &fotg210->regs->intr_enable));
-- temp = scnprintf(next, size, fmt, temp, scratch);
-- size -= temp;
-- next += temp;
--
-- temp = scnprintf(next, size, "uframe %04x\n",
-- fotg210_read_frame_index(fotg210));
-- size -= temp;
-- next += temp;
--
-- if (fotg210->async_unlink) {
-- temp = scnprintf(next, size, "async unlink qh %p\n",
-- fotg210->async_unlink);
-- size -= temp;
-- next += temp;
-- }
--
--#ifdef FOTG210_STATS
-- temp = scnprintf(next, size,
-- "irq normal %ld err %ld iaa %ld(lost %ld)\n",
-- fotg210->stats.normal, fotg210->stats.error,
-- fotg210->stats.iaa, fotg210->stats.lost_iaa);
-- size -= temp;
-- next += temp;
--
-- temp = scnprintf(next, size, "complete %ld unlink %ld\n",
-- fotg210->stats.complete, fotg210->stats.unlink);
-- size -= temp;
-- next += temp;
--#endif
--
--done:
-- spin_unlock_irqrestore(&fotg210->lock, flags);
--
-- return buf->alloc_size - size;
--}
--
--static struct debug_buffer
--*alloc_buffer(struct usb_bus *bus, ssize_t (*fill_func)(struct debug_buffer *))
--{
-- struct debug_buffer *buf;
--
-- buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
--
-- if (buf) {
-- buf->bus = bus;
-- buf->fill_func = fill_func;
-- mutex_init(&buf->mutex);
-- buf->alloc_size = PAGE_SIZE;
-- }
--
-- return buf;
--}
--
--static int fill_buffer(struct debug_buffer *buf)
--{
-- int ret = 0;
--
-- if (!buf->output_buf)
-- buf->output_buf = vmalloc(buf->alloc_size);
--
-- if (!buf->output_buf) {
-- ret = -ENOMEM;
-- goto out;
-- }
--
-- ret = buf->fill_func(buf);
--
-- if (ret >= 0) {
-- buf->count = ret;
-- ret = 0;
-- }
--
--out:
-- return ret;
--}
--
--static ssize_t debug_output(struct file *file, char __user *user_buf,
-- size_t len, loff_t *offset)
--{
-- struct debug_buffer *buf = file->private_data;
-- int ret = 0;
--
-- mutex_lock(&buf->mutex);
-- if (buf->count == 0) {
-- ret = fill_buffer(buf);
-- if (ret != 0) {
-- mutex_unlock(&buf->mutex);
-- goto out;
-- }
-- }
-- mutex_unlock(&buf->mutex);
--
-- ret = simple_read_from_buffer(user_buf, len, offset,
-- buf->output_buf, buf->count);
--
--out:
-- return ret;
--
--}
--
--static int debug_close(struct inode *inode, struct file *file)
--{
-- struct debug_buffer *buf = file->private_data;
--
-- if (buf) {
-- vfree(buf->output_buf);
-- kfree(buf);
-- }
--
-- return 0;
--}
--static int debug_async_open(struct inode *inode, struct file *file)
--{
-- file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
--
-- return file->private_data ? 0 : -ENOMEM;
--}
--
--static int debug_periodic_open(struct inode *inode, struct file *file)
--{
-- struct debug_buffer *buf;
--
-- buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
-- if (!buf)
-- return -ENOMEM;
--
-- buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
-- file->private_data = buf;
-- return 0;
--}
--
--static int debug_registers_open(struct inode *inode, struct file *file)
--{
-- file->private_data = alloc_buffer(inode->i_private,
-- fill_registers_buffer);
--
-- return file->private_data ? 0 : -ENOMEM;
--}
--
--static inline void create_debug_files(struct fotg210_hcd *fotg210)
--{
-- struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
-- struct dentry *root;
--
-- root = debugfs_create_dir(bus->bus_name, fotg210_debug_root);
--
-- debugfs_create_file("async", S_IRUGO, root, bus, &debug_async_fops);
-- debugfs_create_file("periodic", S_IRUGO, root, bus,
-- &debug_periodic_fops);
-- debugfs_create_file("registers", S_IRUGO, root, bus,
-- &debug_registers_fops);
--}
--
--static inline void remove_debug_files(struct fotg210_hcd *fotg210)
--{
-- struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
--
-- debugfs_lookup_and_remove(bus->bus_name, fotg210_debug_root);
--}
--
--/* handshake - spin reading hc until handshake completes or fails
-- * @ptr: address of hc register to be read
-- * @mask: bits to look at in result of read
-- * @done: value of those bits when handshake succeeds
-- * @usec: timeout in microseconds
-- *
-- * Returns negative errno, or zero on success
-- *
-- * Success happens when the "mask" bits have the specified value (hardware
-- * handshake done). There are two failure modes: "usec" have passed (major
-- * hardware flakeout), or the register reads as all-ones (hardware removed).
-- *
-- * That last failure should_only happen in cases like physical cardbus eject
-- * before driver shutdown. But it also seems to be caused by bugs in cardbus
-- * bridge shutdown: shutting down the bridge before the devices using it.
-- */
--static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
-- u32 mask, u32 done, int usec)
--{
-- u32 result;
-- int ret;
--
-- ret = readl_poll_timeout_atomic(ptr, result,
-- ((result & mask) == done ||
-- result == U32_MAX), 1, usec);
-- if (result == U32_MAX) /* card removed */
-- return -ENODEV;
--
-- return ret;
--}
--
--/* Force HC to halt state from unknown (EHCI spec section 2.3).
-- * Must be called with interrupts enabled and the lock not held.
-- */
--static int fotg210_halt(struct fotg210_hcd *fotg210)
--{
-- u32 temp;
--
-- spin_lock_irq(&fotg210->lock);
--
-- /* disable any irqs left enabled by previous code */
-- fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
--
-- /*
-- * This routine gets called during probe before fotg210->command
-- * has been initialized, so we can't rely on its value.
-- */
-- fotg210->command &= ~CMD_RUN;
-- temp = fotg210_readl(fotg210, &fotg210->regs->command);
-- temp &= ~(CMD_RUN | CMD_IAAD);
-- fotg210_writel(fotg210, temp, &fotg210->regs->command);
--
-- spin_unlock_irq(&fotg210->lock);
-- synchronize_irq(fotg210_to_hcd(fotg210)->irq);
--
-- return handshake(fotg210, &fotg210->regs->status,
-- STS_HALT, STS_HALT, 16 * 125);
--}
--
--/* Reset a non-running (STS_HALT == 1) controller.
-- * Must be called with interrupts enabled and the lock not held.
-- */
--static int fotg210_reset(struct fotg210_hcd *fotg210)
--{
-- int retval;
-- u32 command = fotg210_readl(fotg210, &fotg210->regs->command);
--
-- /* If the EHCI debug controller is active, special care must be
-- * taken before and after a host controller reset
-- */
-- if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
-- fotg210->debug = NULL;
--
-- command |= CMD_RESET;
-- dbg_cmd(fotg210, "reset", command);
-- fotg210_writel(fotg210, command, &fotg210->regs->command);
-- fotg210->rh_state = FOTG210_RH_HALTED;
-- fotg210->next_statechange = jiffies;
-- retval = handshake(fotg210, &fotg210->regs->command,
-- CMD_RESET, 0, 250 * 1000);
--
-- if (retval)
-- return retval;
--
-- if (fotg210->debug)
-- dbgp_external_startup(fotg210_to_hcd(fotg210));
--
-- fotg210->port_c_suspend = fotg210->suspended_ports =
-- fotg210->resuming_ports = 0;
-- return retval;
--}
--
--/* Idle the controller (turn off the schedules).
-- * Must be called with interrupts enabled and the lock not held.
-- */
--static void fotg210_quiesce(struct fotg210_hcd *fotg210)
--{
-- u32 temp;
--
-- if (fotg210->rh_state != FOTG210_RH_RUNNING)
-- return;
--
-- /* wait for any schedule enables/disables to take effect */
-- temp = (fotg210->command << 10) & (STS_ASS | STS_PSS);
-- handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, temp,
-- 16 * 125);
--
-- /* then disable anything that's still active */
-- spin_lock_irq(&fotg210->lock);
-- fotg210->command &= ~(CMD_ASE | CMD_PSE);
-- fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-- spin_unlock_irq(&fotg210->lock);
--
-- /* hardware can take 16 microframes to turn off ... */
-- handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, 0,
-- 16 * 125);
--}
--
--static void end_unlink_async(struct fotg210_hcd *fotg210);
--static void unlink_empty_async(struct fotg210_hcd *fotg210);
--static void fotg210_work(struct fotg210_hcd *fotg210);
--static void start_unlink_intr(struct fotg210_hcd *fotg210,
-- struct fotg210_qh *qh);
--static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
--
--/* Set a bit in the USBCMD register */
--static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
--{
-- fotg210->command |= bit;
-- fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
--
-- /* unblock posted write */
-- fotg210_readl(fotg210, &fotg210->regs->command);
--}
--
--/* Clear a bit in the USBCMD register */
--static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
--{
-- fotg210->command &= ~bit;
-- fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
--
-- /* unblock posted write */
-- fotg210_readl(fotg210, &fotg210->regs->command);
--}
--
--/* EHCI timer support... Now using hrtimers.
-- *
-- * Lots of different events are triggered from fotg210->hrtimer. Whenever
-- * the timer routine runs, it checks each possible event; events that are
-- * currently enabled and whose expiration time has passed get handled.
-- * The set of enabled events is stored as a collection of bitflags in
-- * fotg210->enabled_hrtimer_events, and they are numbered in order of
-- * increasing delay values (ranging between 1 ms and 100 ms).
-- *
-- * Rather than implementing a sorted list or tree of all pending events,
-- * we keep track only of the lowest-numbered pending event, in
-- * fotg210->next_hrtimer_event. Whenever fotg210->hrtimer gets restarted, its
-- * expiration time is set to the timeout value for this event.
-- *
-- * As a result, events might not get handled right away; the actual delay
-- * could be anywhere up to twice the requested delay. This doesn't
-- * matter, because none of the events are especially time-critical. The
-- * ones that matter most all have a delay of 1 ms, so they will be
-- * handled after 2 ms at most, which is okay. In addition to this, we
-- * allow for an expiration range of 1 ms.
-- */
--
--/* Delay lengths for the hrtimer event types.
-- * Keep this list sorted by delay length, in the same order as
-- * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
-- */
--static unsigned event_delays_ns[] = {
-- 1 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_POLL_ASS */
-- 1 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_POLL_PSS */
-- 1 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_POLL_DEAD */
-- 1125 * NSEC_PER_USEC, /* FOTG210_HRTIMER_UNLINK_INTR */
-- 2 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_FREE_ITDS */
-- 6 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_ASYNC_UNLINKS */
-- 10 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_IAA_WATCHDOG */
-- 10 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_DISABLE_PERIODIC */
-- 15 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_DISABLE_ASYNC */
-- 100 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_IO_WATCHDOG */
--};
--
--/* Enable a pending hrtimer event */
--static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
-- bool resched)
--{
-- ktime_t *timeout = &fotg210->hr_timeouts[event];
--
-- if (resched)
-- *timeout = ktime_add(ktime_get(), event_delays_ns[event]);
-- fotg210->enabled_hrtimer_events |= (1 << event);
--
-- /* Track only the lowest-numbered pending event */
-- if (event < fotg210->next_hrtimer_event) {
-- fotg210->next_hrtimer_event = event;
-- hrtimer_start_range_ns(&fotg210->hrtimer, *timeout,
-- NSEC_PER_MSEC, HRTIMER_MODE_ABS);
-- }
--}
--
--
--/* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
--static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
--{
-- unsigned actual, want;
--
-- /* Don't enable anything if the controller isn't running (e.g., died) */
-- if (fotg210->rh_state != FOTG210_RH_RUNNING)
-- return;
--
-- want = (fotg210->command & CMD_ASE) ? STS_ASS : 0;
-- actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_ASS;
--
-- if (want != actual) {
--
-- /* Poll again later, but give up after about 20 ms */
-- if (fotg210->ASS_poll_count++ < 20) {
-- fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_ASS,
-- true);
-- return;
-- }
-- fotg210_dbg(fotg210, "Waited too long for the async schedule status (%x/%x), giving up\n",
-- want, actual);
-- }
-- fotg210->ASS_poll_count = 0;
--
-- /* The status is up-to-date; restart or stop the schedule as needed */
-- if (want == 0) { /* Stopped */
-- if (fotg210->async_count > 0)
-- fotg210_set_command_bit(fotg210, CMD_ASE);
--
-- } else { /* Running */
-- if (fotg210->async_count == 0) {
--
-- /* Turn off the schedule after a while */
-- fotg210_enable_event(fotg210,
-- FOTG210_HRTIMER_DISABLE_ASYNC,
-- true);
-- }
-- }
--}
--
--/* Turn off the async schedule after a brief delay */
--static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
--{
-- fotg210_clear_command_bit(fotg210, CMD_ASE);
--}
--
--
--/* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
--static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
--{
-- unsigned actual, want;
--
-- /* Don't do anything if the controller isn't running (e.g., died) */
-- if (fotg210->rh_state != FOTG210_RH_RUNNING)
-- return;
--
-- want = (fotg210->command & CMD_PSE) ? STS_PSS : 0;
-- actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_PSS;
--
-- if (want != actual) {
--
-- /* Poll again later, but give up after about 20 ms */
-- if (fotg210->PSS_poll_count++ < 20) {
-- fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_PSS,
-- true);
-- return;
-- }
-- fotg210_dbg(fotg210, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
-- want, actual);
-- }
-- fotg210->PSS_poll_count = 0;
--
-- /* The status is up-to-date; restart or stop the schedule as needed */
-- if (want == 0) { /* Stopped */
-- if (fotg210->periodic_count > 0)
-- fotg210_set_command_bit(fotg210, CMD_PSE);
--
-- } else { /* Running */
-- if (fotg210->periodic_count == 0) {
--
-- /* Turn off the schedule after a while */
-- fotg210_enable_event(fotg210,
-- FOTG210_HRTIMER_DISABLE_PERIODIC,
-- true);
-- }
-- }
--}
--
--/* Turn off the periodic schedule after a brief delay */
--static void fotg210_disable_PSE(struct fotg210_hcd *fotg210)
--{
-- fotg210_clear_command_bit(fotg210, CMD_PSE);
--}
--
--
--/* Poll the STS_HALT status bit; see when a dead controller stops */
--static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
--{
-- if (!(fotg210_readl(fotg210, &fotg210->regs->status) & STS_HALT)) {
--
-- /* Give up after a few milliseconds */
-- if (fotg210->died_poll_count++ < 5) {
-- /* Try again later */
-- fotg210_enable_event(fotg210,
-- FOTG210_HRTIMER_POLL_DEAD, true);
-- return;
-- }
-- fotg210_warn(fotg210, "Waited too long for the controller to stop, giving up\n");
-- }
--
-- /* Clean up the mess */
-- fotg210->rh_state = FOTG210_RH_HALTED;
-- fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-- fotg210_work(fotg210);
-- end_unlink_async(fotg210);
--
-- /* Not in process context, so don't try to reset the controller */
--}
--
--
--/* Handle unlinked interrupt QHs once they are gone from the hardware */
--static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
--{
-- bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
--
-- /*
-- * Process all the QHs on the intr_unlink list that were added
-- * before the current unlink cycle began. The list is in
-- * temporal order, so stop when we reach the first entry in the
-- * current cycle. But if the root hub isn't running then
-- * process all the QHs on the list.
-- */
-- fotg210->intr_unlinking = true;
-- while (fotg210->intr_unlink) {
-- struct fotg210_qh *qh = fotg210->intr_unlink;
--
-- if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
-- break;
-- fotg210->intr_unlink = qh->unlink_next;
-- qh->unlink_next = NULL;
-- end_unlink_intr(fotg210, qh);
-- }
--
-- /* Handle remaining entries later */
-- if (fotg210->intr_unlink) {
-- fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-- true);
-- ++fotg210->intr_unlink_cycle;
-- }
-- fotg210->intr_unlinking = false;
--}
--
--
--/* Start another free-iTDs/siTDs cycle */
--static void start_free_itds(struct fotg210_hcd *fotg210)
--{
-- if (!(fotg210->enabled_hrtimer_events &
-- BIT(FOTG210_HRTIMER_FREE_ITDS))) {
-- fotg210->last_itd_to_free = list_entry(
-- fotg210->cached_itd_list.prev,
-- struct fotg210_itd, itd_list);
-- fotg210_enable_event(fotg210, FOTG210_HRTIMER_FREE_ITDS, true);
-- }
--}
--
--/* Wait for controller to stop using old iTDs and siTDs */
--static void end_free_itds(struct fotg210_hcd *fotg210)
--{
-- struct fotg210_itd *itd, *n;
--
-- if (fotg210->rh_state < FOTG210_RH_RUNNING)
-- fotg210->last_itd_to_free = NULL;
--
-- list_for_each_entry_safe(itd, n, &fotg210->cached_itd_list, itd_list) {
-- list_del(&itd->itd_list);
-- dma_pool_free(fotg210->itd_pool, itd, itd->itd_dma);
-- if (itd == fotg210->last_itd_to_free)
-- break;
-- }
--
-- if (!list_empty(&fotg210->cached_itd_list))
-- start_free_itds(fotg210);
--}
--
--
--/* Handle lost (or very late) IAA interrupts */
--static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
--{
-- if (fotg210->rh_state != FOTG210_RH_RUNNING)
-- return;
--
-- /*
-- * Lost IAA irqs wedge things badly; seen first with a vt8235.
-- * So we need this watchdog, but must protect it against both
-- * (a) SMP races against real IAA firing and retriggering, and
-- * (b) clean HC shutdown, when IAA watchdog was pending.
-- */
-- if (fotg210->async_iaa) {
-- u32 cmd, status;
--
-- /* If we get here, IAA is *REALLY* late. It's barely
-- * conceivable that the system is so busy that CMD_IAAD
-- * is still legitimately set, so let's be sure it's
-- * clear before we read STS_IAA. (The HC should clear
-- * CMD_IAAD when it sets STS_IAA.)
-- */
-- cmd = fotg210_readl(fotg210, &fotg210->regs->command);
--
-- /*
-- * If IAA is set here it either legitimately triggered
-- * after the watchdog timer expired (_way_ late, so we'll
-- * still count it as lost) ... or a silicon erratum:
-- * - VIA seems to set IAA without triggering the IRQ;
-- * - IAAD potentially cleared without setting IAA.
-- */
-- status = fotg210_readl(fotg210, &fotg210->regs->status);
-- if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
-- INCR(fotg210->stats.lost_iaa);
-- fotg210_writel(fotg210, STS_IAA,
-- &fotg210->regs->status);
-- }
--
-- fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",
-- status, cmd);
-- end_unlink_async(fotg210);
-- }
--}
--
--
--/* Enable the I/O watchdog, if appropriate */
--static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
--{
-- /* Not needed if the controller isn't running or it's already enabled */
-- if (fotg210->rh_state != FOTG210_RH_RUNNING ||
-- (fotg210->enabled_hrtimer_events &
-- BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
-- return;
--
-- /*
-- * Isochronous transfers always need the watchdog.
-- * For other sorts we use it only if the flag is set.
-- */
-- if (fotg210->isoc_count > 0 || (fotg210->need_io_watchdog &&
-- fotg210->async_count + fotg210->intr_count > 0))
-- fotg210_enable_event(fotg210, FOTG210_HRTIMER_IO_WATCHDOG,
-- true);
--}
--
--
--/* Handler functions for the hrtimer event types.
-- * Keep this array in the same order as the event types indexed by
-- * enum fotg210_hrtimer_event in fotg210.h.
-- */
--static void (*event_handlers[])(struct fotg210_hcd *) = {
-- fotg210_poll_ASS, /* FOTG210_HRTIMER_POLL_ASS */
-- fotg210_poll_PSS, /* FOTG210_HRTIMER_POLL_PSS */
-- fotg210_handle_controller_death, /* FOTG210_HRTIMER_POLL_DEAD */
-- fotg210_handle_intr_unlinks, /* FOTG210_HRTIMER_UNLINK_INTR */
-- end_free_itds, /* FOTG210_HRTIMER_FREE_ITDS */
-- unlink_empty_async, /* FOTG210_HRTIMER_ASYNC_UNLINKS */
-- fotg210_iaa_watchdog, /* FOTG210_HRTIMER_IAA_WATCHDOG */
-- fotg210_disable_PSE, /* FOTG210_HRTIMER_DISABLE_PERIODIC */
-- fotg210_disable_ASE, /* FOTG210_HRTIMER_DISABLE_ASYNC */
-- fotg210_work, /* FOTG210_HRTIMER_IO_WATCHDOG */
--};
--
--static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
--{
-- struct fotg210_hcd *fotg210 =
-- container_of(t, struct fotg210_hcd, hrtimer);
-- ktime_t now;
-- unsigned long events;
-- unsigned long flags;
-- unsigned e;
--
-- spin_lock_irqsave(&fotg210->lock, flags);
--
-- events = fotg210->enabled_hrtimer_events;
-- fotg210->enabled_hrtimer_events = 0;
-- fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
--
-- /*
-- * Check each pending event. If its time has expired, handle
-- * the event; otherwise re-enable it.
-- */
-- now = ktime_get();
-- for_each_set_bit(e, &events, FOTG210_HRTIMER_NUM_EVENTS) {
-- if (ktime_compare(now, fotg210->hr_timeouts[e]) >= 0)
-- event_handlers[e](fotg210);
-- else
-- fotg210_enable_event(fotg210, e, false);
-- }
--
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- return HRTIMER_NORESTART;
--}
--
--#define fotg210_bus_suspend NULL
--#define fotg210_bus_resume NULL
--
--static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
-- u32 __iomem *status_reg, int port_status)
--{
-- if (!(port_status & PORT_CONNECT))
-- return port_status;
--
-- /* if reset finished and it's still not enabled -- handoff */
-- if (!(port_status & PORT_PE))
-- /* with integrated TT, there's nobody to hand it to! */
-- fotg210_dbg(fotg210, "Failed to enable port %d on root hub TT\n",
-- index + 1);
-- else
-- fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
-- index + 1);
--
-- return port_status;
--}
--
--
--/* build "status change" packet (one or two bytes) from HC registers */
--
--static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- u32 temp, status;
-- u32 mask;
-- int retval = 1;
-- unsigned long flags;
--
-- /* init status to no-changes */
-- buf[0] = 0;
--
-- /* Inform the core about resumes-in-progress by returning
-- * a non-zero value even if there are no status changes.
-- */
-- status = fotg210->resuming_ports;
--
-- mask = PORT_CSC | PORT_PEC;
-- /* PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND */
--
-- /* no hub change reports (bit 0) for now (power, ...) */
--
-- /* port N changes (bit N)? */
-- spin_lock_irqsave(&fotg210->lock, flags);
--
-- temp = fotg210_readl(fotg210, &fotg210->regs->port_status);
--
-- /*
-- * Return status information even for ports with OWNER set.
-- * Otherwise hub_wq wouldn't see the disconnect event when a
-- * high-speed device is switched over to the companion
-- * controller by the user.
-- */
--
-- if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend) ||
-- (fotg210->reset_done[0] &&
-- time_after_eq(jiffies, fotg210->reset_done[0]))) {
-- buf[0] |= 1 << 1;
-- status = STS_PCD;
-- }
-- /* FIXME autosuspend idle root hubs */
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- return status ? retval : 0;
--}
--
--static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
-- struct usb_hub_descriptor *desc)
--{
-- int ports = HCS_N_PORTS(fotg210->hcs_params);
-- u16 temp;
--
-- desc->bDescriptorType = USB_DT_HUB;
-- desc->bPwrOn2PwrGood = 10; /* fotg210 1.0, 2.3.9 says 20ms max */
-- desc->bHubContrCurrent = 0;
--
-- desc->bNbrPorts = ports;
-- temp = 1 + (ports / 8);
-- desc->bDescLength = 7 + 2 * temp;
--
-- /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
-- memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
-- memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
--
-- temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */
-- temp |= HUB_CHAR_NO_LPSM; /* no power switching */
-- desc->wHubCharacteristics = cpu_to_le16(temp);
--}
--
--static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
-- u16 wIndex, char *buf, u16 wLength)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- int ports = HCS_N_PORTS(fotg210->hcs_params);
-- u32 __iomem *status_reg = &fotg210->regs->port_status;
-- u32 temp, temp1, status;
-- unsigned long flags;
-- int retval = 0;
-- unsigned selector;
--
-- /*
-- * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR.
-- * HCS_INDICATOR may say we can change LEDs to off/amber/green.
-- * (track current state ourselves) ... blink for diagnostics,
-- * power, "this is the one", etc. EHCI spec supports this.
-- */
--
-- spin_lock_irqsave(&fotg210->lock, flags);
-- switch (typeReq) {
-- case ClearHubFeature:
-- switch (wValue) {
-- case C_HUB_LOCAL_POWER:
-- case C_HUB_OVER_CURRENT:
-- /* no hub-wide feature/status flags */
-- break;
-- default:
-- goto error;
-- }
-- break;
-- case ClearPortFeature:
-- if (!wIndex || wIndex > ports)
-- goto error;
-- wIndex--;
-- temp = fotg210_readl(fotg210, status_reg);
-- temp &= ~PORT_RWC_BITS;
--
-- /*
-- * Even if OWNER is set, so the port is owned by the
-- * companion controller, hub_wq needs to be able to clear
-- * the port-change status bits (especially
-- * USB_PORT_STAT_C_CONNECTION).
-- */
--
-- switch (wValue) {
-- case USB_PORT_FEAT_ENABLE:
-- fotg210_writel(fotg210, temp & ~PORT_PE, status_reg);
-- break;
-- case USB_PORT_FEAT_C_ENABLE:
-- fotg210_writel(fotg210, temp | PORT_PEC, status_reg);
-- break;
-- case USB_PORT_FEAT_SUSPEND:
-- if (temp & PORT_RESET)
-- goto error;
-- if (!(temp & PORT_SUSPEND))
-- break;
-- if ((temp & PORT_PE) == 0)
-- goto error;
--
-- /* resume signaling for 20 msec */
-- fotg210_writel(fotg210, temp | PORT_RESUME, status_reg);
-- fotg210->reset_done[wIndex] = jiffies
-- + msecs_to_jiffies(USB_RESUME_TIMEOUT);
-- break;
-- case USB_PORT_FEAT_C_SUSPEND:
-- clear_bit(wIndex, &fotg210->port_c_suspend);
-- break;
-- case USB_PORT_FEAT_C_CONNECTION:
-- fotg210_writel(fotg210, temp | PORT_CSC, status_reg);
-- break;
-- case USB_PORT_FEAT_C_OVER_CURRENT:
-- fotg210_writel(fotg210, temp | OTGISR_OVC,
-- &fotg210->regs->otgisr);
-- break;
-- case USB_PORT_FEAT_C_RESET:
-- /* GetPortStatus clears reset */
-- break;
-- default:
-- goto error;
-- }
-- fotg210_readl(fotg210, &fotg210->regs->command);
-- break;
-- case GetHubDescriptor:
-- fotg210_hub_descriptor(fotg210, (struct usb_hub_descriptor *)
-- buf);
-- break;
-- case GetHubStatus:
-- /* no hub-wide feature/status flags */
-- memset(buf, 0, 4);
-- /*cpu_to_le32s ((u32 *) buf); */
-- break;
-- case GetPortStatus:
-- if (!wIndex || wIndex > ports)
-- goto error;
-- wIndex--;
-- status = 0;
-- temp = fotg210_readl(fotg210, status_reg);
--
-- /* wPortChange bits */
-- if (temp & PORT_CSC)
-- status |= USB_PORT_STAT_C_CONNECTION << 16;
-- if (temp & PORT_PEC)
-- status |= USB_PORT_STAT_C_ENABLE << 16;
--
-- temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
-- if (temp1 & OTGISR_OVC)
-- status |= USB_PORT_STAT_C_OVERCURRENT << 16;
--
-- /* whoever resumes must GetPortStatus to complete it!! */
-- if (temp & PORT_RESUME) {
--
-- /* Remote Wakeup received? */
-- if (!fotg210->reset_done[wIndex]) {
-- /* resume signaling for 20 msec */
-- fotg210->reset_done[wIndex] = jiffies
-- + msecs_to_jiffies(20);
-- /* check the port again */
-- mod_timer(&fotg210_to_hcd(fotg210)->rh_timer,
-- fotg210->reset_done[wIndex]);
-- }
--
-- /* resume completed? */
-- else if (time_after_eq(jiffies,
-- fotg210->reset_done[wIndex])) {
-- clear_bit(wIndex, &fotg210->suspended_ports);
-- set_bit(wIndex, &fotg210->port_c_suspend);
-- fotg210->reset_done[wIndex] = 0;
--
-- /* stop resume signaling */
-- temp = fotg210_readl(fotg210, status_reg);
-- fotg210_writel(fotg210, temp &
-- ~(PORT_RWC_BITS | PORT_RESUME),
-- status_reg);
-- clear_bit(wIndex, &fotg210->resuming_ports);
-- retval = handshake(fotg210, status_reg,
-- PORT_RESUME, 0, 2000);/* 2ms */
-- if (retval != 0) {
-- fotg210_err(fotg210,
-- "port %d resume error %d\n",
-- wIndex + 1, retval);
-- goto error;
-- }
-- temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
-- }
-- }
--
-- /* whoever resets must GetPortStatus to complete it!! */
-- if ((temp & PORT_RESET) && time_after_eq(jiffies,
-- fotg210->reset_done[wIndex])) {
-- status |= USB_PORT_STAT_C_RESET << 16;
-- fotg210->reset_done[wIndex] = 0;
-- clear_bit(wIndex, &fotg210->resuming_ports);
--
-- /* force reset to complete */
-- fotg210_writel(fotg210,
-- temp & ~(PORT_RWC_BITS | PORT_RESET),
-- status_reg);
-- /* REVISIT: some hardware needs 550+ usec to clear
-- * this bit; seems too long to spin routinely...
-- */
-- retval = handshake(fotg210, status_reg,
-- PORT_RESET, 0, 1000);
-- if (retval != 0) {
-- fotg210_err(fotg210, "port %d reset error %d\n",
-- wIndex + 1, retval);
-- goto error;
-- }
--
-- /* see what we found out */
-- temp = check_reset_complete(fotg210, wIndex, status_reg,
-- fotg210_readl(fotg210, status_reg));
--
-- /* restart schedule */
-- fotg210->command |= CMD_RUN;
-- fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-- }
--
-- if (!(temp & (PORT_RESUME|PORT_RESET))) {
-- fotg210->reset_done[wIndex] = 0;
-- clear_bit(wIndex, &fotg210->resuming_ports);
-- }
--
-- /* transfer dedicated ports to the companion hc */
-- if ((temp & PORT_CONNECT) &&
-- test_bit(wIndex, &fotg210->companion_ports)) {
-- temp &= ~PORT_RWC_BITS;
-- fotg210_writel(fotg210, temp, status_reg);
-- fotg210_dbg(fotg210, "port %d --> companion\n",
-- wIndex + 1);
-- temp = fotg210_readl(fotg210, status_reg);
-- }
--
-- /*
-- * Even if OWNER is set, there's no harm letting hub_wq
-- * see the wPortStatus values (they should all be 0 except
-- * for PORT_POWER anyway).
-- */
--
-- if (temp & PORT_CONNECT) {
-- status |= USB_PORT_STAT_CONNECTION;
-- status |= fotg210_port_speed(fotg210, temp);
-- }
-- if (temp & PORT_PE)
-- status |= USB_PORT_STAT_ENABLE;
--
-- /* maybe the port was unsuspended without our knowledge */
-- if (temp & (PORT_SUSPEND|PORT_RESUME)) {
-- status |= USB_PORT_STAT_SUSPEND;
-- } else if (test_bit(wIndex, &fotg210->suspended_ports)) {
-- clear_bit(wIndex, &fotg210->suspended_ports);
-- clear_bit(wIndex, &fotg210->resuming_ports);
-- fotg210->reset_done[wIndex] = 0;
-- if (temp & PORT_PE)
-- set_bit(wIndex, &fotg210->port_c_suspend);
-- }
--
-- temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
-- if (temp1 & OTGISR_OVC)
-- status |= USB_PORT_STAT_OVERCURRENT;
-- if (temp & PORT_RESET)
-- status |= USB_PORT_STAT_RESET;
-- if (test_bit(wIndex, &fotg210->port_c_suspend))
-- status |= USB_PORT_STAT_C_SUSPEND << 16;
--
-- if (status & ~0xffff) /* only if wPortChange is interesting */
-- dbg_port(fotg210, "GetStatus", wIndex + 1, temp);
-- put_unaligned_le32(status, buf);
-- break;
-- case SetHubFeature:
-- switch (wValue) {
-- case C_HUB_LOCAL_POWER:
-- case C_HUB_OVER_CURRENT:
-- /* no hub-wide feature/status flags */
-- break;
-- default:
-- goto error;
-- }
-- break;
-- case SetPortFeature:
-- selector = wIndex >> 8;
-- wIndex &= 0xff;
--
-- if (!wIndex || wIndex > ports)
-- goto error;
-- wIndex--;
-- temp = fotg210_readl(fotg210, status_reg);
-- temp &= ~PORT_RWC_BITS;
-- switch (wValue) {
-- case USB_PORT_FEAT_SUSPEND:
-- if ((temp & PORT_PE) == 0
-- || (temp & PORT_RESET) != 0)
-- goto error;
--
-- /* After above check the port must be connected.
-- * Set appropriate bit thus could put phy into low power
-- * mode if we have hostpc feature
-- */
-- fotg210_writel(fotg210, temp | PORT_SUSPEND,
-- status_reg);
-- set_bit(wIndex, &fotg210->suspended_ports);
-- break;
-- case USB_PORT_FEAT_RESET:
-- if (temp & PORT_RESUME)
-- goto error;
-- /* line status bits may report this as low speed,
-- * which can be fine if this root hub has a
-- * transaction translator built in.
-- */
-- fotg210_dbg(fotg210, "port %d reset\n", wIndex + 1);
-- temp |= PORT_RESET;
-- temp &= ~PORT_PE;
--
-- /*
-- * caller must wait, then call GetPortStatus
-- * usb 2.0 spec says 50 ms resets on root
-- */
-- fotg210->reset_done[wIndex] = jiffies
-- + msecs_to_jiffies(50);
-- fotg210_writel(fotg210, temp, status_reg);
-- break;
--
-- /* For downstream facing ports (these): one hub port is put
-- * into test mode according to USB2 11.24.2.13, then the hub
-- * must be reset (which for root hub now means rmmod+modprobe,
-- * or else system reboot). See EHCI 2.3.9 and 4.14 for info
-- * about the EHCI-specific stuff.
-- */
-- case USB_PORT_FEAT_TEST:
-- if (!selector || selector > 5)
-- goto error;
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- fotg210_quiesce(fotg210);
-- spin_lock_irqsave(&fotg210->lock, flags);
--
-- /* Put all enabled ports into suspend */
-- temp = fotg210_readl(fotg210, status_reg) &
-- ~PORT_RWC_BITS;
-- if (temp & PORT_PE)
-- fotg210_writel(fotg210, temp | PORT_SUSPEND,
-- status_reg);
--
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- fotg210_halt(fotg210);
-- spin_lock_irqsave(&fotg210->lock, flags);
--
-- temp = fotg210_readl(fotg210, status_reg);
-- temp |= selector << 16;
-- fotg210_writel(fotg210, temp, status_reg);
-- break;
--
-- default:
-- goto error;
-- }
-- fotg210_readl(fotg210, &fotg210->regs->command);
-- break;
--
-- default:
--error:
-- /* "stall" on error */
-- retval = -EPIPE;
-- }
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- return retval;
--}
--
--static void __maybe_unused fotg210_relinquish_port(struct usb_hcd *hcd,
-- int portnum)
--{
-- return;
--}
--
--static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
-- int portnum)
--{
-- return 0;
--}
--
--/* There's basically three types of memory:
-- * - data used only by the HCD ... kmalloc is fine
-- * - async and periodic schedules, shared by HC and HCD ... these
-- * need to use dma_pool or dma_alloc_coherent
-- * - driver buffers, read/written by HC ... single shot DMA mapped
-- *
-- * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
-- * No memory seen by this driver is pageable.
-- */
--
--/* Allocate the key transfer structures from the previously allocated pool */
--static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
-- struct fotg210_qtd *qtd, dma_addr_t dma)
--{
-- memset(qtd, 0, sizeof(*qtd));
-- qtd->qtd_dma = dma;
-- qtd->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
-- qtd->hw_next = FOTG210_LIST_END(fotg210);
-- qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
-- INIT_LIST_HEAD(&qtd->qtd_list);
--}
--
--static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
-- gfp_t flags)
--{
-- struct fotg210_qtd *qtd;
-- dma_addr_t dma;
--
-- qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
-- if (qtd != NULL)
-- fotg210_qtd_init(fotg210, qtd, dma);
--
-- return qtd;
--}
--
--static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
-- struct fotg210_qtd *qtd)
--{
-- dma_pool_free(fotg210->qtd_pool, qtd, qtd->qtd_dma);
--}
--
--
--static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
--{
-- /* clean qtds first, and know this is not linked */
-- if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) {
-- fotg210_dbg(fotg210, "unused qh not empty!\n");
-- BUG();
-- }
-- if (qh->dummy)
-- fotg210_qtd_free(fotg210, qh->dummy);
-- dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
-- kfree(qh);
--}
--
--static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
-- gfp_t flags)
--{
-- struct fotg210_qh *qh;
-- dma_addr_t dma;
--
-- qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
-- if (!qh)
-- goto done;
-- qh->hw = (struct fotg210_qh_hw *)
-- dma_pool_zalloc(fotg210->qh_pool, flags, &dma);
-- if (!qh->hw)
-- goto fail;
-- qh->qh_dma = dma;
-- INIT_LIST_HEAD(&qh->qtd_list);
--
-- /* dummy td enables safe urb queuing */
-- qh->dummy = fotg210_qtd_alloc(fotg210, flags);
-- if (qh->dummy == NULL) {
-- fotg210_dbg(fotg210, "no dummy td\n");
-- goto fail1;
-- }
--done:
-- return qh;
--fail1:
-- dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
--fail:
-- kfree(qh);
-- return NULL;
--}
--
--/* The queue heads and transfer descriptors are managed from pools tied
-- * to each of the "per device" structures.
-- * This is the initialisation and cleanup code.
-- */
--
--static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
--{
-- if (fotg210->async)
-- qh_destroy(fotg210, fotg210->async);
-- fotg210->async = NULL;
--
-- if (fotg210->dummy)
-- qh_destroy(fotg210, fotg210->dummy);
-- fotg210->dummy = NULL;
--
-- /* DMA consistent memory and pools */
-- dma_pool_destroy(fotg210->qtd_pool);
-- fotg210->qtd_pool = NULL;
--
-- dma_pool_destroy(fotg210->qh_pool);
-- fotg210->qh_pool = NULL;
--
-- dma_pool_destroy(fotg210->itd_pool);
-- fotg210->itd_pool = NULL;
--
-- if (fotg210->periodic)
-- dma_free_coherent(fotg210_to_hcd(fotg210)->self.controller,
-- fotg210->periodic_size * sizeof(u32),
-- fotg210->periodic, fotg210->periodic_dma);
-- fotg210->periodic = NULL;
--
-- /* shadow periodic table */
-- kfree(fotg210->pshadow);
-- fotg210->pshadow = NULL;
--}
--
--/* remember to add cleanup code (above) if you add anything here */
--static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
--{
-- int i;
--
-- /* QTDs for control/bulk/intr transfers */
-- fotg210->qtd_pool = dma_pool_create("fotg210_qtd",
-- fotg210_to_hcd(fotg210)->self.controller,
-- sizeof(struct fotg210_qtd),
-- 32 /* byte alignment (for hw parts) */,
-- 4096 /* can't cross 4K */);
-- if (!fotg210->qtd_pool)
-- goto fail;
--
-- /* QHs for control/bulk/intr transfers */
-- fotg210->qh_pool = dma_pool_create("fotg210_qh",
-- fotg210_to_hcd(fotg210)->self.controller,
-- sizeof(struct fotg210_qh_hw),
-- 32 /* byte alignment (for hw parts) */,
-- 4096 /* can't cross 4K */);
-- if (!fotg210->qh_pool)
-- goto fail;
--
-- fotg210->async = fotg210_qh_alloc(fotg210, flags);
-- if (!fotg210->async)
-- goto fail;
--
-- /* ITD for high speed ISO transfers */
-- fotg210->itd_pool = dma_pool_create("fotg210_itd",
-- fotg210_to_hcd(fotg210)->self.controller,
-- sizeof(struct fotg210_itd),
-- 64 /* byte alignment (for hw parts) */,
-- 4096 /* can't cross 4K */);
-- if (!fotg210->itd_pool)
-- goto fail;
--
-- /* Hardware periodic table */
-- fotg210->periodic =
-- dma_alloc_coherent(fotg210_to_hcd(fotg210)->self.controller,
-- fotg210->periodic_size * sizeof(__le32),
-- &fotg210->periodic_dma, 0);
-- if (fotg210->periodic == NULL)
-- goto fail;
--
-- for (i = 0; i < fotg210->periodic_size; i++)
-- fotg210->periodic[i] = FOTG210_LIST_END(fotg210);
--
-- /* software shadow of hardware table */
-- fotg210->pshadow = kcalloc(fotg210->periodic_size, sizeof(void *),
-- flags);
-- if (fotg210->pshadow != NULL)
-- return 0;
--
--fail:
-- fotg210_dbg(fotg210, "couldn't init memory\n");
-- fotg210_mem_cleanup(fotg210);
-- return -ENOMEM;
--}
--/* EHCI hardware queue manipulation ... the core. QH/QTD manipulation.
-- *
-- * Control, bulk, and interrupt traffic all use "qh" lists. They list "qtd"
-- * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
-- * buffers needed for the larger number). We use one QH per endpoint, queue
-- * multiple urbs (all three types) per endpoint. URBs may need several qtds.
-- *
-- * ISO traffic uses "ISO TD" (itd) records, and (along with
-- * interrupts) needs careful scheduling. Performance improvements can be
-- * an ongoing challenge. That's in "ehci-sched.c".
-- *
-- * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs,
-- * or otherwise through transaction translators (TTs) in USB 2.0 hubs using
-- * (b) special fields in qh entries or (c) split iso entries. TTs will
-- * buffer low/full speed data so the host collects it at high speed.
-- */
--
--/* fill a qtd, returning how much of the buffer we were able to queue up */
--static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
-- dma_addr_t buf, size_t len, int token, int maxpacket)
--{
-- int i, count;
-- u64 addr = buf;
--
-- /* one buffer entry per 4K ... first might be short or unaligned */
-- qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
-- qtd->hw_buf_hi[0] = cpu_to_hc32(fotg210, (u32)(addr >> 32));
-- count = 0x1000 - (buf & 0x0fff); /* rest of that page */
-- if (likely(len < count)) /* ... iff needed */
-- count = len;
-- else {
-- buf += 0x1000;
-- buf &= ~0x0fff;
--
-- /* per-qtd limit: from 16K to 20K (best alignment) */
-- for (i = 1; count < len && i < 5; i++) {
-- addr = buf;
-- qtd->hw_buf[i] = cpu_to_hc32(fotg210, (u32)addr);
-- qtd->hw_buf_hi[i] = cpu_to_hc32(fotg210,
-- (u32)(addr >> 32));
-- buf += 0x1000;
-- if ((count + 0x1000) < len)
-- count += 0x1000;
-- else
-- count = len;
-- }
--
-- /* short packets may only terminate transfers */
-- if (count != len)
-- count -= (count % maxpacket);
-- }
-- qtd->hw_token = cpu_to_hc32(fotg210, (count << 16) | token);
-- qtd->length = count;
--
-- return count;
--}
--
--static inline void qh_update(struct fotg210_hcd *fotg210,
-- struct fotg210_qh *qh, struct fotg210_qtd *qtd)
--{
-- struct fotg210_qh_hw *hw = qh->hw;
--
-- /* writes to an active overlay are unsafe */
-- BUG_ON(qh->qh_state != QH_STATE_IDLE);
--
-- hw->hw_qtd_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-- hw->hw_alt_next = FOTG210_LIST_END(fotg210);
--
-- /* Except for control endpoints, we make hardware maintain data
-- * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
-- * and set the pseudo-toggle in udev. Only usb_clear_halt() will
-- * ever clear it.
-- */
-- if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
-- unsigned is_out, epnum;
--
-- is_out = qh->is_out;
-- epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
-- if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) {
-- hw->hw_token &= ~cpu_to_hc32(fotg210, QTD_TOGGLE);
-- usb_settoggle(qh->dev, epnum, is_out, 1);
-- }
-- }
--
-- hw->hw_token &= cpu_to_hc32(fotg210, QTD_TOGGLE | QTD_STS_PING);
--}
--
--/* if it weren't for a common silicon quirk (writing the dummy into the qh
-- * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
-- * recovery (including urb dequeue) would need software changes to a QH...
-- */
--static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
--{
-- struct fotg210_qtd *qtd;
--
-- if (list_empty(&qh->qtd_list))
-- qtd = qh->dummy;
-- else {
-- qtd = list_entry(qh->qtd_list.next,
-- struct fotg210_qtd, qtd_list);
-- /*
-- * first qtd may already be partially processed.
-- * If we come here during unlink, the QH overlay region
-- * might have reference to the just unlinked qtd. The
-- * qtd is updated in qh_completions(). Update the QH
-- * overlay here.
-- */
-- if (cpu_to_hc32(fotg210, qtd->qtd_dma) == qh->hw->hw_current) {
-- qh->hw->hw_qtd_next = qtd->hw_next;
-- qtd = NULL;
-- }
-- }
--
-- if (qtd)
-- qh_update(fotg210, qh, qtd);
--}
--
--static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
--
--static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
-- struct usb_host_endpoint *ep)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- struct fotg210_qh *qh = ep->hcpriv;
-- unsigned long flags;
--
-- spin_lock_irqsave(&fotg210->lock, flags);
-- qh->clearing_tt = 0;
-- if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
-- && fotg210->rh_state == FOTG210_RH_RUNNING)
-- qh_link_async(fotg210, qh);
-- spin_unlock_irqrestore(&fotg210->lock, flags);
--}
--
--static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
-- struct fotg210_qh *qh, struct urb *urb, u32 token)
--{
--
-- /* If an async split transaction gets an error or is unlinked,
-- * the TT buffer may be left in an indeterminate state. We
-- * have to clear the TT buffer.
-- *
-- * Note: this routine is never called for Isochronous transfers.
-- */
-- if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
-- struct usb_device *tt = urb->dev->tt->hub;
--
-- dev_dbg(&tt->dev,
-- "clear tt buffer port %d, a%d ep%d t%08x\n",
-- urb->dev->ttport, urb->dev->devnum,
-- usb_pipeendpoint(urb->pipe), token);
--
-- if (urb->dev->tt->hub !=
-- fotg210_to_hcd(fotg210)->self.root_hub) {
-- if (usb_hub_clear_tt_buffer(urb) == 0)
-- qh->clearing_tt = 1;
-- }
-- }
--}
--
--static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
-- size_t length, u32 token)
--{
-- int status = -EINPROGRESS;
--
-- /* count IN/OUT bytes, not SETUP (even short packets) */
-- if (likely(QTD_PID(token) != 2))
-- urb->actual_length += length - QTD_LENGTH(token);
--
-- /* don't modify error codes */
-- if (unlikely(urb->unlinked))
-- return status;
--
-- /* force cleanup after short read; not always an error */
-- if (unlikely(IS_SHORT_READ(token)))
-- status = -EREMOTEIO;
--
-- /* serious "can't proceed" faults reported by the hardware */
-- if (token & QTD_STS_HALT) {
-- if (token & QTD_STS_BABBLE) {
-- /* FIXME "must" disable babbling device's port too */
-- status = -EOVERFLOW;
-- /* CERR nonzero + halt --> stall */
-- } else if (QTD_CERR(token)) {
-- status = -EPIPE;
--
-- /* In theory, more than one of the following bits can be set
-- * since they are sticky and the transaction is retried.
-- * Which to test first is rather arbitrary.
-- */
-- } else if (token & QTD_STS_MMF) {
-- /* fs/ls interrupt xfer missed the complete-split */
-- status = -EPROTO;
-- } else if (token & QTD_STS_DBE) {
-- status = (QTD_PID(token) == 1) /* IN ? */
-- ? -ENOSR /* hc couldn't read data */
-- : -ECOMM; /* hc couldn't write data */
-- } else if (token & QTD_STS_XACT) {
-- /* timeout, bad CRC, wrong PID, etc */
-- fotg210_dbg(fotg210, "devpath %s ep%d%s 3strikes\n",
-- urb->dev->devpath,
-- usb_pipeendpoint(urb->pipe),
-- usb_pipein(urb->pipe) ? "in" : "out");
-- status = -EPROTO;
-- } else { /* unknown */
-- status = -EPROTO;
-- }
--
-- fotg210_dbg(fotg210,
-- "dev%d ep%d%s qtd token %08x --> status %d\n",
-- usb_pipedevice(urb->pipe),
-- usb_pipeendpoint(urb->pipe),
-- usb_pipein(urb->pipe) ? "in" : "out",
-- token, status);
-- }
--
-- return status;
--}
--
--static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
-- int status)
--__releases(fotg210->lock)
--__acquires(fotg210->lock)
--{
-- if (likely(urb->hcpriv != NULL)) {
-- struct fotg210_qh *qh = (struct fotg210_qh *) urb->hcpriv;
--
-- /* S-mask in a QH means it's an interrupt urb */
-- if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
--
-- /* ... update hc-wide periodic stats (for usbfs) */
-- fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs--;
-- }
-- }
--
-- if (unlikely(urb->unlinked)) {
-- INCR(fotg210->stats.unlink);
-- } else {
-- /* report non-error and short read status as zero */
-- if (status == -EINPROGRESS || status == -EREMOTEIO)
-- status = 0;
-- INCR(fotg210->stats.complete);
-- }
--
--#ifdef FOTG210_URB_TRACE
-- fotg210_dbg(fotg210,
-- "%s %s urb %p ep%d%s status %d len %d/%d\n",
-- __func__, urb->dev->devpath, urb,
-- usb_pipeendpoint(urb->pipe),
-- usb_pipein(urb->pipe) ? "in" : "out",
-- status,
-- urb->actual_length, urb->transfer_buffer_length);
--#endif
--
-- /* complete() can reenter this HCD */
-- usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-- spin_unlock(&fotg210->lock);
-- usb_hcd_giveback_urb(fotg210_to_hcd(fotg210), urb, status);
-- spin_lock(&fotg210->lock);
--}
--
--static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
--
--/* Process and free completed qtds for a qh, returning URBs to drivers.
-- * Chases up to qh->hw_current. Returns number of completions called,
-- * indicating how much "real" work we did.
-- */
--static unsigned qh_completions(struct fotg210_hcd *fotg210,
-- struct fotg210_qh *qh)
--{
-- struct fotg210_qtd *last, *end = qh->dummy;
-- struct fotg210_qtd *qtd, *tmp;
-- int last_status;
-- int stopped;
-- unsigned count = 0;
-- u8 state;
-- struct fotg210_qh_hw *hw = qh->hw;
--
-- if (unlikely(list_empty(&qh->qtd_list)))
-- return count;
--
-- /* completions (or tasks on other cpus) must never clobber HALT
-- * till we've gone through and cleaned everything up, even when
-- * they add urbs to this qh's queue or mark them for unlinking.
-- *
-- * NOTE: unlinking expects to be done in queue order.
-- *
-- * It's a bug for qh->qh_state to be anything other than
-- * QH_STATE_IDLE, unless our caller is scan_async() or
-- * scan_intr().
-- */
-- state = qh->qh_state;
-- qh->qh_state = QH_STATE_COMPLETING;
-- stopped = (state == QH_STATE_IDLE);
--
--rescan:
-- last = NULL;
-- last_status = -EINPROGRESS;
-- qh->needs_rescan = 0;
--
-- /* remove de-activated QTDs from front of queue.
-- * after faults (including short reads), cleanup this urb
-- * then let the queue advance.
-- * if queue is stopped, handles unlinks.
-- */
-- list_for_each_entry_safe(qtd, tmp, &qh->qtd_list, qtd_list) {
-- struct urb *urb;
-- u32 token = 0;
--
-- urb = qtd->urb;
--
-- /* clean up any state from previous QTD ...*/
-- if (last) {
-- if (likely(last->urb != urb)) {
-- fotg210_urb_done(fotg210, last->urb,
-- last_status);
-- count++;
-- last_status = -EINPROGRESS;
-- }
-- fotg210_qtd_free(fotg210, last);
-- last = NULL;
-- }
--
-- /* ignore urbs submitted during completions we reported */
-- if (qtd == end)
-- break;
--
-- /* hardware copies qtd out of qh overlay */
-- rmb();
-- token = hc32_to_cpu(fotg210, qtd->hw_token);
--
-- /* always clean up qtds the hc de-activated */
--retry_xacterr:
-- if ((token & QTD_STS_ACTIVE) == 0) {
--
-- /* Report Data Buffer Error: non-fatal but useful */
-- if (token & QTD_STS_DBE)
-- fotg210_dbg(fotg210,
-- "detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-- urb, usb_endpoint_num(&urb->ep->desc),
-- usb_endpoint_dir_in(&urb->ep->desc)
-- ? "in" : "out",
-- urb->transfer_buffer_length, qtd, qh);
--
-- /* on STALL, error, and short reads this urb must
-- * complete and all its qtds must be recycled.
-- */
-- if ((token & QTD_STS_HALT) != 0) {
--
-- /* retry transaction errors until we
-- * reach the software xacterr limit
-- */
-- if ((token & QTD_STS_XACT) &&
-- QTD_CERR(token) == 0 &&
-- ++qh->xacterrs < QH_XACTERR_MAX &&
-- !urb->unlinked) {
-- fotg210_dbg(fotg210,
-- "detected XactErr len %zu/%zu retry %d\n",
-- qtd->length - QTD_LENGTH(token),
-- qtd->length,
-- qh->xacterrs);
--
-- /* reset the token in the qtd and the
-- * qh overlay (which still contains
-- * the qtd) so that we pick up from
-- * where we left off
-- */
-- token &= ~QTD_STS_HALT;
-- token |= QTD_STS_ACTIVE |
-- (FOTG210_TUNE_CERR << 10);
-- qtd->hw_token = cpu_to_hc32(fotg210,
-- token);
-- wmb();
-- hw->hw_token = cpu_to_hc32(fotg210,
-- token);
-- goto retry_xacterr;
-- }
-- stopped = 1;
--
-- /* magic dummy for some short reads; qh won't advance.
-- * that silicon quirk can kick in with this dummy too.
-- *
-- * other short reads won't stop the queue, including
-- * control transfers (status stage handles that) or
-- * most other single-qtd reads ... the queue stops if
-- * URB_SHORT_NOT_OK was set so the driver submitting
-- * the urbs could clean it up.
-- */
-- } else if (IS_SHORT_READ(token) &&
-- !(qtd->hw_alt_next &
-- FOTG210_LIST_END(fotg210))) {
-- stopped = 1;
-- }
--
-- /* stop scanning when we reach qtds the hc is using */
-- } else if (likely(!stopped
-- && fotg210->rh_state >= FOTG210_RH_RUNNING)) {
-- break;
--
-- /* scan the whole queue for unlinks whenever it stops */
-- } else {
-- stopped = 1;
--
-- /* cancel everything if we halt, suspend, etc */
-- if (fotg210->rh_state < FOTG210_RH_RUNNING)
-- last_status = -ESHUTDOWN;
--
-- /* this qtd is active; skip it unless a previous qtd
-- * for its urb faulted, or its urb was canceled.
-- */
-- else if (last_status == -EINPROGRESS && !urb->unlinked)
-- continue;
--
-- /* qh unlinked; token in overlay may be most current */
-- if (state == QH_STATE_IDLE &&
-- cpu_to_hc32(fotg210, qtd->qtd_dma)
-- == hw->hw_current) {
-- token = hc32_to_cpu(fotg210, hw->hw_token);
--
-- /* An unlink may leave an incomplete
-- * async transaction in the TT buffer.
-- * We have to clear it.
-- */
-- fotg210_clear_tt_buffer(fotg210, qh, urb,
-- token);
-- }
-- }
--
-- /* unless we already know the urb's status, collect qtd status
-- * and update count of bytes transferred. in common short read
-- * cases with only one data qtd (including control transfers),
-- * queue processing won't halt. but with two or more qtds (for
-- * example, with a 32 KB transfer), when the first qtd gets a
-- * short read the second must be removed by hand.
-- */
-- if (last_status == -EINPROGRESS) {
-- last_status = qtd_copy_status(fotg210, urb,
-- qtd->length, token);
-- if (last_status == -EREMOTEIO &&
-- (qtd->hw_alt_next &
-- FOTG210_LIST_END(fotg210)))
-- last_status = -EINPROGRESS;
--
-- /* As part of low/full-speed endpoint-halt processing
-- * we must clear the TT buffer (11.17.5).
-- */
-- if (unlikely(last_status != -EINPROGRESS &&
-- last_status != -EREMOTEIO)) {
-- /* The TT's in some hubs malfunction when they
-- * receive this request following a STALL (they
-- * stop sending isochronous packets). Since a
-- * STALL can't leave the TT buffer in a busy
-- * state (if you believe Figures 11-48 - 11-51
-- * in the USB 2.0 spec), we won't clear the TT
-- * buffer in this case. Strictly speaking this
-- * is a violation of the spec.
-- */
-- if (last_status != -EPIPE)
-- fotg210_clear_tt_buffer(fotg210, qh,
-- urb, token);
-- }
-- }
--
-- /* if we're removing something not at the queue head,
-- * patch the hardware queue pointer.
-- */
-- if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
-- last = list_entry(qtd->qtd_list.prev,
-- struct fotg210_qtd, qtd_list);
-- last->hw_next = qtd->hw_next;
-- }
--
-- /* remove qtd; it's recycled after possible urb completion */
-- list_del(&qtd->qtd_list);
-- last = qtd;
--
-- /* reinit the xacterr counter for the next qtd */
-- qh->xacterrs = 0;
-- }
--
-- /* last urb's completion might still need calling */
-- if (likely(last != NULL)) {
-- fotg210_urb_done(fotg210, last->urb, last_status);
-- count++;
-- fotg210_qtd_free(fotg210, last);
-- }
--
-- /* Do we need to rescan for URBs dequeued during a giveback? */
-- if (unlikely(qh->needs_rescan)) {
-- /* If the QH is already unlinked, do the rescan now. */
-- if (state == QH_STATE_IDLE)
-- goto rescan;
--
-- /* Otherwise we have to wait until the QH is fully unlinked.
-- * Our caller will start an unlink if qh->needs_rescan is
-- * set. But if an unlink has already started, nothing needs
-- * to be done.
-- */
-- if (state != QH_STATE_LINKED)
-- qh->needs_rescan = 0;
-- }
--
-- /* restore original state; caller must unlink or relink */
-- qh->qh_state = state;
--
-- /* be sure the hardware's done with the qh before refreshing
-- * it after fault cleanup, or recovering from silicon wrongly
-- * overlaying the dummy qtd (which reduces DMA chatter).
-- */
-- if (stopped != 0 || hw->hw_qtd_next == FOTG210_LIST_END(fotg210)) {
-- switch (state) {
-- case QH_STATE_IDLE:
-- qh_refresh(fotg210, qh);
-- break;
-- case QH_STATE_LINKED:
-- /* We won't refresh a QH that's linked (after the HC
-- * stopped the queue). That avoids a race:
-- * - HC reads first part of QH;
-- * - CPU updates that first part and the token;
-- * - HC reads rest of that QH, including token
-- * Result: HC gets an inconsistent image, and then
-- * DMAs to/from the wrong memory (corrupting it).
-- *
-- * That should be rare for interrupt transfers,
-- * except maybe high bandwidth ...
-- */
--
-- /* Tell the caller to start an unlink */
-- qh->needs_rescan = 1;
-- break;
-- /* otherwise, unlink already started */
-- }
-- }
--
-- return count;
--}
--
--/* reverse of qh_urb_transaction: free a list of TDs.
-- * used for cleanup after errors, before HC sees an URB's TDs.
-- */
--static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
-- struct list_head *head)
--{
-- struct fotg210_qtd *qtd, *temp;
--
-- list_for_each_entry_safe(qtd, temp, head, qtd_list) {
-- list_del(&qtd->qtd_list);
-- fotg210_qtd_free(fotg210, qtd);
-- }
--}
--
--/* create a list of filled qtds for this URB; won't link into qh.
-- */
--static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
-- struct urb *urb, struct list_head *head, gfp_t flags)
--{
-- struct fotg210_qtd *qtd, *qtd_prev;
-- dma_addr_t buf;
-- int len, this_sg_len, maxpacket;
-- int is_input;
-- u32 token;
-- int i;
-- struct scatterlist *sg;
--
-- /*
-- * URBs map to sequences of QTDs: one logical transaction
-- */
-- qtd = fotg210_qtd_alloc(fotg210, flags);
-- if (unlikely(!qtd))
-- return NULL;
-- list_add_tail(&qtd->qtd_list, head);
-- qtd->urb = urb;
--
-- token = QTD_STS_ACTIVE;
-- token |= (FOTG210_TUNE_CERR << 10);
-- /* for split transactions, SplitXState initialized to zero */
--
-- len = urb->transfer_buffer_length;
-- is_input = usb_pipein(urb->pipe);
-- if (usb_pipecontrol(urb->pipe)) {
-- /* SETUP pid */
-- qtd_fill(fotg210, qtd, urb->setup_dma,
-- sizeof(struct usb_ctrlrequest),
-- token | (2 /* "setup" */ << 8), 8);
--
-- /* ... and always at least one more pid */
-- token ^= QTD_TOGGLE;
-- qtd_prev = qtd;
-- qtd = fotg210_qtd_alloc(fotg210, flags);
-- if (unlikely(!qtd))
-- goto cleanup;
-- qtd->urb = urb;
-- qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-- list_add_tail(&qtd->qtd_list, head);
--
-- /* for zero length DATA stages, STATUS is always IN */
-- if (len == 0)
-- token |= (1 /* "in" */ << 8);
-- }
--
-- /*
-- * data transfer stage: buffer setup
-- */
-- i = urb->num_mapped_sgs;
-- if (len > 0 && i > 0) {
-- sg = urb->sg;
-- buf = sg_dma_address(sg);
--
-- /* urb->transfer_buffer_length may be smaller than the
-- * size of the scatterlist (or vice versa)
-- */
-- this_sg_len = min_t(int, sg_dma_len(sg), len);
-- } else {
-- sg = NULL;
-- buf = urb->transfer_dma;
-- this_sg_len = len;
-- }
--
-- if (is_input)
-- token |= (1 /* "in" */ << 8);
-- /* else it's already initted to "out" pid (0 << 8) */
--
-- maxpacket = usb_maxpacket(urb->dev, urb->pipe);
--
-- /*
-- * buffer gets wrapped in one or more qtds;
-- * last one may be "short" (including zero len)
-- * and may serve as a control status ack
-- */
-- for (;;) {
-- int this_qtd_len;
--
-- this_qtd_len = qtd_fill(fotg210, qtd, buf, this_sg_len, token,
-- maxpacket);
-- this_sg_len -= this_qtd_len;
-- len -= this_qtd_len;
-- buf += this_qtd_len;
--
-- /*
-- * short reads advance to a "magic" dummy instead of the next
-- * qtd ... that forces the queue to stop, for manual cleanup.
-- * (this will usually be overridden later.)
-- */
-- if (is_input)
-- qtd->hw_alt_next = fotg210->async->hw->hw_alt_next;
--
-- /* qh makes control packets use qtd toggle; maybe switch it */
-- if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
-- token ^= QTD_TOGGLE;
--
-- if (likely(this_sg_len <= 0)) {
-- if (--i <= 0 || len <= 0)
-- break;
-- sg = sg_next(sg);
-- buf = sg_dma_address(sg);
-- this_sg_len = min_t(int, sg_dma_len(sg), len);
-- }
--
-- qtd_prev = qtd;
-- qtd = fotg210_qtd_alloc(fotg210, flags);
-- if (unlikely(!qtd))
-- goto cleanup;
-- qtd->urb = urb;
-- qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-- list_add_tail(&qtd->qtd_list, head);
-- }
--
-- /*
-- * unless the caller requires manual cleanup after short reads,
-- * have the alt_next mechanism keep the queue running after the
-- * last data qtd (the only one, for control and most other cases).
-- */
-- if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 ||
-- usb_pipecontrol(urb->pipe)))
-- qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
--
-- /*
-- * control requests may need a terminating data "status" ack;
-- * other OUT ones may need a terminating short packet
-- * (zero length).
-- */
-- if (likely(urb->transfer_buffer_length != 0)) {
-- int one_more = 0;
--
-- if (usb_pipecontrol(urb->pipe)) {
-- one_more = 1;
-- token ^= 0x0100; /* "in" <--> "out" */
-- token |= QTD_TOGGLE; /* force DATA1 */
-- } else if (usb_pipeout(urb->pipe)
-- && (urb->transfer_flags & URB_ZERO_PACKET)
-- && !(urb->transfer_buffer_length % maxpacket)) {
-- one_more = 1;
-- }
-- if (one_more) {
-- qtd_prev = qtd;
-- qtd = fotg210_qtd_alloc(fotg210, flags);
-- if (unlikely(!qtd))
-- goto cleanup;
-- qtd->urb = urb;
-- qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-- list_add_tail(&qtd->qtd_list, head);
--
-- /* never any data in such packets */
-- qtd_fill(fotg210, qtd, 0, 0, token, 0);
-- }
-- }
--
-- /* by default, enable interrupt on urb completion */
-- if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
-- qtd->hw_token |= cpu_to_hc32(fotg210, QTD_IOC);
-- return head;
--
--cleanup:
-- qtd_list_free(fotg210, urb, head);
-- return NULL;
--}
--
--/* Would be best to create all qh's from config descriptors,
-- * when each interface/altsetting is established. Unlink
-- * any previous qh and cancel its urbs first; endpoints are
-- * implicitly reset then (data toggle too).
-- * That'd mean updating how usbcore talks to HCDs. (2.7?)
-- */
--
--
--/* Each QH holds a qtd list; a QH is used for everything except iso.
-- *
-- * For interrupt urbs, the scheduler must set the microframe scheduling
-- * mask(s) each time the QH gets scheduled. For highspeed, that's
-- * just one microframe in the s-mask. For split interrupt transactions
-- * there are additional complications: c-mask, maybe FSTNs.
-- */
--static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
-- gfp_t flags)
--{
-- struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags);
-- struct usb_host_endpoint *ep;
-- u32 info1 = 0, info2 = 0;
-- int is_input, type;
-- int maxp = 0;
-- int mult;
-- struct usb_tt *tt = urb->dev->tt;
-- struct fotg210_qh_hw *hw;
--
-- if (!qh)
-- return qh;
--
-- /*
-- * init endpoint/device data for this QH
-- */
-- info1 |= usb_pipeendpoint(urb->pipe) << 8;
-- info1 |= usb_pipedevice(urb->pipe) << 0;
--
-- is_input = usb_pipein(urb->pipe);
-- type = usb_pipetype(urb->pipe);
-- ep = usb_pipe_endpoint(urb->dev, urb->pipe);
-- maxp = usb_endpoint_maxp(&ep->desc);
-- mult = usb_endpoint_maxp_mult(&ep->desc);
--
-- /* 1024 byte maxpacket is a hardware ceiling. High bandwidth
-- * acts like up to 3KB, but is built from smaller packets.
-- */
-- if (maxp > 1024) {
-- fotg210_dbg(fotg210, "bogus qh maxpacket %d\n", maxp);
-- goto done;
-- }
--
-- /* Compute interrupt scheduling parameters just once, and save.
-- * - allowing for high bandwidth, how many nsec/uframe are used?
-- * - split transactions need a second CSPLIT uframe; same question
-- * - splits also need a schedule gap (for full/low speed I/O)
-- * - qh has a polling interval
-- *
-- * For control/bulk requests, the HC or TT handles these.
-- */
-- if (type == PIPE_INTERRUPT) {
-- qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
-- is_input, 0, mult * maxp));
-- qh->start = NO_FRAME;
--
-- if (urb->dev->speed == USB_SPEED_HIGH) {
-- qh->c_usecs = 0;
-- qh->gap_uf = 0;
--
-- qh->period = urb->interval >> 3;
-- if (qh->period == 0 && urb->interval != 1) {
-- /* NOTE interval 2 or 4 uframes could work.
-- * But interval 1 scheduling is simpler, and
-- * includes high bandwidth.
-- */
-- urb->interval = 1;
-- } else if (qh->period > fotg210->periodic_size) {
-- qh->period = fotg210->periodic_size;
-- urb->interval = qh->period << 3;
-- }
-- } else {
-- int think_time;
--
-- /* gap is f(FS/LS transfer times) */
-- qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed,
-- is_input, 0, maxp) / (125 * 1000);
--
-- /* FIXME this just approximates SPLIT/CSPLIT times */
-- if (is_input) { /* SPLIT, gap, CSPLIT+DATA */
-- qh->c_usecs = qh->usecs + HS_USECS(0);
-- qh->usecs = HS_USECS(1);
-- } else { /* SPLIT+DATA, gap, CSPLIT */
-- qh->usecs += HS_USECS(1);
-- qh->c_usecs = HS_USECS(0);
-- }
--
-- think_time = tt ? tt->think_time : 0;
-- qh->tt_usecs = NS_TO_US(think_time +
-- usb_calc_bus_time(urb->dev->speed,
-- is_input, 0, maxp));
-- qh->period = urb->interval;
-- if (qh->period > fotg210->periodic_size) {
-- qh->period = fotg210->periodic_size;
-- urb->interval = qh->period;
-- }
-- }
-- }
--
-- /* support for tt scheduling, and access to toggles */
-- qh->dev = urb->dev;
--
-- /* using TT? */
-- switch (urb->dev->speed) {
-- case USB_SPEED_LOW:
-- info1 |= QH_LOW_SPEED;
-- fallthrough;
--
-- case USB_SPEED_FULL:
-- /* EPS 0 means "full" */
-- if (type != PIPE_INTERRUPT)
-- info1 |= (FOTG210_TUNE_RL_TT << 28);
-- if (type == PIPE_CONTROL) {
-- info1 |= QH_CONTROL_EP; /* for TT */
-- info1 |= QH_TOGGLE_CTL; /* toggle from qtd */
-- }
-- info1 |= maxp << 16;
--
-- info2 |= (FOTG210_TUNE_MULT_TT << 30);
--
-- /* Some Freescale processors have an erratum in which the
-- * port number in the queue head was 0..N-1 instead of 1..N.
-- */
-- if (fotg210_has_fsl_portno_bug(fotg210))
-- info2 |= (urb->dev->ttport-1) << 23;
-- else
-- info2 |= urb->dev->ttport << 23;
--
-- /* set the address of the TT; for TDI's integrated
-- * root hub tt, leave it zeroed.
-- */
-- if (tt && tt->hub != fotg210_to_hcd(fotg210)->self.root_hub)
-- info2 |= tt->hub->devnum << 16;
--
-- /* NOTE: if (PIPE_INTERRUPT) { scheduler sets c-mask } */
--
-- break;
--
-- case USB_SPEED_HIGH: /* no TT involved */
-- info1 |= QH_HIGH_SPEED;
-- if (type == PIPE_CONTROL) {
-- info1 |= (FOTG210_TUNE_RL_HS << 28);
-- info1 |= 64 << 16; /* usb2 fixed maxpacket */
-- info1 |= QH_TOGGLE_CTL; /* toggle from qtd */
-- info2 |= (FOTG210_TUNE_MULT_HS << 30);
-- } else if (type == PIPE_BULK) {
-- info1 |= (FOTG210_TUNE_RL_HS << 28);
-- /* The USB spec says that high speed bulk endpoints
-- * always use 512 byte maxpacket. But some device
-- * vendors decided to ignore that, and MSFT is happy
-- * to help them do so. So now people expect to use
-- * such nonconformant devices with Linux too; sigh.
-- */
-- info1 |= maxp << 16;
-- info2 |= (FOTG210_TUNE_MULT_HS << 30);
-- } else { /* PIPE_INTERRUPT */
-- info1 |= maxp << 16;
-- info2 |= mult << 30;
-- }
-- break;
-- default:
-- fotg210_dbg(fotg210, "bogus dev %p speed %d\n", urb->dev,
-- urb->dev->speed);
--done:
-- qh_destroy(fotg210, qh);
-- return NULL;
-- }
--
-- /* NOTE: if (PIPE_INTERRUPT) { scheduler sets s-mask } */
--
-- /* init as live, toggle clear, advance to dummy */
-- qh->qh_state = QH_STATE_IDLE;
-- hw = qh->hw;
-- hw->hw_info1 = cpu_to_hc32(fotg210, info1);
-- hw->hw_info2 = cpu_to_hc32(fotg210, info2);
-- qh->is_out = !is_input;
-- usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, 1);
-- qh_refresh(fotg210, qh);
-- return qh;
--}
--
--static void enable_async(struct fotg210_hcd *fotg210)
--{
-- if (fotg210->async_count++)
-- return;
--
-- /* Stop waiting to turn off the async schedule */
-- fotg210->enabled_hrtimer_events &= ~BIT(FOTG210_HRTIMER_DISABLE_ASYNC);
--
-- /* Don't start the schedule until ASS is 0 */
-- fotg210_poll_ASS(fotg210);
-- turn_on_io_watchdog(fotg210);
--}
--
--static void disable_async(struct fotg210_hcd *fotg210)
--{
-- if (--fotg210->async_count)
-- return;
--
-- /* The async schedule and async_unlink list are supposed to be empty */
-- WARN_ON(fotg210->async->qh_next.qh || fotg210->async_unlink);
--
-- /* Don't turn off the schedule until ASS is 1 */
-- fotg210_poll_ASS(fotg210);
--}
--
--/* move qh (and its qtds) onto async queue; maybe enable queue. */
--
--static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
--{
-- __hc32 dma = QH_NEXT(fotg210, qh->qh_dma);
-- struct fotg210_qh *head;
--
-- /* Don't link a QH if there's a Clear-TT-Buffer pending */
-- if (unlikely(qh->clearing_tt))
-- return;
--
-- WARN_ON(qh->qh_state != QH_STATE_IDLE);
--
-- /* clear halt and/or toggle; and maybe recover from silicon quirk */
-- qh_refresh(fotg210, qh);
--
-- /* splice right after start */
-- head = fotg210->async;
-- qh->qh_next = head->qh_next;
-- qh->hw->hw_next = head->hw->hw_next;
-- wmb();
--
-- head->qh_next.qh = qh;
-- head->hw->hw_next = dma;
--
-- qh->xacterrs = 0;
-- qh->qh_state = QH_STATE_LINKED;
-- /* qtd completions reported later by interrupt */
--
-- enable_async(fotg210);
--}
--
--/* For control/bulk/interrupt, return QH with these TDs appended.
-- * Allocates and initializes the QH if necessary.
-- * Returns null if it can't allocate a QH it needs to.
-- * If the QH has TDs (urbs) already, that's great.
-- */
--static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
-- struct urb *urb, struct list_head *qtd_list,
-- int epnum, void **ptr)
--{
-- struct fotg210_qh *qh = NULL;
-- __hc32 qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
--
-- qh = (struct fotg210_qh *) *ptr;
-- if (unlikely(qh == NULL)) {
-- /* can't sleep here, we have fotg210->lock... */
-- qh = qh_make(fotg210, urb, GFP_ATOMIC);
-- *ptr = qh;
-- }
-- if (likely(qh != NULL)) {
-- struct fotg210_qtd *qtd;
--
-- if (unlikely(list_empty(qtd_list)))
-- qtd = NULL;
-- else
-- qtd = list_entry(qtd_list->next, struct fotg210_qtd,
-- qtd_list);
--
-- /* control qh may need patching ... */
-- if (unlikely(epnum == 0)) {
-- /* usb_reset_device() briefly reverts to address 0 */
-- if (usb_pipedevice(urb->pipe) == 0)
-- qh->hw->hw_info1 &= ~qh_addr_mask;
-- }
--
-- /* just one way to queue requests: swap with the dummy qtd.
-- * only hc or qh_refresh() ever modify the overlay.
-- */
-- if (likely(qtd != NULL)) {
-- struct fotg210_qtd *dummy;
-- dma_addr_t dma;
-- __hc32 token;
--
-- /* to avoid racing the HC, use the dummy td instead of
-- * the first td of our list (becomes new dummy). both
-- * tds stay deactivated until we're done, when the
-- * HC is allowed to fetch the old dummy (4.10.2).
-- */
-- token = qtd->hw_token;
-- qtd->hw_token = HALT_BIT(fotg210);
--
-- dummy = qh->dummy;
--
-- dma = dummy->qtd_dma;
-- *dummy = *qtd;
-- dummy->qtd_dma = dma;
--
-- list_del(&qtd->qtd_list);
-- list_add(&dummy->qtd_list, qtd_list);
-- list_splice_tail(qtd_list, &qh->qtd_list);
--
-- fotg210_qtd_init(fotg210, qtd, qtd->qtd_dma);
-- qh->dummy = qtd;
--
-- /* hc must see the new dummy at list end */
-- dma = qtd->qtd_dma;
-- qtd = list_entry(qh->qtd_list.prev,
-- struct fotg210_qtd, qtd_list);
-- qtd->hw_next = QTD_NEXT(fotg210, dma);
--
-- /* let the hc process these next qtds */
-- wmb();
-- dummy->hw_token = token;
--
-- urb->hcpriv = qh;
-- }
-- }
-- return qh;
--}
--
--static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
-- struct list_head *qtd_list, gfp_t mem_flags)
--{
-- int epnum;
-- unsigned long flags;
-- struct fotg210_qh *qh = NULL;
-- int rc;
--
-- epnum = urb->ep->desc.bEndpointAddress;
--
--#ifdef FOTG210_URB_TRACE
-- {
-- struct fotg210_qtd *qtd;
--
-- qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
-- fotg210_dbg(fotg210,
-- "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-- __func__, urb->dev->devpath, urb,
-- epnum & 0x0f, (epnum & USB_DIR_IN)
-- ? "in" : "out",
-- urb->transfer_buffer_length,
-- qtd, urb->ep->hcpriv);
-- }
--#endif
--
-- spin_lock_irqsave(&fotg210->lock, flags);
-- if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
-- rc = -ESHUTDOWN;
-- goto done;
-- }
-- rc = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
-- if (unlikely(rc))
-- goto done;
--
-- qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
-- if (unlikely(qh == NULL)) {
-- usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-- rc = -ENOMEM;
-- goto done;
-- }
--
-- /* Control/bulk operations through TTs don't need scheduling,
-- * the HC and TT handle it when the TT has a buffer ready.
-- */
-- if (likely(qh->qh_state == QH_STATE_IDLE))
-- qh_link_async(fotg210, qh);
--done:
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- if (unlikely(qh == NULL))
-- qtd_list_free(fotg210, urb, qtd_list);
-- return rc;
--}
--
--static void single_unlink_async(struct fotg210_hcd *fotg210,
-- struct fotg210_qh *qh)
--{
-- struct fotg210_qh *prev;
--
-- /* Add to the end of the list of QHs waiting for the next IAAD */
-- qh->qh_state = QH_STATE_UNLINK;
-- if (fotg210->async_unlink)
-- fotg210->async_unlink_last->unlink_next = qh;
-- else
-- fotg210->async_unlink = qh;
-- fotg210->async_unlink_last = qh;
--
-- /* Unlink it from the schedule */
-- prev = fotg210->async;
-- while (prev->qh_next.qh != qh)
-- prev = prev->qh_next.qh;
--
-- prev->hw->hw_next = qh->hw->hw_next;
-- prev->qh_next = qh->qh_next;
-- if (fotg210->qh_scan_next == qh)
-- fotg210->qh_scan_next = qh->qh_next.qh;
--}
--
--static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
--{
-- /*
-- * Do nothing if an IAA cycle is already running or
-- * if one will be started shortly.
-- */
-- if (fotg210->async_iaa || fotg210->async_unlinking)
-- return;
--
-- /* Do all the waiting QHs at once */
-- fotg210->async_iaa = fotg210->async_unlink;
-- fotg210->async_unlink = NULL;
--
-- /* If the controller isn't running, we don't have to wait for it */
-- if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING)) {
-- if (!nested) /* Avoid recursion */
-- end_unlink_async(fotg210);
--
-- /* Otherwise start a new IAA cycle */
-- } else if (likely(fotg210->rh_state == FOTG210_RH_RUNNING)) {
-- /* Make sure the unlinks are all visible to the hardware */
-- wmb();
--
-- fotg210_writel(fotg210, fotg210->command | CMD_IAAD,
-- &fotg210->regs->command);
-- fotg210_readl(fotg210, &fotg210->regs->command);
-- fotg210_enable_event(fotg210, FOTG210_HRTIMER_IAA_WATCHDOG,
-- true);
-- }
--}
--
--/* the async qh for the qtds being unlinked are now gone from the HC */
--
--static void end_unlink_async(struct fotg210_hcd *fotg210)
--{
-- struct fotg210_qh *qh;
--
-- /* Process the idle QHs */
--restart:
-- fotg210->async_unlinking = true;
-- while (fotg210->async_iaa) {
-- qh = fotg210->async_iaa;
-- fotg210->async_iaa = qh->unlink_next;
-- qh->unlink_next = NULL;
--
-- qh->qh_state = QH_STATE_IDLE;
-- qh->qh_next.qh = NULL;
--
-- qh_completions(fotg210, qh);
-- if (!list_empty(&qh->qtd_list) &&
-- fotg210->rh_state == FOTG210_RH_RUNNING)
-- qh_link_async(fotg210, qh);
-- disable_async(fotg210);
-- }
-- fotg210->async_unlinking = false;
--
-- /* Start a new IAA cycle if any QHs are waiting for it */
-- if (fotg210->async_unlink) {
-- start_iaa_cycle(fotg210, true);
-- if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING))
-- goto restart;
-- }
--}
--
--static void unlink_empty_async(struct fotg210_hcd *fotg210)
--{
-- struct fotg210_qh *qh, *next;
-- bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
-- bool check_unlinks_later = false;
--
-- /* Unlink all the async QHs that have been empty for a timer cycle */
-- next = fotg210->async->qh_next.qh;
-- while (next) {
-- qh = next;
-- next = qh->qh_next.qh;
--
-- if (list_empty(&qh->qtd_list) &&
-- qh->qh_state == QH_STATE_LINKED) {
-- if (!stopped && qh->unlink_cycle ==
-- fotg210->async_unlink_cycle)
-- check_unlinks_later = true;
-- else
-- single_unlink_async(fotg210, qh);
-- }
-- }
--
-- /* Start a new IAA cycle if any QHs are waiting for it */
-- if (fotg210->async_unlink)
-- start_iaa_cycle(fotg210, false);
--
-- /* QHs that haven't been empty for long enough will be handled later */
-- if (check_unlinks_later) {
-- fotg210_enable_event(fotg210, FOTG210_HRTIMER_ASYNC_UNLINKS,
-- true);
-- ++fotg210->async_unlink_cycle;
-- }
--}
--
--/* makes sure the async qh will become idle */
--/* caller must own fotg210->lock */
--
--static void start_unlink_async(struct fotg210_hcd *fotg210,
-- struct fotg210_qh *qh)
--{
-- /*
-- * If the QH isn't linked then there's nothing we can do
-- * unless we were called during a giveback, in which case
-- * qh_completions() has to deal with it.
-- */
-- if (qh->qh_state != QH_STATE_LINKED) {
-- if (qh->qh_state == QH_STATE_COMPLETING)
-- qh->needs_rescan = 1;
-- return;
-- }
--
-- single_unlink_async(fotg210, qh);
-- start_iaa_cycle(fotg210, false);
--}
--
--static void scan_async(struct fotg210_hcd *fotg210)
--{
-- struct fotg210_qh *qh;
-- bool check_unlinks_later = false;
--
-- fotg210->qh_scan_next = fotg210->async->qh_next.qh;
-- while (fotg210->qh_scan_next) {
-- qh = fotg210->qh_scan_next;
-- fotg210->qh_scan_next = qh->qh_next.qh;
--rescan:
-- /* clean any finished work for this qh */
-- if (!list_empty(&qh->qtd_list)) {
-- int temp;
--
-- /*
-- * Unlinks could happen here; completion reporting
-- * drops the lock. That's why fotg210->qh_scan_next
-- * always holds the next qh to scan; if the next qh
-- * gets unlinked then fotg210->qh_scan_next is adjusted
-- * in single_unlink_async().
-- */
-- temp = qh_completions(fotg210, qh);
-- if (qh->needs_rescan) {
-- start_unlink_async(fotg210, qh);
-- } else if (list_empty(&qh->qtd_list)
-- && qh->qh_state == QH_STATE_LINKED) {
-- qh->unlink_cycle = fotg210->async_unlink_cycle;
-- check_unlinks_later = true;
-- } else if (temp != 0)
-- goto rescan;
-- }
-- }
--
-- /*
-- * Unlink empty entries, reducing DMA usage as well
-- * as HCD schedule-scanning costs. Delay for any qh
-- * we just scanned, there's a not-unusual case that it
-- * doesn't stay idle for long.
-- */
-- if (check_unlinks_later && fotg210->rh_state == FOTG210_RH_RUNNING &&
-- !(fotg210->enabled_hrtimer_events &
-- BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
-- fotg210_enable_event(fotg210,
-- FOTG210_HRTIMER_ASYNC_UNLINKS, true);
-- ++fotg210->async_unlink_cycle;
-- }
--}
--/* EHCI scheduled transaction support: interrupt, iso, split iso
-- * These are called "periodic" transactions in the EHCI spec.
-- *
-- * Note that for interrupt transfers, the QH/QTD manipulation is shared
-- * with the "asynchronous" transaction support (control/bulk transfers).
-- * The only real difference is in how interrupt transfers are scheduled.
-- *
-- * For ISO, we make an "iso_stream" head to serve the same role as a QH.
-- * It keeps track of every ITD (or SITD) that's linked, and holds enough
-- * pre-calculated schedule data to make appending to the queue be quick.
-- */
--static int fotg210_get_frame(struct usb_hcd *hcd);
--
--/* periodic_next_shadow - return "next" pointer on shadow list
-- * @periodic: host pointer to qh/itd
-- * @tag: hardware tag for type of this record
-- */
--static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
-- union fotg210_shadow *periodic, __hc32 tag)
--{
-- switch (hc32_to_cpu(fotg210, tag)) {
-- case Q_TYPE_QH:
-- return &periodic->qh->qh_next;
-- case Q_TYPE_FSTN:
-- return &periodic->fstn->fstn_next;
-- default:
-- return &periodic->itd->itd_next;
-- }
--}
--
--static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
-- union fotg210_shadow *periodic, __hc32 tag)
--{
-- switch (hc32_to_cpu(fotg210, tag)) {
-- /* our fotg210_shadow.qh is actually software part */
-- case Q_TYPE_QH:
-- return &periodic->qh->hw->hw_next;
-- /* others are hw parts */
-- default:
-- return periodic->hw_next;
-- }
--}
--
--/* caller must hold fotg210->lock */
--static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
-- void *ptr)
--{
-- union fotg210_shadow *prev_p = &fotg210->pshadow[frame];
-- __hc32 *hw_p = &fotg210->periodic[frame];
-- union fotg210_shadow here = *prev_p;
--
-- /* find predecessor of "ptr"; hw and shadow lists are in sync */
-- while (here.ptr && here.ptr != ptr) {
-- prev_p = periodic_next_shadow(fotg210, prev_p,
-- Q_NEXT_TYPE(fotg210, *hw_p));
-- hw_p = shadow_next_periodic(fotg210, &here,
-- Q_NEXT_TYPE(fotg210, *hw_p));
-- here = *prev_p;
-- }
-- /* an interrupt entry (at list end) could have been shared */
-- if (!here.ptr)
-- return;
--
-- /* update shadow and hardware lists ... the old "next" pointers
-- * from ptr may still be in use, the caller updates them.
-- */
-- *prev_p = *periodic_next_shadow(fotg210, &here,
-- Q_NEXT_TYPE(fotg210, *hw_p));
--
-- *hw_p = *shadow_next_periodic(fotg210, &here,
-- Q_NEXT_TYPE(fotg210, *hw_p));
--}
--
--/* how many of the uframe's 125 usecs are allocated? */
--static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
-- unsigned frame, unsigned uframe)
--{
-- __hc32 *hw_p = &fotg210->periodic[frame];
-- union fotg210_shadow *q = &fotg210->pshadow[frame];
-- unsigned usecs = 0;
-- struct fotg210_qh_hw *hw;
--
-- while (q->ptr) {
-- switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
-- case Q_TYPE_QH:
-- hw = q->qh->hw;
-- /* is it in the S-mask? */
-- if (hw->hw_info2 & cpu_to_hc32(fotg210, 1 << uframe))
-- usecs += q->qh->usecs;
-- /* ... or C-mask? */
-- if (hw->hw_info2 & cpu_to_hc32(fotg210,
-- 1 << (8 + uframe)))
-- usecs += q->qh->c_usecs;
-- hw_p = &hw->hw_next;
-- q = &q->qh->qh_next;
-- break;
-- /* case Q_TYPE_FSTN: */
-- default:
-- /* for "save place" FSTNs, count the relevant INTR
-- * bandwidth from the previous frame
-- */
-- if (q->fstn->hw_prev != FOTG210_LIST_END(fotg210))
-- fotg210_dbg(fotg210, "ignoring FSTN cost ...\n");
--
-- hw_p = &q->fstn->hw_next;
-- q = &q->fstn->fstn_next;
-- break;
-- case Q_TYPE_ITD:
-- if (q->itd->hw_transaction[uframe])
-- usecs += q->itd->stream->usecs;
-- hw_p = &q->itd->hw_next;
-- q = &q->itd->itd_next;
-- break;
-- }
-- }
-- if (usecs > fotg210->uframe_periodic_max)
-- fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",
-- frame * 8 + uframe, usecs);
-- return usecs;
--}
--
--static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
--{
-- if (!dev1->tt || !dev2->tt)
-- return 0;
-- if (dev1->tt != dev2->tt)
-- return 0;
-- if (dev1->tt->multi)
-- return dev1->ttport == dev2->ttport;
-- else
-- return 1;
--}
--
--/* return true iff the device's transaction translator is available
-- * for a periodic transfer starting at the specified frame, using
-- * all the uframes in the mask.
-- */
--static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
-- struct usb_device *dev, unsigned frame, u32 uf_mask)
--{
-- if (period == 0) /* error */
-- return 0;
--
-- /* note bandwidth wastage: split never follows csplit
-- * (different dev or endpoint) until the next uframe.
-- * calling convention doesn't make that distinction.
-- */
-- for (; frame < fotg210->periodic_size; frame += period) {
-- union fotg210_shadow here;
-- __hc32 type;
-- struct fotg210_qh_hw *hw;
--
-- here = fotg210->pshadow[frame];
-- type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
-- while (here.ptr) {
-- switch (hc32_to_cpu(fotg210, type)) {
-- case Q_TYPE_ITD:
-- type = Q_NEXT_TYPE(fotg210, here.itd->hw_next);
-- here = here.itd->itd_next;
-- continue;
-- case Q_TYPE_QH:
-- hw = here.qh->hw;
-- if (same_tt(dev, here.qh->dev)) {
-- u32 mask;
--
-- mask = hc32_to_cpu(fotg210,
-- hw->hw_info2);
-- /* "knows" no gap is needed */
-- mask |= mask >> 8;
-- if (mask & uf_mask)
-- break;
-- }
-- type = Q_NEXT_TYPE(fotg210, hw->hw_next);
-- here = here.qh->qh_next;
-- continue;
-- /* case Q_TYPE_FSTN: */
-- default:
-- fotg210_dbg(fotg210,
-- "periodic frame %d bogus type %d\n",
-- frame, type);
-- }
--
-- /* collision or error */
-- return 0;
-- }
-- }
--
-- /* no collision */
-- return 1;
--}
--
--static void enable_periodic(struct fotg210_hcd *fotg210)
--{
-- if (fotg210->periodic_count++)
-- return;
--
-- /* Stop waiting to turn off the periodic schedule */
-- fotg210->enabled_hrtimer_events &=
-- ~BIT(FOTG210_HRTIMER_DISABLE_PERIODIC);
--
-- /* Don't start the schedule until PSS is 0 */
-- fotg210_poll_PSS(fotg210);
-- turn_on_io_watchdog(fotg210);
--}
--
--static void disable_periodic(struct fotg210_hcd *fotg210)
--{
-- if (--fotg210->periodic_count)
-- return;
--
-- /* Don't turn off the schedule until PSS is 1 */
-- fotg210_poll_PSS(fotg210);
--}
--
--/* periodic schedule slots have iso tds (normal or split) first, then a
-- * sparse tree for active interrupt transfers.
-- *
-- * this just links in a qh; caller guarantees uframe masks are set right.
-- * no FSTN support (yet; fotg210 0.96+)
-- */
--static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
--{
-- unsigned i;
-- unsigned period = qh->period;
--
-- dev_dbg(&qh->dev->dev,
-- "link qh%d-%04x/%p start %d [%d/%d us]\n", period,
-- hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
-- (QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
-- qh->c_usecs);
--
-- /* high bandwidth, or otherwise every microframe */
-- if (period == 0)
-- period = 1;
--
-- for (i = qh->start; i < fotg210->periodic_size; i += period) {
-- union fotg210_shadow *prev = &fotg210->pshadow[i];
-- __hc32 *hw_p = &fotg210->periodic[i];
-- union fotg210_shadow here = *prev;
-- __hc32 type = 0;
--
-- /* skip the iso nodes at list head */
-- while (here.ptr) {
-- type = Q_NEXT_TYPE(fotg210, *hw_p);
-- if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
-- break;
-- prev = periodic_next_shadow(fotg210, prev, type);
-- hw_p = shadow_next_periodic(fotg210, &here, type);
-- here = *prev;
-- }
--
-- /* sorting each branch by period (slow-->fast)
-- * enables sharing interior tree nodes
-- */
-- while (here.ptr && qh != here.qh) {
-- if (qh->period > here.qh->period)
-- break;
-- prev = &here.qh->qh_next;
-- hw_p = &here.qh->hw->hw_next;
-- here = *prev;
-- }
-- /* link in this qh, unless some earlier pass did that */
-- if (qh != here.qh) {
-- qh->qh_next = here;
-- if (here.qh)
-- qh->hw->hw_next = *hw_p;
-- wmb();
-- prev->qh = qh;
-- *hw_p = QH_NEXT(fotg210, qh->qh_dma);
-- }
-- }
-- qh->qh_state = QH_STATE_LINKED;
-- qh->xacterrs = 0;
--
-- /* update per-qh bandwidth for usbfs */
-- fotg210_to_hcd(fotg210)->self.bandwidth_allocated += qh->period
-- ? ((qh->usecs + qh->c_usecs) / qh->period)
-- : (qh->usecs * 8);
--
-- list_add(&qh->intr_node, &fotg210->intr_qh_list);
--
-- /* maybe enable periodic schedule processing */
-- ++fotg210->intr_count;
-- enable_periodic(fotg210);
--}
--
--static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
-- struct fotg210_qh *qh)
--{
-- unsigned i;
-- unsigned period;
--
-- /*
-- * If qh is for a low/full-speed device, simply unlinking it
-- * could interfere with an ongoing split transaction. To unlink
-- * it safely would require setting the QH_INACTIVATE bit and
-- * waiting at least one frame, as described in EHCI 4.12.2.5.
-- *
-- * We won't bother with any of this. Instead, we assume that the
-- * only reason for unlinking an interrupt QH while the current URB
-- * is still active is to dequeue all the URBs (flush the whole
-- * endpoint queue).
-- *
-- * If rebalancing the periodic schedule is ever implemented, this
-- * approach will no longer be valid.
-- */
--
-- /* high bandwidth, or otherwise part of every microframe */
-- period = qh->period;
-- if (!period)
-- period = 1;
--
-- for (i = qh->start; i < fotg210->periodic_size; i += period)
-- periodic_unlink(fotg210, i, qh);
--
-- /* update per-qh bandwidth for usbfs */
-- fotg210_to_hcd(fotg210)->self.bandwidth_allocated -= qh->period
-- ? ((qh->usecs + qh->c_usecs) / qh->period)
-- : (qh->usecs * 8);
--
-- dev_dbg(&qh->dev->dev,
-- "unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-- qh->period, hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
-- (QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
-- qh->c_usecs);
--
-- /* qh->qh_next still "live" to HC */
-- qh->qh_state = QH_STATE_UNLINK;
-- qh->qh_next.ptr = NULL;
--
-- if (fotg210->qh_scan_next == qh)
-- fotg210->qh_scan_next = list_entry(qh->intr_node.next,
-- struct fotg210_qh, intr_node);
-- list_del(&qh->intr_node);
--}
--
--static void start_unlink_intr(struct fotg210_hcd *fotg210,
-- struct fotg210_qh *qh)
--{
-- /* If the QH isn't linked then there's nothing we can do
-- * unless we were called during a giveback, in which case
-- * qh_completions() has to deal with it.
-- */
-- if (qh->qh_state != QH_STATE_LINKED) {
-- if (qh->qh_state == QH_STATE_COMPLETING)
-- qh->needs_rescan = 1;
-- return;
-- }
--
-- qh_unlink_periodic(fotg210, qh);
--
-- /* Make sure the unlinks are visible before starting the timer */
-- wmb();
--
-- /*
-- * The EHCI spec doesn't say how long it takes the controller to
-- * stop accessing an unlinked interrupt QH. The timer delay is
-- * 9 uframes; presumably that will be long enough.
-- */
-- qh->unlink_cycle = fotg210->intr_unlink_cycle;
--
-- /* New entries go at the end of the intr_unlink list */
-- if (fotg210->intr_unlink)
-- fotg210->intr_unlink_last->unlink_next = qh;
-- else
-- fotg210->intr_unlink = qh;
-- fotg210->intr_unlink_last = qh;
--
-- if (fotg210->intr_unlinking)
-- ; /* Avoid recursive calls */
-- else if (fotg210->rh_state < FOTG210_RH_RUNNING)
-- fotg210_handle_intr_unlinks(fotg210);
-- else if (fotg210->intr_unlink == qh) {
-- fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-- true);
-- ++fotg210->intr_unlink_cycle;
-- }
--}
--
--static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
--{
-- struct fotg210_qh_hw *hw = qh->hw;
-- int rc;
--
-- qh->qh_state = QH_STATE_IDLE;
-- hw->hw_next = FOTG210_LIST_END(fotg210);
--
-- qh_completions(fotg210, qh);
--
-- /* reschedule QH iff another request is queued */
-- if (!list_empty(&qh->qtd_list) &&
-- fotg210->rh_state == FOTG210_RH_RUNNING) {
-- rc = qh_schedule(fotg210, qh);
--
-- /* An error here likely indicates handshake failure
-- * or no space left in the schedule. Neither fault
-- * should happen often ...
-- *
-- * FIXME kill the now-dysfunctional queued urbs
-- */
-- if (rc != 0)
-- fotg210_err(fotg210, "can't reschedule qh %p, err %d\n",
-- qh, rc);
-- }
--
-- /* maybe turn off periodic schedule */
-- --fotg210->intr_count;
-- disable_periodic(fotg210);
--}
--
--static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
-- unsigned uframe, unsigned period, unsigned usecs)
--{
-- int claimed;
--
-- /* complete split running into next frame?
-- * given FSTN support, we could sometimes check...
-- */
-- if (uframe >= 8)
-- return 0;
--
-- /* convert "usecs we need" to "max already claimed" */
-- usecs = fotg210->uframe_periodic_max - usecs;
--
-- /* we "know" 2 and 4 uframe intervals were rejected; so
-- * for period 0, check _every_ microframe in the schedule.
-- */
-- if (unlikely(period == 0)) {
-- do {
-- for (uframe = 0; uframe < 7; uframe++) {
-- claimed = periodic_usecs(fotg210, frame,
-- uframe);
-- if (claimed > usecs)
-- return 0;
-- }
-- } while ((frame += 1) < fotg210->periodic_size);
--
-- /* just check the specified uframe, at that period */
-- } else {
-- do {
-- claimed = periodic_usecs(fotg210, frame, uframe);
-- if (claimed > usecs)
-- return 0;
-- } while ((frame += period) < fotg210->periodic_size);
-- }
--
-- /* success! */
-- return 1;
--}
--
--static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
-- unsigned uframe, const struct fotg210_qh *qh, __hc32 *c_maskp)
--{
-- int retval = -ENOSPC;
-- u8 mask = 0;
--
-- if (qh->c_usecs && uframe >= 6) /* FSTN territory? */
-- goto done;
--
-- if (!check_period(fotg210, frame, uframe, qh->period, qh->usecs))
-- goto done;
-- if (!qh->c_usecs) {
-- retval = 0;
-- *c_maskp = 0;
-- goto done;
-- }
--
-- /* Make sure this tt's buffer is also available for CSPLITs.
-- * We pessimize a bit; probably the typical full speed case
-- * doesn't need the second CSPLIT.
-- *
-- * NOTE: both SPLIT and CSPLIT could be checked in just
-- * one smart pass...
-- */
-- mask = 0x03 << (uframe + qh->gap_uf);
-- *c_maskp = cpu_to_hc32(fotg210, mask << 8);
--
-- mask |= 1 << uframe;
-- if (tt_no_collision(fotg210, qh->period, qh->dev, frame, mask)) {
-- if (!check_period(fotg210, frame, uframe + qh->gap_uf + 1,
-- qh->period, qh->c_usecs))
-- goto done;
-- if (!check_period(fotg210, frame, uframe + qh->gap_uf,
-- qh->period, qh->c_usecs))
-- goto done;
-- retval = 0;
-- }
--done:
-- return retval;
--}
--
--/* "first fit" scheduling policy used the first time through,
-- * or when the previous schedule slot can't be re-used.
-- */
--static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
--{
-- int status;
-- unsigned uframe;
-- __hc32 c_mask;
-- unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */
-- struct fotg210_qh_hw *hw = qh->hw;
--
-- qh_refresh(fotg210, qh);
-- hw->hw_next = FOTG210_LIST_END(fotg210);
-- frame = qh->start;
--
-- /* reuse the previous schedule slots, if we can */
-- if (frame < qh->period) {
-- uframe = ffs(hc32_to_cpup(fotg210, &hw->hw_info2) & QH_SMASK);
-- status = check_intr_schedule(fotg210, frame, --uframe,
-- qh, &c_mask);
-- } else {
-- uframe = 0;
-- c_mask = 0;
-- status = -ENOSPC;
-- }
--
-- /* else scan the schedule to find a group of slots such that all
-- * uframes have enough periodic bandwidth available.
-- */
-- if (status) {
-- /* "normal" case, uframing flexible except with splits */
-- if (qh->period) {
-- int i;
--
-- for (i = qh->period; status && i > 0; --i) {
-- frame = ++fotg210->random_frame % qh->period;
-- for (uframe = 0; uframe < 8; uframe++) {
-- status = check_intr_schedule(fotg210,
-- frame, uframe, qh,
-- &c_mask);
-- if (status == 0)
-- break;
-- }
-- }
--
-- /* qh->period == 0 means every uframe */
-- } else {
-- frame = 0;
-- status = check_intr_schedule(fotg210, 0, 0, qh,
-- &c_mask);
-- }
-- if (status)
-- goto done;
-- qh->start = frame;
--
-- /* reset S-frame and (maybe) C-frame masks */
-- hw->hw_info2 &= cpu_to_hc32(fotg210, ~(QH_CMASK | QH_SMASK));
-- hw->hw_info2 |= qh->period
-- ? cpu_to_hc32(fotg210, 1 << uframe)
-- : cpu_to_hc32(fotg210, QH_SMASK);
-- hw->hw_info2 |= c_mask;
-- } else
-- fotg210_dbg(fotg210, "reused qh %p schedule\n", qh);
--
-- /* stuff into the periodic schedule */
-- qh_link_periodic(fotg210, qh);
--done:
-- return status;
--}
--
--static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-- struct list_head *qtd_list, gfp_t mem_flags)
--{
-- unsigned epnum;
-- unsigned long flags;
-- struct fotg210_qh *qh;
-- int status;
-- struct list_head empty;
--
-- /* get endpoint and transfer/schedule data */
-- epnum = urb->ep->desc.bEndpointAddress;
--
-- spin_lock_irqsave(&fotg210->lock, flags);
--
-- if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
-- status = -ESHUTDOWN;
-- goto done_not_linked;
-- }
-- status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
-- if (unlikely(status))
-- goto done_not_linked;
--
-- /* get qh and force any scheduling errors */
-- INIT_LIST_HEAD(&empty);
-- qh = qh_append_tds(fotg210, urb, &empty, epnum, &urb->ep->hcpriv);
-- if (qh == NULL) {
-- status = -ENOMEM;
-- goto done;
-- }
-- if (qh->qh_state == QH_STATE_IDLE) {
-- status = qh_schedule(fotg210, qh);
-- if (status)
-- goto done;
-- }
--
-- /* then queue the urb's tds to the qh */
-- qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
-- BUG_ON(qh == NULL);
--
-- /* ... update usbfs periodic stats */
-- fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs++;
--
--done:
-- if (unlikely(status))
-- usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
--done_not_linked:
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- if (status)
-- qtd_list_free(fotg210, urb, qtd_list);
--
-- return status;
--}
--
--static void scan_intr(struct fotg210_hcd *fotg210)
--{
-- struct fotg210_qh *qh;
--
-- list_for_each_entry_safe(qh, fotg210->qh_scan_next,
-- &fotg210->intr_qh_list, intr_node) {
--rescan:
-- /* clean any finished work for this qh */
-- if (!list_empty(&qh->qtd_list)) {
-- int temp;
--
-- /*
-- * Unlinks could happen here; completion reporting
-- * drops the lock. That's why fotg210->qh_scan_next
-- * always holds the next qh to scan; if the next qh
-- * gets unlinked then fotg210->qh_scan_next is adjusted
-- * in qh_unlink_periodic().
-- */
-- temp = qh_completions(fotg210, qh);
-- if (unlikely(qh->needs_rescan ||
-- (list_empty(&qh->qtd_list) &&
-- qh->qh_state == QH_STATE_LINKED)))
-- start_unlink_intr(fotg210, qh);
-- else if (temp != 0)
-- goto rescan;
-- }
-- }
--}
--
--/* fotg210_iso_stream ops work with both ITD and SITD */
--
--static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
--{
-- struct fotg210_iso_stream *stream;
--
-- stream = kzalloc(sizeof(*stream), mem_flags);
-- if (likely(stream != NULL)) {
-- INIT_LIST_HEAD(&stream->td_list);
-- INIT_LIST_HEAD(&stream->free_list);
-- stream->next_uframe = -1;
-- }
-- return stream;
--}
--
--static void iso_stream_init(struct fotg210_hcd *fotg210,
-- struct fotg210_iso_stream *stream, struct usb_device *dev,
-- int pipe, unsigned interval)
--{
-- u32 buf1;
-- unsigned epnum, maxp;
-- int is_input;
-- long bandwidth;
-- unsigned multi;
-- struct usb_host_endpoint *ep;
--
-- /*
-- * this might be a "high bandwidth" highspeed endpoint,
-- * as encoded in the ep descriptor's wMaxPacket field
-- */
-- epnum = usb_pipeendpoint(pipe);
-- is_input = usb_pipein(pipe) ? USB_DIR_IN : 0;
-- ep = usb_pipe_endpoint(dev, pipe);
-- maxp = usb_endpoint_maxp(&ep->desc);
-- if (is_input)
-- buf1 = (1 << 11);
-- else
-- buf1 = 0;
--
-- multi = usb_endpoint_maxp_mult(&ep->desc);
-- buf1 |= maxp;
-- maxp *= multi;
--
-- stream->buf0 = cpu_to_hc32(fotg210, (epnum << 8) | dev->devnum);
-- stream->buf1 = cpu_to_hc32(fotg210, buf1);
-- stream->buf2 = cpu_to_hc32(fotg210, multi);
--
-- /* usbfs wants to report the average usecs per frame tied up
-- * when transfers on this endpoint are scheduled ...
-- */
-- if (dev->speed == USB_SPEED_FULL) {
-- interval <<= 3;
-- stream->usecs = NS_TO_US(usb_calc_bus_time(dev->speed,
-- is_input, 1, maxp));
-- stream->usecs /= 8;
-- } else {
-- stream->highspeed = 1;
-- stream->usecs = HS_USECS_ISO(maxp);
-- }
-- bandwidth = stream->usecs * 8;
-- bandwidth /= interval;
--
-- stream->bandwidth = bandwidth;
-- stream->udev = dev;
-- stream->bEndpointAddress = is_input | epnum;
-- stream->interval = interval;
-- stream->maxp = maxp;
--}
--
--static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
-- struct urb *urb)
--{
-- unsigned epnum;
-- struct fotg210_iso_stream *stream;
-- struct usb_host_endpoint *ep;
-- unsigned long flags;
--
-- epnum = usb_pipeendpoint(urb->pipe);
-- if (usb_pipein(urb->pipe))
-- ep = urb->dev->ep_in[epnum];
-- else
-- ep = urb->dev->ep_out[epnum];
--
-- spin_lock_irqsave(&fotg210->lock, flags);
-- stream = ep->hcpriv;
--
-- if (unlikely(stream == NULL)) {
-- stream = iso_stream_alloc(GFP_ATOMIC);
-- if (likely(stream != NULL)) {
-- ep->hcpriv = stream;
-- stream->ep = ep;
-- iso_stream_init(fotg210, stream, urb->dev, urb->pipe,
-- urb->interval);
-- }
--
-- /* if dev->ep[epnum] is a QH, hw is set */
-- } else if (unlikely(stream->hw != NULL)) {
-- fotg210_dbg(fotg210, "dev %s ep%d%s, not iso??\n",
-- urb->dev->devpath, epnum,
-- usb_pipein(urb->pipe) ? "in" : "out");
-- stream = NULL;
-- }
--
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- return stream;
--}
--
--/* fotg210_iso_sched ops can be ITD-only or SITD-only */
--
--static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
-- gfp_t mem_flags)
--{
-- struct fotg210_iso_sched *iso_sched;
--
-- iso_sched = kzalloc(struct_size(iso_sched, packet, packets), mem_flags);
-- if (likely(iso_sched != NULL))
-- INIT_LIST_HEAD(&iso_sched->td_list);
--
-- return iso_sched;
--}
--
--static inline void itd_sched_init(struct fotg210_hcd *fotg210,
-- struct fotg210_iso_sched *iso_sched,
-- struct fotg210_iso_stream *stream, struct urb *urb)
--{
-- unsigned i;
-- dma_addr_t dma = urb->transfer_dma;
--
-- /* how many uframes are needed for these transfers */
-- iso_sched->span = urb->number_of_packets * stream->interval;
--
-- /* figure out per-uframe itd fields that we'll need later
-- * when we fit new itds into the schedule.
-- */
-- for (i = 0; i < urb->number_of_packets; i++) {
-- struct fotg210_iso_packet *uframe = &iso_sched->packet[i];
-- unsigned length;
-- dma_addr_t buf;
-- u32 trans;
--
-- length = urb->iso_frame_desc[i].length;
-- buf = dma + urb->iso_frame_desc[i].offset;
--
-- trans = FOTG210_ISOC_ACTIVE;
-- trans |= buf & 0x0fff;
-- if (unlikely(((i + 1) == urb->number_of_packets))
-- && !(urb->transfer_flags & URB_NO_INTERRUPT))
-- trans |= FOTG210_ITD_IOC;
-- trans |= length << 16;
-- uframe->transaction = cpu_to_hc32(fotg210, trans);
--
-- /* might need to cross a buffer page within a uframe */
-- uframe->bufp = (buf & ~(u64)0x0fff);
-- buf += length;
-- if (unlikely((uframe->bufp != (buf & ~(u64)0x0fff))))
-- uframe->cross = 1;
-- }
--}
--
--static void iso_sched_free(struct fotg210_iso_stream *stream,
-- struct fotg210_iso_sched *iso_sched)
--{
-- if (!iso_sched)
-- return;
-- /* caller must hold fotg210->lock!*/
-- list_splice(&iso_sched->td_list, &stream->free_list);
-- kfree(iso_sched);
--}
--
--static int itd_urb_transaction(struct fotg210_iso_stream *stream,
-- struct fotg210_hcd *fotg210, struct urb *urb, gfp_t mem_flags)
--{
-- struct fotg210_itd *itd;
-- dma_addr_t itd_dma;
-- int i;
-- unsigned num_itds;
-- struct fotg210_iso_sched *sched;
-- unsigned long flags;
--
-- sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
-- if (unlikely(sched == NULL))
-- return -ENOMEM;
--
-- itd_sched_init(fotg210, sched, stream, urb);
--
-- if (urb->interval < 8)
-- num_itds = 1 + (sched->span + 7) / 8;
-- else
-- num_itds = urb->number_of_packets;
--
-- /* allocate/init ITDs */
-- spin_lock_irqsave(&fotg210->lock, flags);
-- for (i = 0; i < num_itds; i++) {
--
-- /*
-- * Use iTDs from the free list, but not iTDs that may
-- * still be in use by the hardware.
-- */
-- if (likely(!list_empty(&stream->free_list))) {
-- itd = list_first_entry(&stream->free_list,
-- struct fotg210_itd, itd_list);
-- if (itd->frame == fotg210->now_frame)
-- goto alloc_itd;
-- list_del(&itd->itd_list);
-- itd_dma = itd->itd_dma;
-- } else {
--alloc_itd:
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
-- &itd_dma);
-- spin_lock_irqsave(&fotg210->lock, flags);
-- if (!itd) {
-- iso_sched_free(stream, sched);
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- return -ENOMEM;
-- }
-- }
--
-- memset(itd, 0, sizeof(*itd));
-- itd->itd_dma = itd_dma;
-- list_add(&itd->itd_list, &sched->td_list);
-- }
-- spin_unlock_irqrestore(&fotg210->lock, flags);
--
-- /* temporarily store schedule info in hcpriv */
-- urb->hcpriv = sched;
-- urb->error_count = 0;
-- return 0;
--}
--
--static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
-- u8 usecs, u32 period)
--{
-- uframe %= period;
-- do {
-- /* can't commit more than uframe_periodic_max usec */
-- if (periodic_usecs(fotg210, uframe >> 3, uframe & 0x7)
-- > (fotg210->uframe_periodic_max - usecs))
-- return 0;
--
-- /* we know urb->interval is 2^N uframes */
-- uframe += period;
-- } while (uframe < mod);
-- return 1;
--}
--
--/* This scheduler plans almost as far into the future as it has actual
-- * periodic schedule slots. (Affected by TUNE_FLS, which defaults to
-- * "as small as possible" to be cache-friendlier.) That limits the size
-- * transfers you can stream reliably; avoid more than 64 msec per urb.
-- * Also avoid queue depths of less than fotg210's worst irq latency (affected
-- * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
-- * and other factors); or more than about 230 msec total (for portability,
-- * given FOTG210_TUNE_FLS and the slop). Or, write a smarter scheduler!
-- */
--
--#define SCHEDULE_SLOP 80 /* microframes */
--
--static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
-- struct fotg210_iso_stream *stream)
--{
-- u32 now, next, start, period, span;
-- int status;
-- unsigned mod = fotg210->periodic_size << 3;
-- struct fotg210_iso_sched *sched = urb->hcpriv;
--
-- period = urb->interval;
-- span = sched->span;
--
-- if (span > mod - SCHEDULE_SLOP) {
-- fotg210_dbg(fotg210, "iso request %p too long\n", urb);
-- status = -EFBIG;
-- goto fail;
-- }
--
-- now = fotg210_read_frame_index(fotg210) & (mod - 1);
--
-- /* Typical case: reuse current schedule, stream is still active.
-- * Hopefully there are no gaps from the host falling behind
-- * (irq delays etc), but if there are we'll take the next
-- * slot in the schedule, implicitly assuming URB_ISO_ASAP.
-- */
-- if (likely(!list_empty(&stream->td_list))) {
-- u32 excess;
--
-- /* For high speed devices, allow scheduling within the
-- * isochronous scheduling threshold. For full speed devices
-- * and Intel PCI-based controllers, don't (work around for
-- * Intel ICH9 bug).
-- */
-- if (!stream->highspeed && fotg210->fs_i_thresh)
-- next = now + fotg210->i_thresh;
-- else
-- next = now;
--
-- /* Fell behind (by up to twice the slop amount)?
-- * We decide based on the time of the last currently-scheduled
-- * slot, not the time of the next available slot.
-- */
-- excess = (stream->next_uframe - period - next) & (mod - 1);
-- if (excess >= mod - 2 * SCHEDULE_SLOP)
-- start = next + excess - mod + period *
-- DIV_ROUND_UP(mod - excess, period);
-- else
-- start = next + excess + period;
-- if (start - now >= mod) {
-- fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
-- urb, start - now - period, period,
-- mod);
-- status = -EFBIG;
-- goto fail;
-- }
-- }
--
-- /* need to schedule; when's the next (u)frame we could start?
-- * this is bigger than fotg210->i_thresh allows; scheduling itself
-- * isn't free, the slop should handle reasonably slow cpus. it
-- * can also help high bandwidth if the dma and irq loads don't
-- * jump until after the queue is primed.
-- */
-- else {
-- int done = 0;
--
-- start = SCHEDULE_SLOP + (now & ~0x07);
--
-- /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
--
-- /* find a uframe slot with enough bandwidth.
-- * Early uframes are more precious because full-speed
-- * iso IN transfers can't use late uframes,
-- * and therefore they should be allocated last.
-- */
-- next = start;
-- start += period;
-- do {
-- start--;
-- /* check schedule: enough space? */
-- if (itd_slot_ok(fotg210, mod, start,
-- stream->usecs, period))
-- done = 1;
-- } while (start > next && !done);
--
-- /* no room in the schedule */
-- if (!done) {
-- fotg210_dbg(fotg210, "iso resched full %p (now %d max %d)\n",
-- urb, now, now + mod);
-- status = -ENOSPC;
-- goto fail;
-- }
-- }
--
-- /* Tried to schedule too far into the future? */
-- if (unlikely(start - now + span - period >=
-- mod - 2 * SCHEDULE_SLOP)) {
-- fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
-- urb, start - now, span - period,
-- mod - 2 * SCHEDULE_SLOP);
-- status = -EFBIG;
-- goto fail;
-- }
--
-- stream->next_uframe = start & (mod - 1);
--
-- /* report high speed start in uframes; full speed, in frames */
-- urb->start_frame = stream->next_uframe;
-- if (!stream->highspeed)
-- urb->start_frame >>= 3;
--
-- /* Make sure scan_isoc() sees these */
-- if (fotg210->isoc_count == 0)
-- fotg210->next_frame = now >> 3;
-- return 0;
--
--fail:
-- iso_sched_free(stream, sched);
-- urb->hcpriv = NULL;
-- return status;
--}
--
--static inline void itd_init(struct fotg210_hcd *fotg210,
-- struct fotg210_iso_stream *stream, struct fotg210_itd *itd)
--{
-- int i;
--
-- /* it's been recently zeroed */
-- itd->hw_next = FOTG210_LIST_END(fotg210);
-- itd->hw_bufp[0] = stream->buf0;
-- itd->hw_bufp[1] = stream->buf1;
-- itd->hw_bufp[2] = stream->buf2;
--
-- for (i = 0; i < 8; i++)
-- itd->index[i] = -1;
--
-- /* All other fields are filled when scheduling */
--}
--
--static inline void itd_patch(struct fotg210_hcd *fotg210,
-- struct fotg210_itd *itd, struct fotg210_iso_sched *iso_sched,
-- unsigned index, u16 uframe)
--{
-- struct fotg210_iso_packet *uf = &iso_sched->packet[index];
-- unsigned pg = itd->pg;
--
-- uframe &= 0x07;
-- itd->index[uframe] = index;
--
-- itd->hw_transaction[uframe] = uf->transaction;
-- itd->hw_transaction[uframe] |= cpu_to_hc32(fotg210, pg << 12);
-- itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, uf->bufp & ~(u32)0);
-- itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(uf->bufp >> 32));
--
-- /* iso_frame_desc[].offset must be strictly increasing */
-- if (unlikely(uf->cross)) {
-- u64 bufp = uf->bufp + 4096;
--
-- itd->pg = ++pg;
-- itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
-- itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(bufp >> 32));
-- }
--}
--
--static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
-- struct fotg210_itd *itd)
--{
-- union fotg210_shadow *prev = &fotg210->pshadow[frame];
-- __hc32 *hw_p = &fotg210->periodic[frame];
-- union fotg210_shadow here = *prev;
-- __hc32 type = 0;
--
-- /* skip any iso nodes which might belong to previous microframes */
-- while (here.ptr) {
-- type = Q_NEXT_TYPE(fotg210, *hw_p);
-- if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
-- break;
-- prev = periodic_next_shadow(fotg210, prev, type);
-- hw_p = shadow_next_periodic(fotg210, &here, type);
-- here = *prev;
-- }
--
-- itd->itd_next = here;
-- itd->hw_next = *hw_p;
-- prev->itd = itd;
-- itd->frame = frame;
-- wmb();
-- *hw_p = cpu_to_hc32(fotg210, itd->itd_dma | Q_TYPE_ITD);
--}
--
--/* fit urb's itds into the selected schedule slot; activate as needed */
--static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
-- unsigned mod, struct fotg210_iso_stream *stream)
--{
-- int packet;
-- unsigned next_uframe, uframe, frame;
-- struct fotg210_iso_sched *iso_sched = urb->hcpriv;
-- struct fotg210_itd *itd;
--
-- next_uframe = stream->next_uframe & (mod - 1);
--
-- if (unlikely(list_empty(&stream->td_list))) {
-- fotg210_to_hcd(fotg210)->self.bandwidth_allocated
-- += stream->bandwidth;
-- fotg210_dbg(fotg210,
-- "schedule devp %s ep%d%s-iso period %d start %d.%d\n",
-- urb->dev->devpath, stream->bEndpointAddress & 0x0f,
-- (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
-- urb->interval,
-- next_uframe >> 3, next_uframe & 0x7);
-- }
--
-- /* fill iTDs uframe by uframe */
-- for (packet = 0, itd = NULL; packet < urb->number_of_packets;) {
-- if (itd == NULL) {
-- /* ASSERT: we have all necessary itds */
--
-- /* ASSERT: no itds for this endpoint in this uframe */
--
-- itd = list_entry(iso_sched->td_list.next,
-- struct fotg210_itd, itd_list);
-- list_move_tail(&itd->itd_list, &stream->td_list);
-- itd->stream = stream;
-- itd->urb = urb;
-- itd_init(fotg210, stream, itd);
-- }
--
-- uframe = next_uframe & 0x07;
-- frame = next_uframe >> 3;
--
-- itd_patch(fotg210, itd, iso_sched, packet, uframe);
--
-- next_uframe += stream->interval;
-- next_uframe &= mod - 1;
-- packet++;
--
-- /* link completed itds into the schedule */
-- if (((next_uframe >> 3) != frame)
-- || packet == urb->number_of_packets) {
-- itd_link(fotg210, frame & (fotg210->periodic_size - 1),
-- itd);
-- itd = NULL;
-- }
-- }
-- stream->next_uframe = next_uframe;
--
-- /* don't need that schedule data any more */
-- iso_sched_free(stream, iso_sched);
-- urb->hcpriv = NULL;
--
-- ++fotg210->isoc_count;
-- enable_periodic(fotg210);
--}
--
--#define ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
-- FOTG210_ISOC_XACTERR)
--
--/* Process and recycle a completed ITD. Return true iff its urb completed,
-- * and hence its completion callback probably added things to the hardware
-- * schedule.
-- *
-- * Note that we carefully avoid recycling this descriptor until after any
-- * completion callback runs, so that it won't be reused quickly. That is,
-- * assuming (a) no more than two urbs per frame on this endpoint, and also
-- * (b) only this endpoint's completions submit URBs. It seems some silicon
-- * corrupts things if you reuse completed descriptors very quickly...
-- */
--static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
--{
-- struct urb *urb = itd->urb;
-- struct usb_iso_packet_descriptor *desc;
-- u32 t;
-- unsigned uframe;
-- int urb_index = -1;
-- struct fotg210_iso_stream *stream = itd->stream;
-- struct usb_device *dev;
-- bool retval = false;
--
-- /* for each uframe with a packet */
-- for (uframe = 0; uframe < 8; uframe++) {
-- if (likely(itd->index[uframe] == -1))
-- continue;
-- urb_index = itd->index[uframe];
-- desc = &urb->iso_frame_desc[urb_index];
--
-- t = hc32_to_cpup(fotg210, &itd->hw_transaction[uframe]);
-- itd->hw_transaction[uframe] = 0;
--
-- /* report transfer status */
-- if (unlikely(t & ISO_ERRS)) {
-- urb->error_count++;
-- if (t & FOTG210_ISOC_BUF_ERR)
-- desc->status = usb_pipein(urb->pipe)
-- ? -ENOSR /* hc couldn't read */
-- : -ECOMM; /* hc couldn't write */
-- else if (t & FOTG210_ISOC_BABBLE)
-- desc->status = -EOVERFLOW;
-- else /* (t & FOTG210_ISOC_XACTERR) */
-- desc->status = -EPROTO;
--
-- /* HC need not update length with this error */
-- if (!(t & FOTG210_ISOC_BABBLE)) {
-- desc->actual_length = FOTG210_ITD_LENGTH(t);
-- urb->actual_length += desc->actual_length;
-- }
-- } else if (likely((t & FOTG210_ISOC_ACTIVE) == 0)) {
-- desc->status = 0;
-- desc->actual_length = FOTG210_ITD_LENGTH(t);
-- urb->actual_length += desc->actual_length;
-- } else {
-- /* URB was too late */
-- desc->status = -EXDEV;
-- }
-- }
--
-- /* handle completion now? */
-- if (likely((urb_index + 1) != urb->number_of_packets))
-- goto done;
--
-- /* ASSERT: it's really the last itd for this urb
-- * list_for_each_entry (itd, &stream->td_list, itd_list)
-- * BUG_ON (itd->urb == urb);
-- */
--
-- /* give urb back to the driver; completion often (re)submits */
-- dev = urb->dev;
-- fotg210_urb_done(fotg210, urb, 0);
-- retval = true;
-- urb = NULL;
--
-- --fotg210->isoc_count;
-- disable_periodic(fotg210);
--
-- if (unlikely(list_is_singular(&stream->td_list))) {
-- fotg210_to_hcd(fotg210)->self.bandwidth_allocated
-- -= stream->bandwidth;
-- fotg210_dbg(fotg210,
-- "deschedule devp %s ep%d%s-iso\n",
-- dev->devpath, stream->bEndpointAddress & 0x0f,
-- (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
-- }
--
--done:
-- itd->urb = NULL;
--
-- /* Add to the end of the free list for later reuse */
-- list_move_tail(&itd->itd_list, &stream->free_list);
--
-- /* Recycle the iTDs when the pipeline is empty (ep no longer in use) */
-- if (list_empty(&stream->td_list)) {
-- list_splice_tail_init(&stream->free_list,
-- &fotg210->cached_itd_list);
-- start_free_itds(fotg210);
-- }
--
-- return retval;
--}
--
--static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-- gfp_t mem_flags)
--{
-- int status = -EINVAL;
-- unsigned long flags;
-- struct fotg210_iso_stream *stream;
--
-- /* Get iso_stream head */
-- stream = iso_stream_find(fotg210, urb);
-- if (unlikely(stream == NULL)) {
-- fotg210_dbg(fotg210, "can't get iso stream\n");
-- return -ENOMEM;
-- }
-- if (unlikely(urb->interval != stream->interval &&
-- fotg210_port_speed(fotg210, 0) ==
-- USB_PORT_STAT_HIGH_SPEED)) {
-- fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
-- stream->interval, urb->interval);
-- goto done;
-- }
--
--#ifdef FOTG210_URB_TRACE
-- fotg210_dbg(fotg210,
-- "%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
-- __func__, urb->dev->devpath, urb,
-- usb_pipeendpoint(urb->pipe),
-- usb_pipein(urb->pipe) ? "in" : "out",
-- urb->transfer_buffer_length,
-- urb->number_of_packets, urb->interval,
-- stream);
--#endif
--
-- /* allocate ITDs w/o locking anything */
-- status = itd_urb_transaction(stream, fotg210, urb, mem_flags);
-- if (unlikely(status < 0)) {
-- fotg210_dbg(fotg210, "can't init itds\n");
-- goto done;
-- }
--
-- /* schedule ... need to lock */
-- spin_lock_irqsave(&fotg210->lock, flags);
-- if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
-- status = -ESHUTDOWN;
-- goto done_not_linked;
-- }
-- status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
-- if (unlikely(status))
-- goto done_not_linked;
-- status = iso_stream_schedule(fotg210, urb, stream);
-- if (likely(status == 0))
-- itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
-- else
-- usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
--done_not_linked:
-- spin_unlock_irqrestore(&fotg210->lock, flags);
--done:
-- return status;
--}
--
--static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
-- unsigned now_frame, bool live)
--{
-- unsigned uf;
-- bool modified;
-- union fotg210_shadow q, *q_p;
-- __hc32 type, *hw_p;
--
-- /* scan each element in frame's queue for completions */
-- q_p = &fotg210->pshadow[frame];
-- hw_p = &fotg210->periodic[frame];
-- q.ptr = q_p->ptr;
-- type = Q_NEXT_TYPE(fotg210, *hw_p);
-- modified = false;
--
-- while (q.ptr) {
-- switch (hc32_to_cpu(fotg210, type)) {
-- case Q_TYPE_ITD:
-- /* If this ITD is still active, leave it for
-- * later processing ... check the next entry.
-- * No need to check for activity unless the
-- * frame is current.
-- */
-- if (frame == now_frame && live) {
-- rmb();
-- for (uf = 0; uf < 8; uf++) {
-- if (q.itd->hw_transaction[uf] &
-- ITD_ACTIVE(fotg210))
-- break;
-- }
-- if (uf < 8) {
-- q_p = &q.itd->itd_next;
-- hw_p = &q.itd->hw_next;
-- type = Q_NEXT_TYPE(fotg210,
-- q.itd->hw_next);
-- q = *q_p;
-- break;
-- }
-- }
--
-- /* Take finished ITDs out of the schedule
-- * and process them: recycle, maybe report
-- * URB completion. HC won't cache the
-- * pointer for much longer, if at all.
-- */
-- *q_p = q.itd->itd_next;
-- *hw_p = q.itd->hw_next;
-- type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
-- wmb();
-- modified = itd_complete(fotg210, q.itd);
-- q = *q_p;
-- break;
-- default:
-- fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
-- type, frame, q.ptr);
-- fallthrough;
-- case Q_TYPE_QH:
-- case Q_TYPE_FSTN:
-- /* End of the iTDs and siTDs */
-- q.ptr = NULL;
-- break;
-- }
--
-- /* assume completion callbacks modify the queue */
-- if (unlikely(modified && fotg210->isoc_count > 0))
-- return -EINVAL;
-- }
-- return 0;
--}
--
--static void scan_isoc(struct fotg210_hcd *fotg210)
--{
-- unsigned uf, now_frame, frame, ret;
-- unsigned fmask = fotg210->periodic_size - 1;
-- bool live;
--
-- /*
-- * When running, scan from last scan point up to "now"
-- * else clean up by scanning everything that's left.
-- * Touches as few pages as possible: cache-friendly.
-- */
-- if (fotg210->rh_state >= FOTG210_RH_RUNNING) {
-- uf = fotg210_read_frame_index(fotg210);
-- now_frame = (uf >> 3) & fmask;
-- live = true;
-- } else {
-- now_frame = (fotg210->next_frame - 1) & fmask;
-- live = false;
-- }
-- fotg210->now_frame = now_frame;
--
-- frame = fotg210->next_frame;
-- for (;;) {
-- ret = 1;
-- while (ret != 0)
-- ret = scan_frame_queue(fotg210, frame,
-- now_frame, live);
--
-- /* Stop when we have reached the current frame */
-- if (frame == now_frame)
-- break;
-- frame = (frame + 1) & fmask;
-- }
-- fotg210->next_frame = now_frame;
--}
--
--/* Display / Set uframe_periodic_max
-- */
--static ssize_t uframe_periodic_max_show(struct device *dev,
-- struct device_attribute *attr, char *buf)
--{
-- struct fotg210_hcd *fotg210;
-- int n;
--
-- fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
-- n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
-- return n;
--}
--
--
--static ssize_t uframe_periodic_max_store(struct device *dev,
-- struct device_attribute *attr, const char *buf, size_t count)
--{
-- struct fotg210_hcd *fotg210;
-- unsigned uframe_periodic_max;
-- unsigned frame, uframe;
-- unsigned short allocated_max;
-- unsigned long flags;
-- ssize_t ret;
--
-- fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
-- if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
-- return -EINVAL;
--
-- if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
-- fotg210_info(fotg210, "rejecting invalid request for uframe_periodic_max=%u\n",
-- uframe_periodic_max);
-- return -EINVAL;
-- }
--
-- ret = -EINVAL;
--
-- /*
-- * lock, so that our checking does not race with possible periodic
-- * bandwidth allocation through submitting new urbs.
-- */
-- spin_lock_irqsave(&fotg210->lock, flags);
--
-- /*
-- * for request to decrease max periodic bandwidth, we have to check
-- * every microframe in the schedule to see whether the decrease is
-- * possible.
-- */
-- if (uframe_periodic_max < fotg210->uframe_periodic_max) {
-- allocated_max = 0;
--
-- for (frame = 0; frame < fotg210->periodic_size; ++frame)
-- for (uframe = 0; uframe < 7; ++uframe)
-- allocated_max = max(allocated_max,
-- periodic_usecs(fotg210, frame,
-- uframe));
--
-- if (allocated_max > uframe_periodic_max) {
-- fotg210_info(fotg210,
-- "cannot decrease uframe_periodic_max because periodic bandwidth is already allocated (%u > %u)\n",
-- allocated_max, uframe_periodic_max);
-- goto out_unlock;
-- }
-- }
--
-- /* increasing is always ok */
--
-- fotg210_info(fotg210,
-- "setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
-- 100 * uframe_periodic_max/125, uframe_periodic_max);
--
-- if (uframe_periodic_max != 100)
-- fotg210_warn(fotg210, "max periodic bandwidth set is non-standard\n");
--
-- fotg210->uframe_periodic_max = uframe_periodic_max;
-- ret = count;
--
--out_unlock:
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- return ret;
--}
--
--static DEVICE_ATTR_RW(uframe_periodic_max);
--
--static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
--{
-- struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
--
-- return device_create_file(controller, &dev_attr_uframe_periodic_max);
--}
--
--static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
--{
-- struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
--
-- device_remove_file(controller, &dev_attr_uframe_periodic_max);
--}
--/* On some systems, leaving remote wakeup enabled prevents system shutdown.
-- * The firmware seems to think that powering off is a wakeup event!
-- * This routine turns off remote wakeup and everything else, on all ports.
-- */
--static void fotg210_turn_off_all_ports(struct fotg210_hcd *fotg210)
--{
-- u32 __iomem *status_reg = &fotg210->regs->port_status;
--
-- fotg210_writel(fotg210, PORT_RWC_BITS, status_reg);
--}
--
--/* Halt HC, turn off all ports, and let the BIOS use the companion controllers.
-- * Must be called with interrupts enabled and the lock not held.
-- */
--static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
--{
-- fotg210_halt(fotg210);
--
-- spin_lock_irq(&fotg210->lock);
-- fotg210->rh_state = FOTG210_RH_HALTED;
-- fotg210_turn_off_all_ports(fotg210);
-- spin_unlock_irq(&fotg210->lock);
--}
--
--/* fotg210_shutdown kick in for silicon on any bus (not just pci, etc).
-- * This forcibly disables dma and IRQs, helping kexec and other cases
-- * where the next system software may expect clean state.
-- */
--static void fotg210_shutdown(struct usb_hcd *hcd)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
--
-- spin_lock_irq(&fotg210->lock);
-- fotg210->shutdown = true;
-- fotg210->rh_state = FOTG210_RH_STOPPING;
-- fotg210->enabled_hrtimer_events = 0;
-- spin_unlock_irq(&fotg210->lock);
--
-- fotg210_silence_controller(fotg210);
--
-- hrtimer_cancel(&fotg210->hrtimer);
--}
--
--/* fotg210_work is called from some interrupts, timers, and so on.
-- * it calls driver completion functions, after dropping fotg210->lock.
-- */
--static void fotg210_work(struct fotg210_hcd *fotg210)
--{
-- /* another CPU may drop fotg210->lock during a schedule scan while
-- * it reports urb completions. this flag guards against bogus
-- * attempts at re-entrant schedule scanning.
-- */
-- if (fotg210->scanning) {
-- fotg210->need_rescan = true;
-- return;
-- }
-- fotg210->scanning = true;
--
--rescan:
-- fotg210->need_rescan = false;
-- if (fotg210->async_count)
-- scan_async(fotg210);
-- if (fotg210->intr_count > 0)
-- scan_intr(fotg210);
-- if (fotg210->isoc_count > 0)
-- scan_isoc(fotg210);
-- if (fotg210->need_rescan)
-- goto rescan;
-- fotg210->scanning = false;
--
-- /* the IO watchdog guards against hardware or driver bugs that
-- * misplace IRQs, and should let us run completely without IRQs.
-- * such lossage has been observed on both VT6202 and VT8235.
-- */
-- turn_on_io_watchdog(fotg210);
--}
--
--/* Called when the fotg210_hcd module is removed.
-- */
--static void fotg210_stop(struct usb_hcd *hcd)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
--
-- fotg210_dbg(fotg210, "stop\n");
--
-- /* no more interrupts ... */
--
-- spin_lock_irq(&fotg210->lock);
-- fotg210->enabled_hrtimer_events = 0;
-- spin_unlock_irq(&fotg210->lock);
--
-- fotg210_quiesce(fotg210);
-- fotg210_silence_controller(fotg210);
-- fotg210_reset(fotg210);
--
-- hrtimer_cancel(&fotg210->hrtimer);
-- remove_sysfs_files(fotg210);
-- remove_debug_files(fotg210);
--
-- /* root hub is shut down separately (first, when possible) */
-- spin_lock_irq(&fotg210->lock);
-- end_free_itds(fotg210);
-- spin_unlock_irq(&fotg210->lock);
-- fotg210_mem_cleanup(fotg210);
--
--#ifdef FOTG210_STATS
-- fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-- fotg210->stats.normal, fotg210->stats.error,
-- fotg210->stats.iaa, fotg210->stats.lost_iaa);
-- fotg210_dbg(fotg210, "complete %ld unlink %ld\n",
-- fotg210->stats.complete, fotg210->stats.unlink);
--#endif
--
-- dbg_status(fotg210, "fotg210_stop completed",
-- fotg210_readl(fotg210, &fotg210->regs->status));
--}
--
--/* one-time init, only for memory state */
--static int hcd_fotg210_init(struct usb_hcd *hcd)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- u32 temp;
-- int retval;
-- u32 hcc_params;
-- struct fotg210_qh_hw *hw;
--
-- spin_lock_init(&fotg210->lock);
--
-- /*
-- * keep io watchdog by default, those good HCDs could turn off it later
-- */
-- fotg210->need_io_watchdog = 1;
--
-- hrtimer_init(&fotg210->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-- fotg210->hrtimer.function = fotg210_hrtimer_func;
-- fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
--
-- hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
--
-- /*
-- * by default set standard 80% (== 100 usec/uframe) max periodic
-- * bandwidth as required by USB 2.0
-- */
-- fotg210->uframe_periodic_max = 100;
--
-- /*
-- * hw default: 1K periodic list heads, one per frame.
-- * periodic_size can shrink by USBCMD update if hcc_params allows.
-- */
-- fotg210->periodic_size = DEFAULT_I_TDPS;
-- INIT_LIST_HEAD(&fotg210->intr_qh_list);
-- INIT_LIST_HEAD(&fotg210->cached_itd_list);
--
-- if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-- /* periodic schedule size can be smaller than default */
-- switch (FOTG210_TUNE_FLS) {
-- case 0:
-- fotg210->periodic_size = 1024;
-- break;
-- case 1:
-- fotg210->periodic_size = 512;
-- break;
-- case 2:
-- fotg210->periodic_size = 256;
-- break;
-- default:
-- BUG();
-- }
-- }
-- retval = fotg210_mem_init(fotg210, GFP_KERNEL);
-- if (retval < 0)
-- return retval;
--
-- /* controllers may cache some of the periodic schedule ... */
-- fotg210->i_thresh = 2;
--
-- /*
-- * dedicate a qh for the async ring head, since we couldn't unlink
-- * a 'real' qh without stopping the async schedule [4.8]. use it
-- * as the 'reclamation list head' too.
-- * its dummy is used in hw_alt_next of many tds, to prevent the qh
-- * from automatically advancing to the next td after short reads.
-- */
-- fotg210->async->qh_next.qh = NULL;
-- hw = fotg210->async->hw;
-- hw->hw_next = QH_NEXT(fotg210, fotg210->async->qh_dma);
-- hw->hw_info1 = cpu_to_hc32(fotg210, QH_HEAD);
-- hw->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
-- hw->hw_qtd_next = FOTG210_LIST_END(fotg210);
-- fotg210->async->qh_state = QH_STATE_LINKED;
-- hw->hw_alt_next = QTD_NEXT(fotg210, fotg210->async->dummy->qtd_dma);
--
-- /* clear interrupt enables, set irq latency */
-- if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
-- log2_irq_thresh = 0;
-- temp = 1 << (16 + log2_irq_thresh);
-- if (HCC_CANPARK(hcc_params)) {
-- /* HW default park == 3, on hardware that supports it (like
-- * NVidia and ALI silicon), maximizes throughput on the async
-- * schedule by avoiding QH fetches between transfers.
-- *
-- * With fast usb storage devices and NForce2, "park" seems to
-- * make problems: throughput reduction (!), data errors...
-- */
-- if (park) {
-- park = min_t(unsigned, park, 3);
-- temp |= CMD_PARK;
-- temp |= park << 8;
-- }
-- fotg210_dbg(fotg210, "park %d\n", park);
-- }
-- if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-- /* periodic schedule size can be smaller than default */
-- temp &= ~(3 << 2);
-- temp |= (FOTG210_TUNE_FLS << 2);
-- }
-- fotg210->command = temp;
--
-- /* Accept arbitrarily long scatter-gather lists */
-- if (!hcd->localmem_pool)
-- hcd->self.sg_tablesize = ~0;
-- return 0;
--}
--
--/* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
--static int fotg210_run(struct usb_hcd *hcd)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- u32 temp;
--
-- hcd->uses_new_polling = 1;
--
-- /* EHCI spec section 4.1 */
--
-- fotg210_writel(fotg210, fotg210->periodic_dma,
-- &fotg210->regs->frame_list);
-- fotg210_writel(fotg210, (u32)fotg210->async->qh_dma,
-- &fotg210->regs->async_next);
--
-- /*
-- * hcc_params controls whether fotg210->regs->segment must (!!!)
-- * be used; it constrains QH/ITD/SITD and QTD locations.
-- * dma_pool consistent memory always uses segment zero.
-- * streaming mappings for I/O buffers, like dma_map_single(),
-- * can return segments above 4GB, if the device allows.
-- *
-- * NOTE: the dma mask is visible through dev->dma_mask, so
-- * drivers can pass this info along ... like NETIF_F_HIGHDMA,
-- * Scsi_Host.highmem_io, and so forth. It's readonly to all
-- * host side drivers though.
-- */
-- fotg210_readl(fotg210, &fotg210->caps->hcc_params);
--
-- /*
-- * Philips, Intel, and maybe others need CMD_RUN before the
-- * root hub will detect new devices (why?); NEC doesn't
-- */
-- fotg210->command &= ~(CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
-- fotg210->command |= CMD_RUN;
-- fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-- dbg_cmd(fotg210, "init", fotg210->command);
--
-- /*
-- * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
-- * are explicitly handed to companion controller(s), so no TT is
-- * involved with the root hub. (Except where one is integrated,
-- * and there's no companion controller unless maybe for USB OTG.)
-- *
-- * Turning on the CF flag will transfer ownership of all ports
-- * from the companions to the EHCI controller. If any of the
-- * companions are in the middle of a port reset at the time, it
-- * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
-- * guarantees that no resets are in progress. After we set CF,
-- * a short delay lets the hardware catch up; new resets shouldn't
-- * be started before the port switching actions could complete.
-- */
-- down_write(&ehci_cf_port_reset_rwsem);
-- fotg210->rh_state = FOTG210_RH_RUNNING;
-- /* unblock posted writes */
-- fotg210_readl(fotg210, &fotg210->regs->command);
-- usleep_range(5000, 10000);
-- up_write(&ehci_cf_port_reset_rwsem);
-- fotg210->last_periodic_enable = ktime_get_real();
--
-- temp = HC_VERSION(fotg210,
-- fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
-- fotg210_info(fotg210,
-- "USB %x.%x started, EHCI %x.%02x\n",
-- ((fotg210->sbrn & 0xf0) >> 4), (fotg210->sbrn & 0x0f),
-- temp >> 8, temp & 0xff);
--
-- fotg210_writel(fotg210, INTR_MASK,
-- &fotg210->regs->intr_enable); /* Turn On Interrupts */
--
-- /* GRR this is run-once init(), being done every time the HC starts.
-- * So long as they're part of class devices, we can't do it init()
-- * since the class device isn't created that early.
-- */
-- create_debug_files(fotg210);
-- create_sysfs_files(fotg210);
--
-- return 0;
--}
--
--static int fotg210_setup(struct usb_hcd *hcd)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- int retval;
--
-- fotg210->regs = (void __iomem *)fotg210->caps +
-- HC_LENGTH(fotg210,
-- fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
-- dbg_hcs_params(fotg210, "reset");
-- dbg_hcc_params(fotg210, "reset");
--
-- /* cache this readonly data; minimize chip reads */
-- fotg210->hcs_params = fotg210_readl(fotg210,
-- &fotg210->caps->hcs_params);
--
-- fotg210->sbrn = HCD_USB2;
--
-- /* data structure init */
-- retval = hcd_fotg210_init(hcd);
-- if (retval)
-- return retval;
--
-- retval = fotg210_halt(fotg210);
-- if (retval)
-- return retval;
--
-- fotg210_reset(fotg210);
--
-- return 0;
--}
--
--static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- u32 status, masked_status, pcd_status = 0, cmd;
-- int bh;
--
-- spin_lock(&fotg210->lock);
--
-- status = fotg210_readl(fotg210, &fotg210->regs->status);
--
-- /* e.g. cardbus physical eject */
-- if (status == ~(u32) 0) {
-- fotg210_dbg(fotg210, "device removed\n");
-- goto dead;
-- }
--
-- /*
-- * We don't use STS_FLR, but some controllers don't like it to
-- * remain on, so mask it out along with the other status bits.
-- */
-- masked_status = status & (INTR_MASK | STS_FLR);
--
-- /* Shared IRQ? */
-- if (!masked_status ||
-- unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
-- spin_unlock(&fotg210->lock);
-- return IRQ_NONE;
-- }
--
-- /* clear (just) interrupts */
-- fotg210_writel(fotg210, masked_status, &fotg210->regs->status);
-- cmd = fotg210_readl(fotg210, &fotg210->regs->command);
-- bh = 0;
--
-- /* unrequested/ignored: Frame List Rollover */
-- dbg_status(fotg210, "irq", status);
--
-- /* INT, ERR, and IAA interrupt rates can be throttled */
--
-- /* normal [4.15.1.2] or error [4.15.1.1] completion */
-- if (likely((status & (STS_INT|STS_ERR)) != 0)) {
-- if (likely((status & STS_ERR) == 0))
-- INCR(fotg210->stats.normal);
-- else
-- INCR(fotg210->stats.error);
-- bh = 1;
-- }
--
-- /* complete the unlinking of some qh [4.15.2.3] */
-- if (status & STS_IAA) {
--
-- /* Turn off the IAA watchdog */
-- fotg210->enabled_hrtimer_events &=
-- ~BIT(FOTG210_HRTIMER_IAA_WATCHDOG);
--
-- /*
-- * Mild optimization: Allow another IAAD to reset the
-- * hrtimer, if one occurs before the next expiration.
-- * In theory we could always cancel the hrtimer, but
-- * tests show that about half the time it will be reset
-- * for some other event anyway.
-- */
-- if (fotg210->next_hrtimer_event == FOTG210_HRTIMER_IAA_WATCHDOG)
-- ++fotg210->next_hrtimer_event;
--
-- /* guard against (alleged) silicon errata */
-- if (cmd & CMD_IAAD)
-- fotg210_dbg(fotg210, "IAA with IAAD still set?\n");
-- if (fotg210->async_iaa) {
-- INCR(fotg210->stats.iaa);
-- end_unlink_async(fotg210);
-- } else
-- fotg210_dbg(fotg210, "IAA with nothing unlinked?\n");
-- }
--
-- /* remote wakeup [4.3.1] */
-- if (status & STS_PCD) {
-- int pstatus;
-- u32 __iomem *status_reg = &fotg210->regs->port_status;
--
-- /* kick root hub later */
-- pcd_status = status;
--
-- /* resume root hub? */
-- if (fotg210->rh_state == FOTG210_RH_SUSPENDED)
-- usb_hcd_resume_root_hub(hcd);
--
-- pstatus = fotg210_readl(fotg210, status_reg);
--
-- if (test_bit(0, &fotg210->suspended_ports) &&
-- ((pstatus & PORT_RESUME) ||
-- !(pstatus & PORT_SUSPEND)) &&
-- (pstatus & PORT_PE) &&
-- fotg210->reset_done[0] == 0) {
--
-- /* start 20 msec resume signaling from this port,
-- * and make hub_wq collect PORT_STAT_C_SUSPEND to
-- * stop that signaling. Use 5 ms extra for safety,
-- * like usb_port_resume() does.
-- */
-- fotg210->reset_done[0] = jiffies + msecs_to_jiffies(25);
-- set_bit(0, &fotg210->resuming_ports);
-- fotg210_dbg(fotg210, "port 1 remote wakeup\n");
-- mod_timer(&hcd->rh_timer, fotg210->reset_done[0]);
-- }
-- }
--
-- /* PCI errors [4.15.2.4] */
-- if (unlikely((status & STS_FATAL) != 0)) {
-- fotg210_err(fotg210, "fatal error\n");
-- dbg_cmd(fotg210, "fatal", cmd);
-- dbg_status(fotg210, "fatal", status);
--dead:
-- usb_hc_died(hcd);
--
-- /* Don't let the controller do anything more */
-- fotg210->shutdown = true;
-- fotg210->rh_state = FOTG210_RH_STOPPING;
-- fotg210->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
-- fotg210_writel(fotg210, fotg210->command,
-- &fotg210->regs->command);
-- fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-- fotg210_handle_controller_death(fotg210);
--
-- /* Handle completions when the controller stops */
-- bh = 0;
-- }
--
-- if (bh)
-- fotg210_work(fotg210);
-- spin_unlock(&fotg210->lock);
-- if (pcd_status)
-- usb_hcd_poll_rh_status(hcd);
-- return IRQ_HANDLED;
--}
--
--/* non-error returns are a promise to giveback() the urb later
-- * we drop ownership so next owner (or urb unlink) can get it
-- *
-- * urb + dev is in hcd.self.controller.urb_list
-- * we're queueing TDs onto software and hardware lists
-- *
-- * hcd-specific init for hcpriv hasn't been done yet
-- *
-- * NOTE: control, bulk, and interrupt share the same code to append TDs
-- * to a (possibly active) QH, and the same QH scanning code.
-- */
--static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
-- gfp_t mem_flags)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- struct list_head qtd_list;
--
-- INIT_LIST_HEAD(&qtd_list);
--
-- switch (usb_pipetype(urb->pipe)) {
-- case PIPE_CONTROL:
-- /* qh_completions() code doesn't handle all the fault cases
-- * in multi-TD control transfers. Even 1KB is rare anyway.
-- */
-- if (urb->transfer_buffer_length > (16 * 1024))
-- return -EMSGSIZE;
-- fallthrough;
-- /* case PIPE_BULK: */
-- default:
-- if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
-- return -ENOMEM;
-- return submit_async(fotg210, urb, &qtd_list, mem_flags);
--
-- case PIPE_INTERRUPT:
-- if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
-- return -ENOMEM;
-- return intr_submit(fotg210, urb, &qtd_list, mem_flags);
--
-- case PIPE_ISOCHRONOUS:
-- return itd_submit(fotg210, urb, mem_flags);
-- }
--}
--
--/* remove from hardware lists
-- * completions normally happen asynchronously
-- */
--
--static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- struct fotg210_qh *qh;
-- unsigned long flags;
-- int rc;
--
-- spin_lock_irqsave(&fotg210->lock, flags);
-- rc = usb_hcd_check_unlink_urb(hcd, urb, status);
-- if (rc)
-- goto done;
--
-- switch (usb_pipetype(urb->pipe)) {
-- /* case PIPE_CONTROL: */
-- /* case PIPE_BULK:*/
-- default:
-- qh = (struct fotg210_qh *) urb->hcpriv;
-- if (!qh)
-- break;
-- switch (qh->qh_state) {
-- case QH_STATE_LINKED:
-- case QH_STATE_COMPLETING:
-- start_unlink_async(fotg210, qh);
-- break;
-- case QH_STATE_UNLINK:
-- case QH_STATE_UNLINK_WAIT:
-- /* already started */
-- break;
-- case QH_STATE_IDLE:
-- /* QH might be waiting for a Clear-TT-Buffer */
-- qh_completions(fotg210, qh);
-- break;
-- }
-- break;
--
-- case PIPE_INTERRUPT:
-- qh = (struct fotg210_qh *) urb->hcpriv;
-- if (!qh)
-- break;
-- switch (qh->qh_state) {
-- case QH_STATE_LINKED:
-- case QH_STATE_COMPLETING:
-- start_unlink_intr(fotg210, qh);
-- break;
-- case QH_STATE_IDLE:
-- qh_completions(fotg210, qh);
-- break;
-- default:
-- fotg210_dbg(fotg210, "bogus qh %p state %d\n",
-- qh, qh->qh_state);
-- goto done;
-- }
-- break;
--
-- case PIPE_ISOCHRONOUS:
-- /* itd... */
--
-- /* wait till next completion, do it then. */
-- /* completion irqs can wait up to 1024 msec, */
-- break;
-- }
--done:
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- return rc;
--}
--
--/* bulk qh holds the data toggle */
--
--static void fotg210_endpoint_disable(struct usb_hcd *hcd,
-- struct usb_host_endpoint *ep)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- unsigned long flags;
-- struct fotg210_qh *qh, *tmp;
--
-- /* ASSERT: any requests/urbs are being unlinked */
-- /* ASSERT: nobody can be submitting urbs for this any more */
--
--rescan:
-- spin_lock_irqsave(&fotg210->lock, flags);
-- qh = ep->hcpriv;
-- if (!qh)
-- goto done;
--
-- /* endpoints can be iso streams. for now, we don't
-- * accelerate iso completions ... so spin a while.
-- */
-- if (qh->hw == NULL) {
-- struct fotg210_iso_stream *stream = ep->hcpriv;
--
-- if (!list_empty(&stream->td_list))
-- goto idle_timeout;
--
-- /* BUG_ON(!list_empty(&stream->free_list)); */
-- kfree(stream);
-- goto done;
-- }
--
-- if (fotg210->rh_state < FOTG210_RH_RUNNING)
-- qh->qh_state = QH_STATE_IDLE;
-- switch (qh->qh_state) {
-- case QH_STATE_LINKED:
-- case QH_STATE_COMPLETING:
-- for (tmp = fotg210->async->qh_next.qh;
-- tmp && tmp != qh;
-- tmp = tmp->qh_next.qh)
-- continue;
-- /* periodic qh self-unlinks on empty, and a COMPLETING qh
-- * may already be unlinked.
-- */
-- if (tmp)
-- start_unlink_async(fotg210, qh);
-- fallthrough;
-- case QH_STATE_UNLINK: /* wait for hw to finish? */
-- case QH_STATE_UNLINK_WAIT:
--idle_timeout:
-- spin_unlock_irqrestore(&fotg210->lock, flags);
-- schedule_timeout_uninterruptible(1);
-- goto rescan;
-- case QH_STATE_IDLE: /* fully unlinked */
-- if (qh->clearing_tt)
-- goto idle_timeout;
-- if (list_empty(&qh->qtd_list)) {
-- qh_destroy(fotg210, qh);
-- break;
-- }
-- fallthrough;
-- default:
-- /* caller was supposed to have unlinked any requests;
-- * that's not our job. just leak this memory.
-- */
-- fotg210_err(fotg210, "qh %p (#%02x) state %d%s\n",
-- qh, ep->desc.bEndpointAddress, qh->qh_state,
-- list_empty(&qh->qtd_list) ? "" : "(has tds)");
-- break;
-- }
--done:
-- ep->hcpriv = NULL;
-- spin_unlock_irqrestore(&fotg210->lock, flags);
--}
--
--static void fotg210_endpoint_reset(struct usb_hcd *hcd,
-- struct usb_host_endpoint *ep)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-- struct fotg210_qh *qh;
-- int eptype = usb_endpoint_type(&ep->desc);
-- int epnum = usb_endpoint_num(&ep->desc);
-- int is_out = usb_endpoint_dir_out(&ep->desc);
-- unsigned long flags;
--
-- if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
-- return;
--
-- spin_lock_irqsave(&fotg210->lock, flags);
-- qh = ep->hcpriv;
--
-- /* For Bulk and Interrupt endpoints we maintain the toggle state
-- * in the hardware; the toggle bits in udev aren't used at all.
-- * When an endpoint is reset by usb_clear_halt() we must reset
-- * the toggle bit in the QH.
-- */
-- if (qh) {
-- usb_settoggle(qh->dev, epnum, is_out, 0);
-- if (!list_empty(&qh->qtd_list)) {
-- WARN_ONCE(1, "clear_halt for a busy endpoint\n");
-- } else if (qh->qh_state == QH_STATE_LINKED ||
-- qh->qh_state == QH_STATE_COMPLETING) {
--
-- /* The toggle value in the QH can't be updated
-- * while the QH is active. Unlink it now;
-- * re-linking will call qh_refresh().
-- */
-- if (eptype == USB_ENDPOINT_XFER_BULK)
-- start_unlink_async(fotg210, qh);
-- else
-- start_unlink_intr(fotg210, qh);
-- }
-- }
-- spin_unlock_irqrestore(&fotg210->lock, flags);
--}
--
--static int fotg210_get_frame(struct usb_hcd *hcd)
--{
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
--
-- return (fotg210_read_frame_index(fotg210) >> 3) %
-- fotg210->periodic_size;
--}
--
--/* The EHCI in ChipIdea HDRC cannot be a separate module or device,
-- * because its registers (and irq) are shared between host/gadget/otg
-- * functions and in order to facilitate role switching we cannot
-- * give the fotg210 driver exclusive access to those.
-- */
--MODULE_DESCRIPTION(DRIVER_DESC);
--MODULE_AUTHOR(DRIVER_AUTHOR);
--MODULE_LICENSE("GPL");
--
--static const struct hc_driver fotg210_fotg210_hc_driver = {
-- .description = hcd_name,
-- .product_desc = "Faraday USB2.0 Host Controller",
-- .hcd_priv_size = sizeof(struct fotg210_hcd),
--
-- /*
-- * generic hardware linkage
-- */
-- .irq = fotg210_irq,
-- .flags = HCD_MEMORY | HCD_DMA | HCD_USB2,
--
-- /*
-- * basic lifecycle operations
-- */
-- .reset = hcd_fotg210_init,
-- .start = fotg210_run,
-- .stop = fotg210_stop,
-- .shutdown = fotg210_shutdown,
--
-- /*
-- * managing i/o requests and associated device resources
-- */
-- .urb_enqueue = fotg210_urb_enqueue,
-- .urb_dequeue = fotg210_urb_dequeue,
-- .endpoint_disable = fotg210_endpoint_disable,
-- .endpoint_reset = fotg210_endpoint_reset,
--
-- /*
-- * scheduling support
-- */
-- .get_frame_number = fotg210_get_frame,
--
-- /*
-- * root hub support
-- */
-- .hub_status_data = fotg210_hub_status_data,
-- .hub_control = fotg210_hub_control,
-- .bus_suspend = fotg210_bus_suspend,
-- .bus_resume = fotg210_bus_resume,
--
-- .relinquish_port = fotg210_relinquish_port,
-- .port_handed_over = fotg210_port_handed_over,
--
-- .clear_tt_buffer_complete = fotg210_clear_tt_buffer_complete,
--};
--
--static void fotg210_init(struct fotg210_hcd *fotg210)
--{
-- u32 value;
--
-- iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
-- &fotg210->regs->gmir);
--
-- value = ioread32(&fotg210->regs->otgcsr);
-- value &= ~OTGCSR_A_BUS_DROP;
-- value |= OTGCSR_A_BUS_REQ;
-- iowrite32(value, &fotg210->regs->otgcsr);
--}
--
--/*
-- * fotg210_hcd_probe - initialize faraday FOTG210 HCDs
-- *
-- * Allocates basic resources for this USB host controller, and
-- * then invokes the start() method for the HCD associated with it
-- * through the hotplug entry's driver_data.
-- */
--static int fotg210_hcd_probe(struct platform_device *pdev)
--{
-- struct device *dev = &pdev->dev;
-- struct usb_hcd *hcd;
-- struct resource *res;
-- int irq;
-- int retval;
-- struct fotg210_hcd *fotg210;
--
-- if (usb_disabled())
-- return -ENODEV;
--
-- pdev->dev.power.power_state = PMSG_ON;
--
-- irq = platform_get_irq(pdev, 0);
-- if (irq < 0)
-- return irq;
--
-- hcd = usb_create_hcd(&fotg210_fotg210_hc_driver, dev,
-- dev_name(dev));
-- if (!hcd) {
-- dev_err(dev, "failed to create hcd\n");
-- retval = -ENOMEM;
-- goto fail_create_hcd;
-- }
--
-- hcd->has_tt = 1;
--
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- hcd->regs = devm_ioremap_resource(&pdev->dev, res);
-- if (IS_ERR(hcd->regs)) {
-- retval = PTR_ERR(hcd->regs);
-- goto failed_put_hcd;
-- }
--
-- hcd->rsrc_start = res->start;
-- hcd->rsrc_len = resource_size(res);
--
-- fotg210 = hcd_to_fotg210(hcd);
--
-- fotg210->caps = hcd->regs;
--
-- /* It's OK not to supply this clock */
-- fotg210->pclk = clk_get(dev, "PCLK");
-- if (!IS_ERR(fotg210->pclk)) {
-- retval = clk_prepare_enable(fotg210->pclk);
-- if (retval) {
-- dev_err(dev, "failed to enable PCLK\n");
-- goto failed_put_hcd;
-- }
-- } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
-- /*
-- * Percolate deferrals, for anything else,
-- * just live without the clocking.
-- */
-- retval = PTR_ERR(fotg210->pclk);
-- goto failed_dis_clk;
-- }
--
-- retval = fotg210_setup(hcd);
-- if (retval)
-- goto failed_dis_clk;
--
-- fotg210_init(fotg210);
--
-- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
-- if (retval) {
-- dev_err(dev, "failed to add hcd with err %d\n", retval);
-- goto failed_dis_clk;
-- }
-- device_wakeup_enable(hcd->self.controller);
-- platform_set_drvdata(pdev, hcd);
--
-- return retval;
--
--failed_dis_clk:
-- if (!IS_ERR(fotg210->pclk)) {
-- clk_disable_unprepare(fotg210->pclk);
-- clk_put(fotg210->pclk);
-- }
--failed_put_hcd:
-- usb_put_hcd(hcd);
--fail_create_hcd:
-- dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
-- return retval;
--}
--
--/*
-- * fotg210_hcd_remove - shutdown processing for EHCI HCDs
-- * @dev: USB Host Controller being removed
-- *
-- */
--static int fotg210_hcd_remove(struct platform_device *pdev)
--{
-- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
--
-- if (!IS_ERR(fotg210->pclk)) {
-- clk_disable_unprepare(fotg210->pclk);
-- clk_put(fotg210->pclk);
-- }
--
-- usb_remove_hcd(hcd);
-- usb_put_hcd(hcd);
--
-- return 0;
--}
--
--#ifdef CONFIG_OF
--static const struct of_device_id fotg210_of_match[] = {
-- { .compatible = "faraday,fotg210" },
-- {},
--};
--MODULE_DEVICE_TABLE(of, fotg210_of_match);
--#endif
--
--static struct platform_driver fotg210_hcd_driver = {
-- .driver = {
-- .name = "fotg210-hcd",
-- .of_match_table = of_match_ptr(fotg210_of_match),
-- },
-- .probe = fotg210_hcd_probe,
-- .remove = fotg210_hcd_remove,
--};
--
--static int __init fotg210_hcd_init(void)
--{
-- int retval = 0;
--
-- if (usb_disabled())
-- return -ENODEV;
--
-- set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-- if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
-- test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-- pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
--
-- pr_debug("%s: block sizes: qh %zd qtd %zd itd %zd\n",
-- hcd_name, sizeof(struct fotg210_qh),
-- sizeof(struct fotg210_qtd),
-- sizeof(struct fotg210_itd));
--
-- fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
--
-- retval = platform_driver_register(&fotg210_hcd_driver);
-- if (retval < 0)
-- goto clean;
-- return retval;
--
--clean:
-- debugfs_remove(fotg210_debug_root);
-- fotg210_debug_root = NULL;
--
-- clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-- return retval;
--}
--module_init(fotg210_hcd_init);
--
--static void __exit fotg210_hcd_cleanup(void)
--{
-- platform_driver_unregister(&fotg210_hcd_driver);
-- debugfs_remove(fotg210_debug_root);
-- clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
--}
--module_exit(fotg210_hcd_cleanup);
---- /dev/null
-+++ b/drivers/usb/fotg210/fotg210-hcd.c
-@@ -0,0 +1,5727 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/* Faraday FOTG210 EHCI-like driver
-+ *
-+ * Copyright (c) 2013 Faraday Technology Corporation
-+ *
-+ * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com>
-+ * Feng-Hsin Chiang <john453@faraday-tech.com>
-+ * Po-Yu Chuang <ratbert.chuang@gmail.com>
-+ *
-+ * Most of code borrowed from the Linux-3.7 EHCI driver
-+ */
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/device.h>
-+#include <linux/dmapool.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/ioport.h>
-+#include <linux/sched.h>
-+#include <linux/vmalloc.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/hrtimer.h>
-+#include <linux/list.h>
-+#include <linux/interrupt.h>
-+#include <linux/usb.h>
-+#include <linux/usb/hcd.h>
-+#include <linux/moduleparam.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/debugfs.h>
-+#include <linux/slab.h>
-+#include <linux/uaccess.h>
-+#include <linux/platform_device.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/clk.h>
-+
-+#include <asm/byteorder.h>
-+#include <asm/irq.h>
-+#include <asm/unaligned.h>
-+
-+#define DRIVER_AUTHOR "Yuan-Hsin Chen"
-+#define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
-+static const char hcd_name[] = "fotg210_hcd";
-+
-+#undef FOTG210_URB_TRACE
-+#define FOTG210_STATS
-+
-+/* magic numbers that can affect system performance */
-+#define FOTG210_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */
-+#define FOTG210_TUNE_RL_HS 4 /* nak throttle; see 4.9 */
-+#define FOTG210_TUNE_RL_TT 0
-+#define FOTG210_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */
-+#define FOTG210_TUNE_MULT_TT 1
-+
-+/* Some drivers think it's safe to schedule isochronous transfers more than 256
-+ * ms into the future (partly as a result of an old bug in the scheduling
-+ * code). In an attempt to avoid trouble, we will use a minimum scheduling
-+ * length of 512 frames instead of 256.
-+ */
-+#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
-+
-+/* Initial IRQ latency: faster than hw default */
-+static int log2_irq_thresh; /* 0 to 6 */
-+module_param(log2_irq_thresh, int, S_IRUGO);
-+MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
-+
-+/* initial park setting: slower than hw default */
-+static unsigned park;
-+module_param(park, uint, S_IRUGO);
-+MODULE_PARM_DESC(park, "park setting; 1-3 back-to-back async packets");
-+
-+/* for link power management(LPM) feature */
-+static unsigned int hird;
-+module_param(hird, int, S_IRUGO);
-+MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
-+
-+#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
-+
-+#include "fotg210-hcd.h"
-+
-+#define fotg210_dbg(fotg210, fmt, args...) \
-+ dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-+#define fotg210_err(fotg210, fmt, args...) \
-+ dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-+#define fotg210_info(fotg210, fmt, args...) \
-+ dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-+#define fotg210_warn(fotg210, fmt, args...) \
-+ dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-+
-+/* check the values in the HCSPARAMS register (host controller _Structural_
-+ * parameters) see EHCI spec, Table 2-4 for each value
-+ */
-+static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
-+{
-+ u32 params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
-+
-+ fotg210_dbg(fotg210, "%s hcs_params 0x%x ports=%d\n", label, params,
-+ HCS_N_PORTS(params));
-+}
-+
-+/* check the values in the HCCPARAMS register (host controller _Capability_
-+ * parameters) see EHCI Spec, Table 2-5 for each value
-+ */
-+static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
-+{
-+ u32 params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
-+
-+ fotg210_dbg(fotg210, "%s hcc_params %04x uframes %s%s\n", label,
-+ params,
-+ HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-+ HCC_CANPARK(params) ? " park" : "");
-+}
-+
-+static void __maybe_unused
-+dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
-+{
-+ fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-+ hc32_to_cpup(fotg210, &qtd->hw_next),
-+ hc32_to_cpup(fotg210, &qtd->hw_alt_next),
-+ hc32_to_cpup(fotg210, &qtd->hw_token),
-+ hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
-+ if (qtd->hw_buf[1])
-+ fotg210_dbg(fotg210, " p1=%08x p2=%08x p3=%08x p4=%08x\n",
-+ hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
-+ hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
-+ hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
-+ hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
-+}
-+
-+static void __maybe_unused
-+dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-+{
-+ struct fotg210_qh_hw *hw = qh->hw;
-+
-+ fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
-+ hw->hw_next, hw->hw_info1, hw->hw_info2,
-+ hw->hw_current);
-+
-+ dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
-+}
-+
-+static void __maybe_unused
-+dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
-+{
-+ fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n", label,
-+ itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
-+ itd->urb);
-+
-+ fotg210_dbg(fotg210,
-+ " trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-+ hc32_to_cpu(fotg210, itd->hw_transaction[0]),
-+ hc32_to_cpu(fotg210, itd->hw_transaction[1]),
-+ hc32_to_cpu(fotg210, itd->hw_transaction[2]),
-+ hc32_to_cpu(fotg210, itd->hw_transaction[3]),
-+ hc32_to_cpu(fotg210, itd->hw_transaction[4]),
-+ hc32_to_cpu(fotg210, itd->hw_transaction[5]),
-+ hc32_to_cpu(fotg210, itd->hw_transaction[6]),
-+ hc32_to_cpu(fotg210, itd->hw_transaction[7]));
-+
-+ fotg210_dbg(fotg210,
-+ " buf: %08x %08x %08x %08x %08x %08x %08x\n",
-+ hc32_to_cpu(fotg210, itd->hw_bufp[0]),
-+ hc32_to_cpu(fotg210, itd->hw_bufp[1]),
-+ hc32_to_cpu(fotg210, itd->hw_bufp[2]),
-+ hc32_to_cpu(fotg210, itd->hw_bufp[3]),
-+ hc32_to_cpu(fotg210, itd->hw_bufp[4]),
-+ hc32_to_cpu(fotg210, itd->hw_bufp[5]),
-+ hc32_to_cpu(fotg210, itd->hw_bufp[6]));
-+
-+ fotg210_dbg(fotg210, " index: %d %d %d %d %d %d %d %d\n",
-+ itd->index[0], itd->index[1], itd->index[2],
-+ itd->index[3], itd->index[4], itd->index[5],
-+ itd->index[6], itd->index[7]);
-+}
-+
-+static int __maybe_unused
-+dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
-+{
-+ return scnprintf(buf, len, "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-+ label, label[0] ? " " : "", status,
-+ (status & STS_ASS) ? " Async" : "",
-+ (status & STS_PSS) ? " Periodic" : "",
-+ (status & STS_RECL) ? " Recl" : "",
-+ (status & STS_HALT) ? " Halt" : "",
-+ (status & STS_IAA) ? " IAA" : "",
-+ (status & STS_FATAL) ? " FATAL" : "",
-+ (status & STS_FLR) ? " FLR" : "",
-+ (status & STS_PCD) ? " PCD" : "",
-+ (status & STS_ERR) ? " ERR" : "",
-+ (status & STS_INT) ? " INT" : "");
-+}
-+
-+static int __maybe_unused
-+dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
-+{
-+ return scnprintf(buf, len, "%s%sintrenable %02x%s%s%s%s%s%s",
-+ label, label[0] ? " " : "", enable,
-+ (enable & STS_IAA) ? " IAA" : "",
-+ (enable & STS_FATAL) ? " FATAL" : "",
-+ (enable & STS_FLR) ? " FLR" : "",
-+ (enable & STS_PCD) ? " PCD" : "",
-+ (enable & STS_ERR) ? " ERR" : "",
-+ (enable & STS_INT) ? " INT" : "");
-+}
-+
-+static const char *const fls_strings[] = { "1024", "512", "256", "??" };
-+
-+static int dbg_command_buf(char *buf, unsigned len, const char *label,
-+ u32 command)
-+{
-+ return scnprintf(buf, len,
-+ "%s%scommand %07x %s=%d ithresh=%d%s%s%s period=%s%s %s",
-+ label, label[0] ? " " : "", command,
-+ (command & CMD_PARK) ? " park" : "(park)",
-+ CMD_PARK_CNT(command),
-+ (command >> 16) & 0x3f,
-+ (command & CMD_IAAD) ? " IAAD" : "",
-+ (command & CMD_ASE) ? " Async" : "",
-+ (command & CMD_PSE) ? " Periodic" : "",
-+ fls_strings[(command >> 2) & 0x3],
-+ (command & CMD_RESET) ? " Reset" : "",
-+ (command & CMD_RUN) ? "RUN" : "HALT");
-+}
-+
-+static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
-+ u32 status)
-+{
-+ char *sig;
-+
-+ /* signaling state */
-+ switch (status & (3 << 10)) {
-+ case 0 << 10:
-+ sig = "se0";
-+ break;
-+ case 1 << 10:
-+ sig = "k";
-+ break; /* low speed */
-+ case 2 << 10:
-+ sig = "j";
-+ break;
-+ default:
-+ sig = "?";
-+ break;
-+ }
-+
-+ scnprintf(buf, len, "%s%sport:%d status %06x %d sig=%s%s%s%s%s%s%s%s",
-+ label, label[0] ? " " : "", port, status,
-+ status >> 25, /*device address */
-+ sig,
-+ (status & PORT_RESET) ? " RESET" : "",
-+ (status & PORT_SUSPEND) ? " SUSPEND" : "",
-+ (status & PORT_RESUME) ? " RESUME" : "",
-+ (status & PORT_PEC) ? " PEC" : "",
-+ (status & PORT_PE) ? " PE" : "",
-+ (status & PORT_CSC) ? " CSC" : "",
-+ (status & PORT_CONNECT) ? " CONNECT" : "");
-+
-+ return buf;
-+}
-+
-+/* functions have the "wrong" filename when they're output... */
-+#define dbg_status(fotg210, label, status) { \
-+ char _buf[80]; \
-+ dbg_status_buf(_buf, sizeof(_buf), label, status); \
-+ fotg210_dbg(fotg210, "%s\n", _buf); \
-+}
-+
-+#define dbg_cmd(fotg210, label, command) { \
-+ char _buf[80]; \
-+ dbg_command_buf(_buf, sizeof(_buf), label, command); \
-+ fotg210_dbg(fotg210, "%s\n", _buf); \
-+}
-+
-+#define dbg_port(fotg210, label, port, status) { \
-+ char _buf[80]; \
-+ fotg210_dbg(fotg210, "%s\n", \
-+ dbg_port_buf(_buf, sizeof(_buf), label, port, status));\
-+}
-+
-+/* troubleshooting help: expose state in debugfs */
-+static int debug_async_open(struct inode *, struct file *);
-+static int debug_periodic_open(struct inode *, struct file *);
-+static int debug_registers_open(struct inode *, struct file *);
-+static int debug_async_open(struct inode *, struct file *);
-+
-+static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
-+static int debug_close(struct inode *, struct file *);
-+
-+static const struct file_operations debug_async_fops = {
-+ .owner = THIS_MODULE,
-+ .open = debug_async_open,
-+ .read = debug_output,
-+ .release = debug_close,
-+ .llseek = default_llseek,
-+};
-+static const struct file_operations debug_periodic_fops = {
-+ .owner = THIS_MODULE,
-+ .open = debug_periodic_open,
-+ .read = debug_output,
-+ .release = debug_close,
-+ .llseek = default_llseek,
-+};
-+static const struct file_operations debug_registers_fops = {
-+ .owner = THIS_MODULE,
-+ .open = debug_registers_open,
-+ .read = debug_output,
-+ .release = debug_close,
-+ .llseek = default_llseek,
-+};
-+
-+static struct dentry *fotg210_debug_root;
-+
-+struct debug_buffer {
-+ ssize_t (*fill_func)(struct debug_buffer *); /* fill method */
-+ struct usb_bus *bus;
-+ struct mutex mutex; /* protect filling of buffer */
-+ size_t count; /* number of characters filled into buffer */
-+ char *output_buf;
-+ size_t alloc_size;
-+};
-+
-+static inline char speed_char(u32 scratch)
-+{
-+ switch (scratch & (3 << 12)) {
-+ case QH_FULL_SPEED:
-+ return 'f';
-+
-+ case QH_LOW_SPEED:
-+ return 'l';
-+
-+ case QH_HIGH_SPEED:
-+ return 'h';
-+
-+ default:
-+ return '?';
-+ }
-+}
-+
-+static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
-+{
-+ __u32 v = hc32_to_cpu(fotg210, token);
-+
-+ if (v & QTD_STS_ACTIVE)
-+ return '*';
-+ if (v & QTD_STS_HALT)
-+ return '-';
-+ if (!IS_SHORT_READ(v))
-+ return ' ';
-+ /* tries to advance through hw_alt_next */
-+ return '/';
-+}
-+
-+static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
-+ char **nextp, unsigned *sizep)
-+{
-+ u32 scratch;
-+ u32 hw_curr;
-+ struct fotg210_qtd *td;
-+ unsigned temp;
-+ unsigned size = *sizep;
-+ char *next = *nextp;
-+ char mark;
-+ __le32 list_end = FOTG210_LIST_END(fotg210);
-+ struct fotg210_qh_hw *hw = qh->hw;
-+
-+ if (hw->hw_qtd_next == list_end) /* NEC does this */
-+ mark = '@';
-+ else
-+ mark = token_mark(fotg210, hw->hw_token);
-+ if (mark == '/') { /* qh_alt_next controls qh advance? */
-+ if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
-+ fotg210->async->hw->hw_alt_next)
-+ mark = '#'; /* blocked */
-+ else if (hw->hw_alt_next == list_end)
-+ mark = '.'; /* use hw_qtd_next */
-+ /* else alt_next points to some other qtd */
-+ }
-+ scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
-+ hw_curr = (mark == '*') ? hc32_to_cpup(fotg210, &hw->hw_current) : 0;
-+ temp = scnprintf(next, size,
-+ "qh/%p dev%d %cs ep%d %08x %08x(%08x%c %s nak%d)",
-+ qh, scratch & 0x007f,
-+ speed_char(scratch),
-+ (scratch >> 8) & 0x000f,
-+ scratch, hc32_to_cpup(fotg210, &hw->hw_info2),
-+ hc32_to_cpup(fotg210, &hw->hw_token), mark,
-+ (cpu_to_hc32(fotg210, QTD_TOGGLE) & hw->hw_token)
-+ ? "data1" : "data0",
-+ (hc32_to_cpup(fotg210, &hw->hw_alt_next) >> 1) & 0x0f);
-+ size -= temp;
-+ next += temp;
-+
-+ /* hc may be modifying the list as we read it ... */
-+ list_for_each_entry(td, &qh->qtd_list, qtd_list) {
-+ scratch = hc32_to_cpup(fotg210, &td->hw_token);
-+ mark = ' ';
-+ if (hw_curr == td->qtd_dma)
-+ mark = '*';
-+ else if (hw->hw_qtd_next == cpu_to_hc32(fotg210, td->qtd_dma))
-+ mark = '+';
-+ else if (QTD_LENGTH(scratch)) {
-+ if (td->hw_alt_next == fotg210->async->hw->hw_alt_next)
-+ mark = '#';
-+ else if (td->hw_alt_next != list_end)
-+ mark = '/';
-+ }
-+ temp = snprintf(next, size,
-+ "\n\t%p%c%s len=%d %08x urb %p",
-+ td, mark, ({ char *tmp;
-+ switch ((scratch>>8)&0x03) {
-+ case 0:
-+ tmp = "out";
-+ break;
-+ case 1:
-+ tmp = "in";
-+ break;
-+ case 2:
-+ tmp = "setup";
-+ break;
-+ default:
-+ tmp = "?";
-+ break;
-+ } tmp; }),
-+ (scratch >> 16) & 0x7fff,
-+ scratch,
-+ td->urb);
-+ if (size < temp)
-+ temp = size;
-+ size -= temp;
-+ next += temp;
-+ if (temp == size)
-+ goto done;
-+ }
-+
-+ temp = snprintf(next, size, "\n");
-+ if (size < temp)
-+ temp = size;
-+
-+ size -= temp;
-+ next += temp;
-+
-+done:
-+ *sizep = size;
-+ *nextp = next;
-+}
-+
-+static ssize_t fill_async_buffer(struct debug_buffer *buf)
-+{
-+ struct usb_hcd *hcd;
-+ struct fotg210_hcd *fotg210;
-+ unsigned long flags;
-+ unsigned temp, size;
-+ char *next;
-+ struct fotg210_qh *qh;
-+
-+ hcd = bus_to_hcd(buf->bus);
-+ fotg210 = hcd_to_fotg210(hcd);
-+ next = buf->output_buf;
-+ size = buf->alloc_size;
-+
-+ *next = 0;
-+
-+ /* dumps a snapshot of the async schedule.
-+ * usually empty except for long-term bulk reads, or head.
-+ * one QH per line, and TDs we know about
-+ */
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ for (qh = fotg210->async->qh_next.qh; size > 0 && qh;
-+ qh = qh->qh_next.qh)
-+ qh_lines(fotg210, qh, &next, &size);
-+ if (fotg210->async_unlink && size > 0) {
-+ temp = scnprintf(next, size, "\nunlink =\n");
-+ size -= temp;
-+ next += temp;
-+
-+ for (qh = fotg210->async_unlink; size > 0 && qh;
-+ qh = qh->unlink_next)
-+ qh_lines(fotg210, qh, &next, &size);
-+ }
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+
-+ return strlen(buf->output_buf);
-+}
-+
-+/* count tds, get ep direction */
-+static unsigned output_buf_tds_dir(char *buf, struct fotg210_hcd *fotg210,
-+ struct fotg210_qh_hw *hw, struct fotg210_qh *qh, unsigned size)
-+{
-+ u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
-+ struct fotg210_qtd *qtd;
-+ char *type = "";
-+ unsigned temp = 0;
-+
-+ /* count tds, get ep direction */
-+ list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
-+ temp++;
-+ switch ((hc32_to_cpu(fotg210, qtd->hw_token) >> 8) & 0x03) {
-+ case 0:
-+ type = "out";
-+ continue;
-+ case 1:
-+ type = "in";
-+ continue;
-+ }
-+ }
-+
-+ return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
-+ speed_char(scratch), scratch & 0x007f,
-+ (scratch >> 8) & 0x000f, type, qh->usecs,
-+ qh->c_usecs, temp, (scratch >> 16) & 0x7ff);
-+}
-+
-+#define DBG_SCHED_LIMIT 64
-+static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
-+{
-+ struct usb_hcd *hcd;
-+ struct fotg210_hcd *fotg210;
-+ unsigned long flags;
-+ union fotg210_shadow p, *seen;
-+ unsigned temp, size, seen_count;
-+ char *next;
-+ unsigned i;
-+ __hc32 tag;
-+
-+ seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
-+ if (!seen)
-+ return 0;
-+
-+ seen_count = 0;
-+
-+ hcd = bus_to_hcd(buf->bus);
-+ fotg210 = hcd_to_fotg210(hcd);
-+ next = buf->output_buf;
-+ size = buf->alloc_size;
-+
-+ temp = scnprintf(next, size, "size = %d\n", fotg210->periodic_size);
-+ size -= temp;
-+ next += temp;
-+
-+ /* dump a snapshot of the periodic schedule.
-+ * iso changes, interrupt usually doesn't.
-+ */
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ for (i = 0; i < fotg210->periodic_size; i++) {
-+ p = fotg210->pshadow[i];
-+ if (likely(!p.ptr))
-+ continue;
-+
-+ tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
-+
-+ temp = scnprintf(next, size, "%4d: ", i);
-+ size -= temp;
-+ next += temp;
-+
-+ do {
-+ struct fotg210_qh_hw *hw;
-+
-+ switch (hc32_to_cpu(fotg210, tag)) {
-+ case Q_TYPE_QH:
-+ hw = p.qh->hw;
-+ temp = scnprintf(next, size, " qh%d-%04x/%p",
-+ p.qh->period,
-+ hc32_to_cpup(fotg210,
-+ &hw->hw_info2)
-+ /* uframe masks */
-+ & (QH_CMASK | QH_SMASK),
-+ p.qh);
-+ size -= temp;
-+ next += temp;
-+ /* don't repeat what follows this qh */
-+ for (temp = 0; temp < seen_count; temp++) {
-+ if (seen[temp].ptr != p.ptr)
-+ continue;
-+ if (p.qh->qh_next.ptr) {
-+ temp = scnprintf(next, size,
-+ " ...");
-+ size -= temp;
-+ next += temp;
-+ }
-+ break;
-+ }
-+ /* show more info the first time around */
-+ if (temp == seen_count) {
-+ temp = output_buf_tds_dir(next,
-+ fotg210, hw,
-+ p.qh, size);
-+
-+ if (seen_count < DBG_SCHED_LIMIT)
-+ seen[seen_count++].qh = p.qh;
-+ } else
-+ temp = 0;
-+ tag = Q_NEXT_TYPE(fotg210, hw->hw_next);
-+ p = p.qh->qh_next;
-+ break;
-+ case Q_TYPE_FSTN:
-+ temp = scnprintf(next, size,
-+ " fstn-%8x/%p",
-+ p.fstn->hw_prev, p.fstn);
-+ tag = Q_NEXT_TYPE(fotg210, p.fstn->hw_next);
-+ p = p.fstn->fstn_next;
-+ break;
-+ case Q_TYPE_ITD:
-+ temp = scnprintf(next, size,
-+ " itd/%p", p.itd);
-+ tag = Q_NEXT_TYPE(fotg210, p.itd->hw_next);
-+ p = p.itd->itd_next;
-+ break;
-+ }
-+ size -= temp;
-+ next += temp;
-+ } while (p.ptr);
-+
-+ temp = scnprintf(next, size, "\n");
-+ size -= temp;
-+ next += temp;
-+ }
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ kfree(seen);
-+
-+ return buf->alloc_size - size;
-+}
-+#undef DBG_SCHED_LIMIT
-+
-+static const char *rh_state_string(struct fotg210_hcd *fotg210)
-+{
-+ switch (fotg210->rh_state) {
-+ case FOTG210_RH_HALTED:
-+ return "halted";
-+ case FOTG210_RH_SUSPENDED:
-+ return "suspended";
-+ case FOTG210_RH_RUNNING:
-+ return "running";
-+ case FOTG210_RH_STOPPING:
-+ return "stopping";
-+ }
-+ return "?";
-+}
-+
-+static ssize_t fill_registers_buffer(struct debug_buffer *buf)
-+{
-+ struct usb_hcd *hcd;
-+ struct fotg210_hcd *fotg210;
-+ unsigned long flags;
-+ unsigned temp, size, i;
-+ char *next, scratch[80];
-+ static const char fmt[] = "%*s\n";
-+ static const char label[] = "";
-+
-+ hcd = bus_to_hcd(buf->bus);
-+ fotg210 = hcd_to_fotg210(hcd);
-+ next = buf->output_buf;
-+ size = buf->alloc_size;
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+
-+ if (!HCD_HW_ACCESSIBLE(hcd)) {
-+ size = scnprintf(next, size,
-+ "bus %s, device %s\n"
-+ "%s\n"
-+ "SUSPENDED(no register access)\n",
-+ hcd->self.controller->bus->name,
-+ dev_name(hcd->self.controller),
-+ hcd->product_desc);
-+ goto done;
-+ }
-+
-+ /* Capability Registers */
-+ i = HC_VERSION(fotg210, fotg210_readl(fotg210,
-+ &fotg210->caps->hc_capbase));
-+ temp = scnprintf(next, size,
-+ "bus %s, device %s\n"
-+ "%s\n"
-+ "EHCI %x.%02x, rh state %s\n",
-+ hcd->self.controller->bus->name,
-+ dev_name(hcd->self.controller),
-+ hcd->product_desc,
-+ i >> 8, i & 0x0ff, rh_state_string(fotg210));
-+ size -= temp;
-+ next += temp;
-+
-+ /* FIXME interpret both types of params */
-+ i = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
-+ temp = scnprintf(next, size, "structural params 0x%08x\n", i);
-+ size -= temp;
-+ next += temp;
-+
-+ i = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
-+ temp = scnprintf(next, size, "capability params 0x%08x\n", i);
-+ size -= temp;
-+ next += temp;
-+
-+ /* Operational Registers */
-+ temp = dbg_status_buf(scratch, sizeof(scratch), label,
-+ fotg210_readl(fotg210, &fotg210->regs->status));
-+ temp = scnprintf(next, size, fmt, temp, scratch);
-+ size -= temp;
-+ next += temp;
-+
-+ temp = dbg_command_buf(scratch, sizeof(scratch), label,
-+ fotg210_readl(fotg210, &fotg210->regs->command));
-+ temp = scnprintf(next, size, fmt, temp, scratch);
-+ size -= temp;
-+ next += temp;
-+
-+ temp = dbg_intr_buf(scratch, sizeof(scratch), label,
-+ fotg210_readl(fotg210, &fotg210->regs->intr_enable));
-+ temp = scnprintf(next, size, fmt, temp, scratch);
-+ size -= temp;
-+ next += temp;
-+
-+ temp = scnprintf(next, size, "uframe %04x\n",
-+ fotg210_read_frame_index(fotg210));
-+ size -= temp;
-+ next += temp;
-+
-+ if (fotg210->async_unlink) {
-+ temp = scnprintf(next, size, "async unlink qh %p\n",
-+ fotg210->async_unlink);
-+ size -= temp;
-+ next += temp;
-+ }
-+
-+#ifdef FOTG210_STATS
-+ temp = scnprintf(next, size,
-+ "irq normal %ld err %ld iaa %ld(lost %ld)\n",
-+ fotg210->stats.normal, fotg210->stats.error,
-+ fotg210->stats.iaa, fotg210->stats.lost_iaa);
-+ size -= temp;
-+ next += temp;
-+
-+ temp = scnprintf(next, size, "complete %ld unlink %ld\n",
-+ fotg210->stats.complete, fotg210->stats.unlink);
-+ size -= temp;
-+ next += temp;
-+#endif
-+
-+done:
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+
-+ return buf->alloc_size - size;
-+}
-+
-+static struct debug_buffer
-+*alloc_buffer(struct usb_bus *bus, ssize_t (*fill_func)(struct debug_buffer *))
-+{
-+ struct debug_buffer *buf;
-+
-+ buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
-+
-+ if (buf) {
-+ buf->bus = bus;
-+ buf->fill_func = fill_func;
-+ mutex_init(&buf->mutex);
-+ buf->alloc_size = PAGE_SIZE;
-+ }
-+
-+ return buf;
-+}
-+
-+static int fill_buffer(struct debug_buffer *buf)
-+{
-+ int ret = 0;
-+
-+ if (!buf->output_buf)
-+ buf->output_buf = vmalloc(buf->alloc_size);
-+
-+ if (!buf->output_buf) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ ret = buf->fill_func(buf);
-+
-+ if (ret >= 0) {
-+ buf->count = ret;
-+ ret = 0;
-+ }
-+
-+out:
-+ return ret;
-+}
-+
-+static ssize_t debug_output(struct file *file, char __user *user_buf,
-+ size_t len, loff_t *offset)
-+{
-+ struct debug_buffer *buf = file->private_data;
-+ int ret = 0;
-+
-+ mutex_lock(&buf->mutex);
-+ if (buf->count == 0) {
-+ ret = fill_buffer(buf);
-+ if (ret != 0) {
-+ mutex_unlock(&buf->mutex);
-+ goto out;
-+ }
-+ }
-+ mutex_unlock(&buf->mutex);
-+
-+ ret = simple_read_from_buffer(user_buf, len, offset,
-+ buf->output_buf, buf->count);
-+
-+out:
-+ return ret;
-+
-+}
-+
-+static int debug_close(struct inode *inode, struct file *file)
-+{
-+ struct debug_buffer *buf = file->private_data;
-+
-+ if (buf) {
-+ vfree(buf->output_buf);
-+ kfree(buf);
-+ }
-+
-+ return 0;
-+}
-+static int debug_async_open(struct inode *inode, struct file *file)
-+{
-+ file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
-+
-+ return file->private_data ? 0 : -ENOMEM;
-+}
-+
-+static int debug_periodic_open(struct inode *inode, struct file *file)
-+{
-+ struct debug_buffer *buf;
-+
-+ buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
-+ file->private_data = buf;
-+ return 0;
-+}
-+
-+static int debug_registers_open(struct inode *inode, struct file *file)
-+{
-+ file->private_data = alloc_buffer(inode->i_private,
-+ fill_registers_buffer);
-+
-+ return file->private_data ? 0 : -ENOMEM;
-+}
-+
-+static inline void create_debug_files(struct fotg210_hcd *fotg210)
-+{
-+ struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
-+ struct dentry *root;
-+
-+ root = debugfs_create_dir(bus->bus_name, fotg210_debug_root);
-+
-+ debugfs_create_file("async", S_IRUGO, root, bus, &debug_async_fops);
-+ debugfs_create_file("periodic", S_IRUGO, root, bus,
-+ &debug_periodic_fops);
-+ debugfs_create_file("registers", S_IRUGO, root, bus,
-+ &debug_registers_fops);
-+}
-+
-+static inline void remove_debug_files(struct fotg210_hcd *fotg210)
-+{
-+ struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
-+
-+ debugfs_lookup_and_remove(bus->bus_name, fotg210_debug_root);
-+}
-+
-+/* handshake - spin reading hc until handshake completes or fails
-+ * @ptr: address of hc register to be read
-+ * @mask: bits to look at in result of read
-+ * @done: value of those bits when handshake succeeds
-+ * @usec: timeout in microseconds
-+ *
-+ * Returns negative errno, or zero on success
-+ *
-+ * Success happens when the "mask" bits have the specified value (hardware
-+ * handshake done). There are two failure modes: "usec" have passed (major
-+ * hardware flakeout), or the register reads as all-ones (hardware removed).
-+ *
-+ * That last failure should_only happen in cases like physical cardbus eject
-+ * before driver shutdown. But it also seems to be caused by bugs in cardbus
-+ * bridge shutdown: shutting down the bridge before the devices using it.
-+ */
-+static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
-+ u32 mask, u32 done, int usec)
-+{
-+ u32 result;
-+ int ret;
-+
-+ ret = readl_poll_timeout_atomic(ptr, result,
-+ ((result & mask) == done ||
-+ result == U32_MAX), 1, usec);
-+ if (result == U32_MAX) /* card removed */
-+ return -ENODEV;
-+
-+ return ret;
-+}
-+
-+/* Force HC to halt state from unknown (EHCI spec section 2.3).
-+ * Must be called with interrupts enabled and the lock not held.
-+ */
-+static int fotg210_halt(struct fotg210_hcd *fotg210)
-+{
-+ u32 temp;
-+
-+ spin_lock_irq(&fotg210->lock);
-+
-+ /* disable any irqs left enabled by previous code */
-+ fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-+
-+ /*
-+ * This routine gets called during probe before fotg210->command
-+ * has been initialized, so we can't rely on its value.
-+ */
-+ fotg210->command &= ~CMD_RUN;
-+ temp = fotg210_readl(fotg210, &fotg210->regs->command);
-+ temp &= ~(CMD_RUN | CMD_IAAD);
-+ fotg210_writel(fotg210, temp, &fotg210->regs->command);
-+
-+ spin_unlock_irq(&fotg210->lock);
-+ synchronize_irq(fotg210_to_hcd(fotg210)->irq);
-+
-+ return handshake(fotg210, &fotg210->regs->status,
-+ STS_HALT, STS_HALT, 16 * 125);
-+}
-+
-+/* Reset a non-running (STS_HALT == 1) controller.
-+ * Must be called with interrupts enabled and the lock not held.
-+ */
-+static int fotg210_reset(struct fotg210_hcd *fotg210)
-+{
-+ int retval;
-+ u32 command = fotg210_readl(fotg210, &fotg210->regs->command);
-+
-+ /* If the EHCI debug controller is active, special care must be
-+ * taken before and after a host controller reset
-+ */
-+ if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
-+ fotg210->debug = NULL;
-+
-+ command |= CMD_RESET;
-+ dbg_cmd(fotg210, "reset", command);
-+ fotg210_writel(fotg210, command, &fotg210->regs->command);
-+ fotg210->rh_state = FOTG210_RH_HALTED;
-+ fotg210->next_statechange = jiffies;
-+ retval = handshake(fotg210, &fotg210->regs->command,
-+ CMD_RESET, 0, 250 * 1000);
-+
-+ if (retval)
-+ return retval;
-+
-+ if (fotg210->debug)
-+ dbgp_external_startup(fotg210_to_hcd(fotg210));
-+
-+ fotg210->port_c_suspend = fotg210->suspended_ports =
-+ fotg210->resuming_ports = 0;
-+ return retval;
-+}
-+
-+/* Idle the controller (turn off the schedules).
-+ * Must be called with interrupts enabled and the lock not held.
-+ */
-+static void fotg210_quiesce(struct fotg210_hcd *fotg210)
-+{
-+ u32 temp;
-+
-+ if (fotg210->rh_state != FOTG210_RH_RUNNING)
-+ return;
-+
-+ /* wait for any schedule enables/disables to take effect */
-+ temp = (fotg210->command << 10) & (STS_ASS | STS_PSS);
-+ handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, temp,
-+ 16 * 125);
-+
-+ /* then disable anything that's still active */
-+ spin_lock_irq(&fotg210->lock);
-+ fotg210->command &= ~(CMD_ASE | CMD_PSE);
-+ fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-+ spin_unlock_irq(&fotg210->lock);
-+
-+ /* hardware can take 16 microframes to turn off ... */
-+ handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, 0,
-+ 16 * 125);
-+}
-+
-+static void end_unlink_async(struct fotg210_hcd *fotg210);
-+static void unlink_empty_async(struct fotg210_hcd *fotg210);
-+static void fotg210_work(struct fotg210_hcd *fotg210);
-+static void start_unlink_intr(struct fotg210_hcd *fotg210,
-+ struct fotg210_qh *qh);
-+static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
-+
-+/* Set a bit in the USBCMD register */
-+static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
-+{
-+ fotg210->command |= bit;
-+ fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-+
-+ /* unblock posted write */
-+ fotg210_readl(fotg210, &fotg210->regs->command);
-+}
-+
-+/* Clear a bit in the USBCMD register */
-+static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
-+{
-+ fotg210->command &= ~bit;
-+ fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-+
-+ /* unblock posted write */
-+ fotg210_readl(fotg210, &fotg210->regs->command);
-+}
-+
-+/* EHCI timer support... Now using hrtimers.
-+ *
-+ * Lots of different events are triggered from fotg210->hrtimer. Whenever
-+ * the timer routine runs, it checks each possible event; events that are
-+ * currently enabled and whose expiration time has passed get handled.
-+ * The set of enabled events is stored as a collection of bitflags in
-+ * fotg210->enabled_hrtimer_events, and they are numbered in order of
-+ * increasing delay values (ranging between 1 ms and 100 ms).
-+ *
-+ * Rather than implementing a sorted list or tree of all pending events,
-+ * we keep track only of the lowest-numbered pending event, in
-+ * fotg210->next_hrtimer_event. Whenever fotg210->hrtimer gets restarted, its
-+ * expiration time is set to the timeout value for this event.
-+ *
-+ * As a result, events might not get handled right away; the actual delay
-+ * could be anywhere up to twice the requested delay. This doesn't
-+ * matter, because none of the events are especially time-critical. The
-+ * ones that matter most all have a delay of 1 ms, so they will be
-+ * handled after 2 ms at most, which is okay. In addition to this, we
-+ * allow for an expiration range of 1 ms.
-+ */
-+
-+/* Delay lengths for the hrtimer event types.
-+ * Keep this list sorted by delay length, in the same order as
-+ * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
-+ */
-+static unsigned event_delays_ns[] = {
-+ 1 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_POLL_ASS */
-+ 1 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_POLL_PSS */
-+ 1 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_POLL_DEAD */
-+ 1125 * NSEC_PER_USEC, /* FOTG210_HRTIMER_UNLINK_INTR */
-+ 2 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_FREE_ITDS */
-+ 6 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_ASYNC_UNLINKS */
-+ 10 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_IAA_WATCHDOG */
-+ 10 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_DISABLE_PERIODIC */
-+ 15 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_DISABLE_ASYNC */
-+ 100 * NSEC_PER_MSEC, /* FOTG210_HRTIMER_IO_WATCHDOG */
-+};
-+
-+/* Enable a pending hrtimer event */
-+static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
-+ bool resched)
-+{
-+ ktime_t *timeout = &fotg210->hr_timeouts[event];
-+
-+ if (resched)
-+ *timeout = ktime_add(ktime_get(), event_delays_ns[event]);
-+ fotg210->enabled_hrtimer_events |= (1 << event);
-+
-+ /* Track only the lowest-numbered pending event */
-+ if (event < fotg210->next_hrtimer_event) {
-+ fotg210->next_hrtimer_event = event;
-+ hrtimer_start_range_ns(&fotg210->hrtimer, *timeout,
-+ NSEC_PER_MSEC, HRTIMER_MODE_ABS);
-+ }
-+}
-+
-+
-+/* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
-+static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
-+{
-+ unsigned actual, want;
-+
-+ /* Don't enable anything if the controller isn't running (e.g., died) */
-+ if (fotg210->rh_state != FOTG210_RH_RUNNING)
-+ return;
-+
-+ want = (fotg210->command & CMD_ASE) ? STS_ASS : 0;
-+ actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_ASS;
-+
-+ if (want != actual) {
-+
-+ /* Poll again later, but give up after about 20 ms */
-+ if (fotg210->ASS_poll_count++ < 20) {
-+ fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_ASS,
-+ true);
-+ return;
-+ }
-+ fotg210_dbg(fotg210, "Waited too long for the async schedule status (%x/%x), giving up\n",
-+ want, actual);
-+ }
-+ fotg210->ASS_poll_count = 0;
-+
-+ /* The status is up-to-date; restart or stop the schedule as needed */
-+ if (want == 0) { /* Stopped */
-+ if (fotg210->async_count > 0)
-+ fotg210_set_command_bit(fotg210, CMD_ASE);
-+
-+ } else { /* Running */
-+ if (fotg210->async_count == 0) {
-+
-+ /* Turn off the schedule after a while */
-+ fotg210_enable_event(fotg210,
-+ FOTG210_HRTIMER_DISABLE_ASYNC,
-+ true);
-+ }
-+ }
-+}
-+
-+/* Turn off the async schedule after a brief delay */
-+static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
-+{
-+ fotg210_clear_command_bit(fotg210, CMD_ASE);
-+}
-+
-+
-+/* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
-+static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
-+{
-+ unsigned actual, want;
-+
-+ /* Don't do anything if the controller isn't running (e.g., died) */
-+ if (fotg210->rh_state != FOTG210_RH_RUNNING)
-+ return;
-+
-+ want = (fotg210->command & CMD_PSE) ? STS_PSS : 0;
-+ actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_PSS;
-+
-+ if (want != actual) {
-+
-+ /* Poll again later, but give up after about 20 ms */
-+ if (fotg210->PSS_poll_count++ < 20) {
-+ fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_PSS,
-+ true);
-+ return;
-+ }
-+ fotg210_dbg(fotg210, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
-+ want, actual);
-+ }
-+ fotg210->PSS_poll_count = 0;
-+
-+ /* The status is up-to-date; restart or stop the schedule as needed */
-+ if (want == 0) { /* Stopped */
-+ if (fotg210->periodic_count > 0)
-+ fotg210_set_command_bit(fotg210, CMD_PSE);
-+
-+ } else { /* Running */
-+ if (fotg210->periodic_count == 0) {
-+
-+ /* Turn off the schedule after a while */
-+ fotg210_enable_event(fotg210,
-+ FOTG210_HRTIMER_DISABLE_PERIODIC,
-+ true);
-+ }
-+ }
-+}
-+
-+/* Turn off the periodic schedule after a brief delay */
-+static void fotg210_disable_PSE(struct fotg210_hcd *fotg210)
-+{
-+ fotg210_clear_command_bit(fotg210, CMD_PSE);
-+}
-+
-+
-+/* Poll the STS_HALT status bit; see when a dead controller stops */
-+static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
-+{
-+ if (!(fotg210_readl(fotg210, &fotg210->regs->status) & STS_HALT)) {
-+
-+ /* Give up after a few milliseconds */
-+ if (fotg210->died_poll_count++ < 5) {
-+ /* Try again later */
-+ fotg210_enable_event(fotg210,
-+ FOTG210_HRTIMER_POLL_DEAD, true);
-+ return;
-+ }
-+ fotg210_warn(fotg210, "Waited too long for the controller to stop, giving up\n");
-+ }
-+
-+ /* Clean up the mess */
-+ fotg210->rh_state = FOTG210_RH_HALTED;
-+ fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-+ fotg210_work(fotg210);
-+ end_unlink_async(fotg210);
-+
-+ /* Not in process context, so don't try to reset the controller */
-+}
-+
-+
-+/* Handle unlinked interrupt QHs once they are gone from the hardware */
-+static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
-+{
-+ bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
-+
-+ /*
-+ * Process all the QHs on the intr_unlink list that were added
-+ * before the current unlink cycle began. The list is in
-+ * temporal order, so stop when we reach the first entry in the
-+ * current cycle. But if the root hub isn't running then
-+ * process all the QHs on the list.
-+ */
-+ fotg210->intr_unlinking = true;
-+ while (fotg210->intr_unlink) {
-+ struct fotg210_qh *qh = fotg210->intr_unlink;
-+
-+ if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
-+ break;
-+ fotg210->intr_unlink = qh->unlink_next;
-+ qh->unlink_next = NULL;
-+ end_unlink_intr(fotg210, qh);
-+ }
-+
-+ /* Handle remaining entries later */
-+ if (fotg210->intr_unlink) {
-+ fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-+ true);
-+ ++fotg210->intr_unlink_cycle;
-+ }
-+ fotg210->intr_unlinking = false;
-+}
-+
-+
-+/* Start another free-iTDs/siTDs cycle */
-+static void start_free_itds(struct fotg210_hcd *fotg210)
-+{
-+ if (!(fotg210->enabled_hrtimer_events &
-+ BIT(FOTG210_HRTIMER_FREE_ITDS))) {
-+ fotg210->last_itd_to_free = list_entry(
-+ fotg210->cached_itd_list.prev,
-+ struct fotg210_itd, itd_list);
-+ fotg210_enable_event(fotg210, FOTG210_HRTIMER_FREE_ITDS, true);
-+ }
-+}
-+
-+/* Wait for controller to stop using old iTDs and siTDs */
-+static void end_free_itds(struct fotg210_hcd *fotg210)
-+{
-+ struct fotg210_itd *itd, *n;
-+
-+ if (fotg210->rh_state < FOTG210_RH_RUNNING)
-+ fotg210->last_itd_to_free = NULL;
-+
-+ list_for_each_entry_safe(itd, n, &fotg210->cached_itd_list, itd_list) {
-+ list_del(&itd->itd_list);
-+ dma_pool_free(fotg210->itd_pool, itd, itd->itd_dma);
-+ if (itd == fotg210->last_itd_to_free)
-+ break;
-+ }
-+
-+ if (!list_empty(&fotg210->cached_itd_list))
-+ start_free_itds(fotg210);
-+}
-+
-+
-+/* Handle lost (or very late) IAA interrupts */
-+static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
-+{
-+ if (fotg210->rh_state != FOTG210_RH_RUNNING)
-+ return;
-+
-+ /*
-+ * Lost IAA irqs wedge things badly; seen first with a vt8235.
-+ * So we need this watchdog, but must protect it against both
-+ * (a) SMP races against real IAA firing and retriggering, and
-+ * (b) clean HC shutdown, when IAA watchdog was pending.
-+ */
-+ if (fotg210->async_iaa) {
-+ u32 cmd, status;
-+
-+ /* If we get here, IAA is *REALLY* late. It's barely
-+ * conceivable that the system is so busy that CMD_IAAD
-+ * is still legitimately set, so let's be sure it's
-+ * clear before we read STS_IAA. (The HC should clear
-+ * CMD_IAAD when it sets STS_IAA.)
-+ */
-+ cmd = fotg210_readl(fotg210, &fotg210->regs->command);
-+
-+ /*
-+ * If IAA is set here it either legitimately triggered
-+ * after the watchdog timer expired (_way_ late, so we'll
-+ * still count it as lost) ... or a silicon erratum:
-+ * - VIA seems to set IAA without triggering the IRQ;
-+ * - IAAD potentially cleared without setting IAA.
-+ */
-+ status = fotg210_readl(fotg210, &fotg210->regs->status);
-+ if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
-+ INCR(fotg210->stats.lost_iaa);
-+ fotg210_writel(fotg210, STS_IAA,
-+ &fotg210->regs->status);
-+ }
-+
-+ fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",
-+ status, cmd);
-+ end_unlink_async(fotg210);
-+ }
-+}
-+
-+
-+/* Enable the I/O watchdog, if appropriate */
-+static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
-+{
-+ /* Not needed if the controller isn't running or it's already enabled */
-+ if (fotg210->rh_state != FOTG210_RH_RUNNING ||
-+ (fotg210->enabled_hrtimer_events &
-+ BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
-+ return;
-+
-+ /*
-+ * Isochronous transfers always need the watchdog.
-+ * For other sorts we use it only if the flag is set.
-+ */
-+ if (fotg210->isoc_count > 0 || (fotg210->need_io_watchdog &&
-+ fotg210->async_count + fotg210->intr_count > 0))
-+ fotg210_enable_event(fotg210, FOTG210_HRTIMER_IO_WATCHDOG,
-+ true);
-+}
-+
-+
-+/* Handler functions for the hrtimer event types.
-+ * Keep this array in the same order as the event types indexed by
-+ * enum fotg210_hrtimer_event in fotg210.h.
-+ */
-+static void (*event_handlers[])(struct fotg210_hcd *) = {
-+ fotg210_poll_ASS, /* FOTG210_HRTIMER_POLL_ASS */
-+ fotg210_poll_PSS, /* FOTG210_HRTIMER_POLL_PSS */
-+ fotg210_handle_controller_death, /* FOTG210_HRTIMER_POLL_DEAD */
-+ fotg210_handle_intr_unlinks, /* FOTG210_HRTIMER_UNLINK_INTR */
-+ end_free_itds, /* FOTG210_HRTIMER_FREE_ITDS */
-+ unlink_empty_async, /* FOTG210_HRTIMER_ASYNC_UNLINKS */
-+ fotg210_iaa_watchdog, /* FOTG210_HRTIMER_IAA_WATCHDOG */
-+ fotg210_disable_PSE, /* FOTG210_HRTIMER_DISABLE_PERIODIC */
-+ fotg210_disable_ASE, /* FOTG210_HRTIMER_DISABLE_ASYNC */
-+ fotg210_work, /* FOTG210_HRTIMER_IO_WATCHDOG */
-+};
-+
-+static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
-+{
-+ struct fotg210_hcd *fotg210 =
-+ container_of(t, struct fotg210_hcd, hrtimer);
-+ ktime_t now;
-+ unsigned long events;
-+ unsigned long flags;
-+ unsigned e;
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+
-+ events = fotg210->enabled_hrtimer_events;
-+ fotg210->enabled_hrtimer_events = 0;
-+ fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
-+
-+ /*
-+ * Check each pending event. If its time has expired, handle
-+ * the event; otherwise re-enable it.
-+ */
-+ now = ktime_get();
-+ for_each_set_bit(e, &events, FOTG210_HRTIMER_NUM_EVENTS) {
-+ if (ktime_compare(now, fotg210->hr_timeouts[e]) >= 0)
-+ event_handlers[e](fotg210);
-+ else
-+ fotg210_enable_event(fotg210, e, false);
-+ }
-+
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ return HRTIMER_NORESTART;
-+}
-+
-+#define fotg210_bus_suspend NULL
-+#define fotg210_bus_resume NULL
-+
-+static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
-+ u32 __iomem *status_reg, int port_status)
-+{
-+ if (!(port_status & PORT_CONNECT))
-+ return port_status;
-+
-+ /* if reset finished and it's still not enabled -- handoff */
-+ if (!(port_status & PORT_PE))
-+ /* with integrated TT, there's nobody to hand it to! */
-+ fotg210_dbg(fotg210, "Failed to enable port %d on root hub TT\n",
-+ index + 1);
-+ else
-+ fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
-+ index + 1);
-+
-+ return port_status;
-+}
-+
-+
-+/* build "status change" packet (one or two bytes) from HC registers */
-+
-+static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ u32 temp, status;
-+ u32 mask;
-+ int retval = 1;
-+ unsigned long flags;
-+
-+ /* init status to no-changes */
-+ buf[0] = 0;
-+
-+ /* Inform the core about resumes-in-progress by returning
-+ * a non-zero value even if there are no status changes.
-+ */
-+ status = fotg210->resuming_ports;
-+
-+ mask = PORT_CSC | PORT_PEC;
-+ /* PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND */
-+
-+ /* no hub change reports (bit 0) for now (power, ...) */
-+
-+ /* port N changes (bit N)? */
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+
-+ temp = fotg210_readl(fotg210, &fotg210->regs->port_status);
-+
-+ /*
-+ * Return status information even for ports with OWNER set.
-+ * Otherwise hub_wq wouldn't see the disconnect event when a
-+ * high-speed device is switched over to the companion
-+ * controller by the user.
-+ */
-+
-+ if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend) ||
-+ (fotg210->reset_done[0] &&
-+ time_after_eq(jiffies, fotg210->reset_done[0]))) {
-+ buf[0] |= 1 << 1;
-+ status = STS_PCD;
-+ }
-+ /* FIXME autosuspend idle root hubs */
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ return status ? retval : 0;
-+}
-+
-+static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
-+ struct usb_hub_descriptor *desc)
-+{
-+ int ports = HCS_N_PORTS(fotg210->hcs_params);
-+ u16 temp;
-+
-+ desc->bDescriptorType = USB_DT_HUB;
-+ desc->bPwrOn2PwrGood = 10; /* fotg210 1.0, 2.3.9 says 20ms max */
-+ desc->bHubContrCurrent = 0;
-+
-+ desc->bNbrPorts = ports;
-+ temp = 1 + (ports / 8);
-+ desc->bDescLength = 7 + 2 * temp;
-+
-+ /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
-+ memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
-+ memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
-+
-+ temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */
-+ temp |= HUB_CHAR_NO_LPSM; /* no power switching */
-+ desc->wHubCharacteristics = cpu_to_le16(temp);
-+}
-+
-+static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
-+ u16 wIndex, char *buf, u16 wLength)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ int ports = HCS_N_PORTS(fotg210->hcs_params);
-+ u32 __iomem *status_reg = &fotg210->regs->port_status;
-+ u32 temp, temp1, status;
-+ unsigned long flags;
-+ int retval = 0;
-+ unsigned selector;
-+
-+ /*
-+ * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR.
-+ * HCS_INDICATOR may say we can change LEDs to off/amber/green.
-+ * (track current state ourselves) ... blink for diagnostics,
-+ * power, "this is the one", etc. EHCI spec supports this.
-+ */
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ switch (typeReq) {
-+ case ClearHubFeature:
-+ switch (wValue) {
-+ case C_HUB_LOCAL_POWER:
-+ case C_HUB_OVER_CURRENT:
-+ /* no hub-wide feature/status flags */
-+ break;
-+ default:
-+ goto error;
-+ }
-+ break;
-+ case ClearPortFeature:
-+ if (!wIndex || wIndex > ports)
-+ goto error;
-+ wIndex--;
-+ temp = fotg210_readl(fotg210, status_reg);
-+ temp &= ~PORT_RWC_BITS;
-+
-+ /*
-+ * Even if OWNER is set, so the port is owned by the
-+ * companion controller, hub_wq needs to be able to clear
-+ * the port-change status bits (especially
-+ * USB_PORT_STAT_C_CONNECTION).
-+ */
-+
-+ switch (wValue) {
-+ case USB_PORT_FEAT_ENABLE:
-+ fotg210_writel(fotg210, temp & ~PORT_PE, status_reg);
-+ break;
-+ case USB_PORT_FEAT_C_ENABLE:
-+ fotg210_writel(fotg210, temp | PORT_PEC, status_reg);
-+ break;
-+ case USB_PORT_FEAT_SUSPEND:
-+ if (temp & PORT_RESET)
-+ goto error;
-+ if (!(temp & PORT_SUSPEND))
-+ break;
-+ if ((temp & PORT_PE) == 0)
-+ goto error;
-+
-+ /* resume signaling for 20 msec */
-+ fotg210_writel(fotg210, temp | PORT_RESUME, status_reg);
-+ fotg210->reset_done[wIndex] = jiffies
-+ + msecs_to_jiffies(USB_RESUME_TIMEOUT);
-+ break;
-+ case USB_PORT_FEAT_C_SUSPEND:
-+ clear_bit(wIndex, &fotg210->port_c_suspend);
-+ break;
-+ case USB_PORT_FEAT_C_CONNECTION:
-+ fotg210_writel(fotg210, temp | PORT_CSC, status_reg);
-+ break;
-+ case USB_PORT_FEAT_C_OVER_CURRENT:
-+ fotg210_writel(fotg210, temp | OTGISR_OVC,
-+ &fotg210->regs->otgisr);
-+ break;
-+ case USB_PORT_FEAT_C_RESET:
-+ /* GetPortStatus clears reset */
-+ break;
-+ default:
-+ goto error;
-+ }
-+ fotg210_readl(fotg210, &fotg210->regs->command);
-+ break;
-+ case GetHubDescriptor:
-+ fotg210_hub_descriptor(fotg210, (struct usb_hub_descriptor *)
-+ buf);
-+ break;
-+ case GetHubStatus:
-+ /* no hub-wide feature/status flags */
-+ memset(buf, 0, 4);
-+ /*cpu_to_le32s ((u32 *) buf); */
-+ break;
-+ case GetPortStatus:
-+ if (!wIndex || wIndex > ports)
-+ goto error;
-+ wIndex--;
-+ status = 0;
-+ temp = fotg210_readl(fotg210, status_reg);
-+
-+ /* wPortChange bits */
-+ if (temp & PORT_CSC)
-+ status |= USB_PORT_STAT_C_CONNECTION << 16;
-+ if (temp & PORT_PEC)
-+ status |= USB_PORT_STAT_C_ENABLE << 16;
-+
-+ temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
-+ if (temp1 & OTGISR_OVC)
-+ status |= USB_PORT_STAT_C_OVERCURRENT << 16;
-+
-+ /* whoever resumes must GetPortStatus to complete it!! */
-+ if (temp & PORT_RESUME) {
-+
-+ /* Remote Wakeup received? */
-+ if (!fotg210->reset_done[wIndex]) {
-+ /* resume signaling for 20 msec */
-+ fotg210->reset_done[wIndex] = jiffies
-+ + msecs_to_jiffies(20);
-+ /* check the port again */
-+ mod_timer(&fotg210_to_hcd(fotg210)->rh_timer,
-+ fotg210->reset_done[wIndex]);
-+ }
-+
-+ /* resume completed? */
-+ else if (time_after_eq(jiffies,
-+ fotg210->reset_done[wIndex])) {
-+ clear_bit(wIndex, &fotg210->suspended_ports);
-+ set_bit(wIndex, &fotg210->port_c_suspend);
-+ fotg210->reset_done[wIndex] = 0;
-+
-+ /* stop resume signaling */
-+ temp = fotg210_readl(fotg210, status_reg);
-+ fotg210_writel(fotg210, temp &
-+ ~(PORT_RWC_BITS | PORT_RESUME),
-+ status_reg);
-+ clear_bit(wIndex, &fotg210->resuming_ports);
-+ retval = handshake(fotg210, status_reg,
-+ PORT_RESUME, 0, 2000);/* 2ms */
-+ if (retval != 0) {
-+ fotg210_err(fotg210,
-+ "port %d resume error %d\n",
-+ wIndex + 1, retval);
-+ goto error;
-+ }
-+ temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
-+ }
-+ }
-+
-+ /* whoever resets must GetPortStatus to complete it!! */
-+ if ((temp & PORT_RESET) && time_after_eq(jiffies,
-+ fotg210->reset_done[wIndex])) {
-+ status |= USB_PORT_STAT_C_RESET << 16;
-+ fotg210->reset_done[wIndex] = 0;
-+ clear_bit(wIndex, &fotg210->resuming_ports);
-+
-+ /* force reset to complete */
-+ fotg210_writel(fotg210,
-+ temp & ~(PORT_RWC_BITS | PORT_RESET),
-+ status_reg);
-+ /* REVISIT: some hardware needs 550+ usec to clear
-+ * this bit; seems too long to spin routinely...
-+ */
-+ retval = handshake(fotg210, status_reg,
-+ PORT_RESET, 0, 1000);
-+ if (retval != 0) {
-+ fotg210_err(fotg210, "port %d reset error %d\n",
-+ wIndex + 1, retval);
-+ goto error;
-+ }
-+
-+ /* see what we found out */
-+ temp = check_reset_complete(fotg210, wIndex, status_reg,
-+ fotg210_readl(fotg210, status_reg));
-+
-+ /* restart schedule */
-+ fotg210->command |= CMD_RUN;
-+ fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-+ }
-+
-+ if (!(temp & (PORT_RESUME|PORT_RESET))) {
-+ fotg210->reset_done[wIndex] = 0;
-+ clear_bit(wIndex, &fotg210->resuming_ports);
-+ }
-+
-+ /* transfer dedicated ports to the companion hc */
-+ if ((temp & PORT_CONNECT) &&
-+ test_bit(wIndex, &fotg210->companion_ports)) {
-+ temp &= ~PORT_RWC_BITS;
-+ fotg210_writel(fotg210, temp, status_reg);
-+ fotg210_dbg(fotg210, "port %d --> companion\n",
-+ wIndex + 1);
-+ temp = fotg210_readl(fotg210, status_reg);
-+ }
-+
-+ /*
-+ * Even if OWNER is set, there's no harm letting hub_wq
-+ * see the wPortStatus values (they should all be 0 except
-+ * for PORT_POWER anyway).
-+ */
-+
-+ if (temp & PORT_CONNECT) {
-+ status |= USB_PORT_STAT_CONNECTION;
-+ status |= fotg210_port_speed(fotg210, temp);
-+ }
-+ if (temp & PORT_PE)
-+ status |= USB_PORT_STAT_ENABLE;
-+
-+ /* maybe the port was unsuspended without our knowledge */
-+ if (temp & (PORT_SUSPEND|PORT_RESUME)) {
-+ status |= USB_PORT_STAT_SUSPEND;
-+ } else if (test_bit(wIndex, &fotg210->suspended_ports)) {
-+ clear_bit(wIndex, &fotg210->suspended_ports);
-+ clear_bit(wIndex, &fotg210->resuming_ports);
-+ fotg210->reset_done[wIndex] = 0;
-+ if (temp & PORT_PE)
-+ set_bit(wIndex, &fotg210->port_c_suspend);
-+ }
-+
-+ temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
-+ if (temp1 & OTGISR_OVC)
-+ status |= USB_PORT_STAT_OVERCURRENT;
-+ if (temp & PORT_RESET)
-+ status |= USB_PORT_STAT_RESET;
-+ if (test_bit(wIndex, &fotg210->port_c_suspend))
-+ status |= USB_PORT_STAT_C_SUSPEND << 16;
-+
-+ if (status & ~0xffff) /* only if wPortChange is interesting */
-+ dbg_port(fotg210, "GetStatus", wIndex + 1, temp);
-+ put_unaligned_le32(status, buf);
-+ break;
-+ case SetHubFeature:
-+ switch (wValue) {
-+ case C_HUB_LOCAL_POWER:
-+ case C_HUB_OVER_CURRENT:
-+ /* no hub-wide feature/status flags */
-+ break;
-+ default:
-+ goto error;
-+ }
-+ break;
-+ case SetPortFeature:
-+ selector = wIndex >> 8;
-+ wIndex &= 0xff;
-+
-+ if (!wIndex || wIndex > ports)
-+ goto error;
-+ wIndex--;
-+ temp = fotg210_readl(fotg210, status_reg);
-+ temp &= ~PORT_RWC_BITS;
-+ switch (wValue) {
-+ case USB_PORT_FEAT_SUSPEND:
-+ if ((temp & PORT_PE) == 0
-+ || (temp & PORT_RESET) != 0)
-+ goto error;
-+
-+ /* After above check the port must be connected.
-+ * Set appropriate bit thus could put phy into low power
-+ * mode if we have hostpc feature
-+ */
-+ fotg210_writel(fotg210, temp | PORT_SUSPEND,
-+ status_reg);
-+ set_bit(wIndex, &fotg210->suspended_ports);
-+ break;
-+ case USB_PORT_FEAT_RESET:
-+ if (temp & PORT_RESUME)
-+ goto error;
-+ /* line status bits may report this as low speed,
-+ * which can be fine if this root hub has a
-+ * transaction translator built in.
-+ */
-+ fotg210_dbg(fotg210, "port %d reset\n", wIndex + 1);
-+ temp |= PORT_RESET;
-+ temp &= ~PORT_PE;
-+
-+ /*
-+ * caller must wait, then call GetPortStatus
-+ * usb 2.0 spec says 50 ms resets on root
-+ */
-+ fotg210->reset_done[wIndex] = jiffies
-+ + msecs_to_jiffies(50);
-+ fotg210_writel(fotg210, temp, status_reg);
-+ break;
-+
-+ /* For downstream facing ports (these): one hub port is put
-+ * into test mode according to USB2 11.24.2.13, then the hub
-+ * must be reset (which for root hub now means rmmod+modprobe,
-+ * or else system reboot). See EHCI 2.3.9 and 4.14 for info
-+ * about the EHCI-specific stuff.
-+ */
-+ case USB_PORT_FEAT_TEST:
-+ if (!selector || selector > 5)
-+ goto error;
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ fotg210_quiesce(fotg210);
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+
-+ /* Put all enabled ports into suspend */
-+ temp = fotg210_readl(fotg210, status_reg) &
-+ ~PORT_RWC_BITS;
-+ if (temp & PORT_PE)
-+ fotg210_writel(fotg210, temp | PORT_SUSPEND,
-+ status_reg);
-+
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ fotg210_halt(fotg210);
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+
-+ temp = fotg210_readl(fotg210, status_reg);
-+ temp |= selector << 16;
-+ fotg210_writel(fotg210, temp, status_reg);
-+ break;
-+
-+ default:
-+ goto error;
-+ }
-+ fotg210_readl(fotg210, &fotg210->regs->command);
-+ break;
-+
-+ default:
-+error:
-+ /* "stall" on error */
-+ retval = -EPIPE;
-+ }
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ return retval;
-+}
-+
-+static void __maybe_unused fotg210_relinquish_port(struct usb_hcd *hcd,
-+ int portnum)
-+{
-+ return;
-+}
-+
-+static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
-+ int portnum)
-+{
-+ return 0;
-+}
-+
-+/* There's basically three types of memory:
-+ * - data used only by the HCD ... kmalloc is fine
-+ * - async and periodic schedules, shared by HC and HCD ... these
-+ * need to use dma_pool or dma_alloc_coherent
-+ * - driver buffers, read/written by HC ... single shot DMA mapped
-+ *
-+ * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
-+ * No memory seen by this driver is pageable.
-+ */
-+
-+/* Allocate the key transfer structures from the previously allocated pool */
-+static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
-+ struct fotg210_qtd *qtd, dma_addr_t dma)
-+{
-+ memset(qtd, 0, sizeof(*qtd));
-+ qtd->qtd_dma = dma;
-+ qtd->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
-+ qtd->hw_next = FOTG210_LIST_END(fotg210);
-+ qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
-+ INIT_LIST_HEAD(&qtd->qtd_list);
-+}
-+
-+static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
-+ gfp_t flags)
-+{
-+ struct fotg210_qtd *qtd;
-+ dma_addr_t dma;
-+
-+ qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
-+ if (qtd != NULL)
-+ fotg210_qtd_init(fotg210, qtd, dma);
-+
-+ return qtd;
-+}
-+
-+static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
-+ struct fotg210_qtd *qtd)
-+{
-+ dma_pool_free(fotg210->qtd_pool, qtd, qtd->qtd_dma);
-+}
-+
-+
-+static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-+{
-+ /* clean qtds first, and know this is not linked */
-+ if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) {
-+ fotg210_dbg(fotg210, "unused qh not empty!\n");
-+ BUG();
-+ }
-+ if (qh->dummy)
-+ fotg210_qtd_free(fotg210, qh->dummy);
-+ dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
-+ kfree(qh);
-+}
-+
-+static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
-+ gfp_t flags)
-+{
-+ struct fotg210_qh *qh;
-+ dma_addr_t dma;
-+
-+ qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
-+ if (!qh)
-+ goto done;
-+ qh->hw = (struct fotg210_qh_hw *)
-+ dma_pool_zalloc(fotg210->qh_pool, flags, &dma);
-+ if (!qh->hw)
-+ goto fail;
-+ qh->qh_dma = dma;
-+ INIT_LIST_HEAD(&qh->qtd_list);
-+
-+ /* dummy td enables safe urb queuing */
-+ qh->dummy = fotg210_qtd_alloc(fotg210, flags);
-+ if (qh->dummy == NULL) {
-+ fotg210_dbg(fotg210, "no dummy td\n");
-+ goto fail1;
-+ }
-+done:
-+ return qh;
-+fail1:
-+ dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
-+fail:
-+ kfree(qh);
-+ return NULL;
-+}
-+
-+/* The queue heads and transfer descriptors are managed from pools tied
-+ * to each of the "per device" structures.
-+ * This is the initialisation and cleanup code.
-+ */
-+
-+static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
-+{
-+ if (fotg210->async)
-+ qh_destroy(fotg210, fotg210->async);
-+ fotg210->async = NULL;
-+
-+ if (fotg210->dummy)
-+ qh_destroy(fotg210, fotg210->dummy);
-+ fotg210->dummy = NULL;
-+
-+ /* DMA consistent memory and pools */
-+ dma_pool_destroy(fotg210->qtd_pool);
-+ fotg210->qtd_pool = NULL;
-+
-+ dma_pool_destroy(fotg210->qh_pool);
-+ fotg210->qh_pool = NULL;
-+
-+ dma_pool_destroy(fotg210->itd_pool);
-+ fotg210->itd_pool = NULL;
-+
-+ if (fotg210->periodic)
-+ dma_free_coherent(fotg210_to_hcd(fotg210)->self.controller,
-+ fotg210->periodic_size * sizeof(u32),
-+ fotg210->periodic, fotg210->periodic_dma);
-+ fotg210->periodic = NULL;
-+
-+ /* shadow periodic table */
-+ kfree(fotg210->pshadow);
-+ fotg210->pshadow = NULL;
-+}
-+
-+/* remember to add cleanup code (above) if you add anything here */
-+static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
-+{
-+ int i;
-+
-+ /* QTDs for control/bulk/intr transfers */
-+ fotg210->qtd_pool = dma_pool_create("fotg210_qtd",
-+ fotg210_to_hcd(fotg210)->self.controller,
-+ sizeof(struct fotg210_qtd),
-+ 32 /* byte alignment (for hw parts) */,
-+ 4096 /* can't cross 4K */);
-+ if (!fotg210->qtd_pool)
-+ goto fail;
-+
-+ /* QHs for control/bulk/intr transfers */
-+ fotg210->qh_pool = dma_pool_create("fotg210_qh",
-+ fotg210_to_hcd(fotg210)->self.controller,
-+ sizeof(struct fotg210_qh_hw),
-+ 32 /* byte alignment (for hw parts) */,
-+ 4096 /* can't cross 4K */);
-+ if (!fotg210->qh_pool)
-+ goto fail;
-+
-+ fotg210->async = fotg210_qh_alloc(fotg210, flags);
-+ if (!fotg210->async)
-+ goto fail;
-+
-+ /* ITD for high speed ISO transfers */
-+ fotg210->itd_pool = dma_pool_create("fotg210_itd",
-+ fotg210_to_hcd(fotg210)->self.controller,
-+ sizeof(struct fotg210_itd),
-+ 64 /* byte alignment (for hw parts) */,
-+ 4096 /* can't cross 4K */);
-+ if (!fotg210->itd_pool)
-+ goto fail;
-+
-+ /* Hardware periodic table */
-+ fotg210->periodic =
-+ dma_alloc_coherent(fotg210_to_hcd(fotg210)->self.controller,
-+ fotg210->periodic_size * sizeof(__le32),
-+ &fotg210->periodic_dma, 0);
-+ if (fotg210->periodic == NULL)
-+ goto fail;
-+
-+ for (i = 0; i < fotg210->periodic_size; i++)
-+ fotg210->periodic[i] = FOTG210_LIST_END(fotg210);
-+
-+ /* software shadow of hardware table */
-+ fotg210->pshadow = kcalloc(fotg210->periodic_size, sizeof(void *),
-+ flags);
-+ if (fotg210->pshadow != NULL)
-+ return 0;
-+
-+fail:
-+ fotg210_dbg(fotg210, "couldn't init memory\n");
-+ fotg210_mem_cleanup(fotg210);
-+ return -ENOMEM;
-+}
-+/* EHCI hardware queue manipulation ... the core. QH/QTD manipulation.
-+ *
-+ * Control, bulk, and interrupt traffic all use "qh" lists. They list "qtd"
-+ * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
-+ * buffers needed for the larger number). We use one QH per endpoint, queue
-+ * multiple urbs (all three types) per endpoint. URBs may need several qtds.
-+ *
-+ * ISO traffic uses "ISO TD" (itd) records, and (along with
-+ * interrupts) needs careful scheduling. Performance improvements can be
-+ * an ongoing challenge. That's in "ehci-sched.c".
-+ *
-+ * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs,
-+ * or otherwise through transaction translators (TTs) in USB 2.0 hubs using
-+ * (b) special fields in qh entries or (c) split iso entries. TTs will
-+ * buffer low/full speed data so the host collects it at high speed.
-+ */
-+
-+/* fill a qtd, returning how much of the buffer we were able to queue up */
-+static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
-+ dma_addr_t buf, size_t len, int token, int maxpacket)
-+{
-+ int i, count;
-+ u64 addr = buf;
-+
-+ /* one buffer entry per 4K ... first might be short or unaligned */
-+ qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
-+ qtd->hw_buf_hi[0] = cpu_to_hc32(fotg210, (u32)(addr >> 32));
-+ count = 0x1000 - (buf & 0x0fff); /* rest of that page */
-+ if (likely(len < count)) /* ... iff needed */
-+ count = len;
-+ else {
-+ buf += 0x1000;
-+ buf &= ~0x0fff;
-+
-+ /* per-qtd limit: from 16K to 20K (best alignment) */
-+ for (i = 1; count < len && i < 5; i++) {
-+ addr = buf;
-+ qtd->hw_buf[i] = cpu_to_hc32(fotg210, (u32)addr);
-+ qtd->hw_buf_hi[i] = cpu_to_hc32(fotg210,
-+ (u32)(addr >> 32));
-+ buf += 0x1000;
-+ if ((count + 0x1000) < len)
-+ count += 0x1000;
-+ else
-+ count = len;
-+ }
-+
-+ /* short packets may only terminate transfers */
-+ if (count != len)
-+ count -= (count % maxpacket);
-+ }
-+ qtd->hw_token = cpu_to_hc32(fotg210, (count << 16) | token);
-+ qtd->length = count;
-+
-+ return count;
-+}
-+
-+static inline void qh_update(struct fotg210_hcd *fotg210,
-+ struct fotg210_qh *qh, struct fotg210_qtd *qtd)
-+{
-+ struct fotg210_qh_hw *hw = qh->hw;
-+
-+ /* writes to an active overlay are unsafe */
-+ BUG_ON(qh->qh_state != QH_STATE_IDLE);
-+
-+ hw->hw_qtd_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-+ hw->hw_alt_next = FOTG210_LIST_END(fotg210);
-+
-+ /* Except for control endpoints, we make hardware maintain data
-+ * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
-+ * and set the pseudo-toggle in udev. Only usb_clear_halt() will
-+ * ever clear it.
-+ */
-+ if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
-+ unsigned is_out, epnum;
-+
-+ is_out = qh->is_out;
-+ epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
-+ if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) {
-+ hw->hw_token &= ~cpu_to_hc32(fotg210, QTD_TOGGLE);
-+ usb_settoggle(qh->dev, epnum, is_out, 1);
-+ }
-+ }
-+
-+ hw->hw_token &= cpu_to_hc32(fotg210, QTD_TOGGLE | QTD_STS_PING);
-+}
-+
-+/* if it weren't for a common silicon quirk (writing the dummy into the qh
-+ * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
-+ * recovery (including urb dequeue) would need software changes to a QH...
-+ */
-+static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-+{
-+ struct fotg210_qtd *qtd;
-+
-+ if (list_empty(&qh->qtd_list))
-+ qtd = qh->dummy;
-+ else {
-+ qtd = list_entry(qh->qtd_list.next,
-+ struct fotg210_qtd, qtd_list);
-+ /*
-+ * first qtd may already be partially processed.
-+ * If we come here during unlink, the QH overlay region
-+ * might have reference to the just unlinked qtd. The
-+ * qtd is updated in qh_completions(). Update the QH
-+ * overlay here.
-+ */
-+ if (cpu_to_hc32(fotg210, qtd->qtd_dma) == qh->hw->hw_current) {
-+ qh->hw->hw_qtd_next = qtd->hw_next;
-+ qtd = NULL;
-+ }
-+ }
-+
-+ if (qtd)
-+ qh_update(fotg210, qh, qtd);
-+}
-+
-+static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
-+
-+static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
-+ struct usb_host_endpoint *ep)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ struct fotg210_qh *qh = ep->hcpriv;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ qh->clearing_tt = 0;
-+ if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
-+ && fotg210->rh_state == FOTG210_RH_RUNNING)
-+ qh_link_async(fotg210, qh);
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+}
-+
-+static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
-+ struct fotg210_qh *qh, struct urb *urb, u32 token)
-+{
-+
-+ /* If an async split transaction gets an error or is unlinked,
-+ * the TT buffer may be left in an indeterminate state. We
-+ * have to clear the TT buffer.
-+ *
-+ * Note: this routine is never called for Isochronous transfers.
-+ */
-+ if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
-+ struct usb_device *tt = urb->dev->tt->hub;
-+
-+ dev_dbg(&tt->dev,
-+ "clear tt buffer port %d, a%d ep%d t%08x\n",
-+ urb->dev->ttport, urb->dev->devnum,
-+ usb_pipeendpoint(urb->pipe), token);
-+
-+ if (urb->dev->tt->hub !=
-+ fotg210_to_hcd(fotg210)->self.root_hub) {
-+ if (usb_hub_clear_tt_buffer(urb) == 0)
-+ qh->clearing_tt = 1;
-+ }
-+ }
-+}
-+
-+static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
-+ size_t length, u32 token)
-+{
-+ int status = -EINPROGRESS;
-+
-+ /* count IN/OUT bytes, not SETUP (even short packets) */
-+ if (likely(QTD_PID(token) != 2))
-+ urb->actual_length += length - QTD_LENGTH(token);
-+
-+ /* don't modify error codes */
-+ if (unlikely(urb->unlinked))
-+ return status;
-+
-+ /* force cleanup after short read; not always an error */
-+ if (unlikely(IS_SHORT_READ(token)))
-+ status = -EREMOTEIO;
-+
-+ /* serious "can't proceed" faults reported by the hardware */
-+ if (token & QTD_STS_HALT) {
-+ if (token & QTD_STS_BABBLE) {
-+ /* FIXME "must" disable babbling device's port too */
-+ status = -EOVERFLOW;
-+ /* CERR nonzero + halt --> stall */
-+ } else if (QTD_CERR(token)) {
-+ status = -EPIPE;
-+
-+ /* In theory, more than one of the following bits can be set
-+ * since they are sticky and the transaction is retried.
-+ * Which to test first is rather arbitrary.
-+ */
-+ } else if (token & QTD_STS_MMF) {
-+ /* fs/ls interrupt xfer missed the complete-split */
-+ status = -EPROTO;
-+ } else if (token & QTD_STS_DBE) {
-+ status = (QTD_PID(token) == 1) /* IN ? */
-+ ? -ENOSR /* hc couldn't read data */
-+ : -ECOMM; /* hc couldn't write data */
-+ } else if (token & QTD_STS_XACT) {
-+ /* timeout, bad CRC, wrong PID, etc */
-+ fotg210_dbg(fotg210, "devpath %s ep%d%s 3strikes\n",
-+ urb->dev->devpath,
-+ usb_pipeendpoint(urb->pipe),
-+ usb_pipein(urb->pipe) ? "in" : "out");
-+ status = -EPROTO;
-+ } else { /* unknown */
-+ status = -EPROTO;
-+ }
-+
-+ fotg210_dbg(fotg210,
-+ "dev%d ep%d%s qtd token %08x --> status %d\n",
-+ usb_pipedevice(urb->pipe),
-+ usb_pipeendpoint(urb->pipe),
-+ usb_pipein(urb->pipe) ? "in" : "out",
-+ token, status);
-+ }
-+
-+ return status;
-+}
-+
-+static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
-+ int status)
-+__releases(fotg210->lock)
-+__acquires(fotg210->lock)
-+{
-+ if (likely(urb->hcpriv != NULL)) {
-+ struct fotg210_qh *qh = (struct fotg210_qh *) urb->hcpriv;
-+
-+ /* S-mask in a QH means it's an interrupt urb */
-+ if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
-+
-+ /* ... update hc-wide periodic stats (for usbfs) */
-+ fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs--;
-+ }
-+ }
-+
-+ if (unlikely(urb->unlinked)) {
-+ INCR(fotg210->stats.unlink);
-+ } else {
-+ /* report non-error and short read status as zero */
-+ if (status == -EINPROGRESS || status == -EREMOTEIO)
-+ status = 0;
-+ INCR(fotg210->stats.complete);
-+ }
-+
-+#ifdef FOTG210_URB_TRACE
-+ fotg210_dbg(fotg210,
-+ "%s %s urb %p ep%d%s status %d len %d/%d\n",
-+ __func__, urb->dev->devpath, urb,
-+ usb_pipeendpoint(urb->pipe),
-+ usb_pipein(urb->pipe) ? "in" : "out",
-+ status,
-+ urb->actual_length, urb->transfer_buffer_length);
-+#endif
-+
-+ /* complete() can reenter this HCD */
-+ usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-+ spin_unlock(&fotg210->lock);
-+ usb_hcd_giveback_urb(fotg210_to_hcd(fotg210), urb, status);
-+ spin_lock(&fotg210->lock);
-+}
-+
-+static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
-+
-+/* Process and free completed qtds for a qh, returning URBs to drivers.
-+ * Chases up to qh->hw_current. Returns number of completions called,
-+ * indicating how much "real" work we did.
-+ */
-+static unsigned qh_completions(struct fotg210_hcd *fotg210,
-+ struct fotg210_qh *qh)
-+{
-+ struct fotg210_qtd *last, *end = qh->dummy;
-+ struct fotg210_qtd *qtd, *tmp;
-+ int last_status;
-+ int stopped;
-+ unsigned count = 0;
-+ u8 state;
-+ struct fotg210_qh_hw *hw = qh->hw;
-+
-+ if (unlikely(list_empty(&qh->qtd_list)))
-+ return count;
-+
-+ /* completions (or tasks on other cpus) must never clobber HALT
-+ * till we've gone through and cleaned everything up, even when
-+ * they add urbs to this qh's queue or mark them for unlinking.
-+ *
-+ * NOTE: unlinking expects to be done in queue order.
-+ *
-+ * It's a bug for qh->qh_state to be anything other than
-+ * QH_STATE_IDLE, unless our caller is scan_async() or
-+ * scan_intr().
-+ */
-+ state = qh->qh_state;
-+ qh->qh_state = QH_STATE_COMPLETING;
-+ stopped = (state == QH_STATE_IDLE);
-+
-+rescan:
-+ last = NULL;
-+ last_status = -EINPROGRESS;
-+ qh->needs_rescan = 0;
-+
-+ /* remove de-activated QTDs from front of queue.
-+ * after faults (including short reads), cleanup this urb
-+ * then let the queue advance.
-+ * if queue is stopped, handles unlinks.
-+ */
-+ list_for_each_entry_safe(qtd, tmp, &qh->qtd_list, qtd_list) {
-+ struct urb *urb;
-+ u32 token = 0;
-+
-+ urb = qtd->urb;
-+
-+ /* clean up any state from previous QTD ...*/
-+ if (last) {
-+ if (likely(last->urb != urb)) {
-+ fotg210_urb_done(fotg210, last->urb,
-+ last_status);
-+ count++;
-+ last_status = -EINPROGRESS;
-+ }
-+ fotg210_qtd_free(fotg210, last);
-+ last = NULL;
-+ }
-+
-+ /* ignore urbs submitted during completions we reported */
-+ if (qtd == end)
-+ break;
-+
-+ /* hardware copies qtd out of qh overlay */
-+ rmb();
-+ token = hc32_to_cpu(fotg210, qtd->hw_token);
-+
-+ /* always clean up qtds the hc de-activated */
-+retry_xacterr:
-+ if ((token & QTD_STS_ACTIVE) == 0) {
-+
-+ /* Report Data Buffer Error: non-fatal but useful */
-+ if (token & QTD_STS_DBE)
-+ fotg210_dbg(fotg210,
-+ "detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-+ urb, usb_endpoint_num(&urb->ep->desc),
-+ usb_endpoint_dir_in(&urb->ep->desc)
-+ ? "in" : "out",
-+ urb->transfer_buffer_length, qtd, qh);
-+
-+ /* on STALL, error, and short reads this urb must
-+ * complete and all its qtds must be recycled.
-+ */
-+ if ((token & QTD_STS_HALT) != 0) {
-+
-+ /* retry transaction errors until we
-+ * reach the software xacterr limit
-+ */
-+ if ((token & QTD_STS_XACT) &&
-+ QTD_CERR(token) == 0 &&
-+ ++qh->xacterrs < QH_XACTERR_MAX &&
-+ !urb->unlinked) {
-+ fotg210_dbg(fotg210,
-+ "detected XactErr len %zu/%zu retry %d\n",
-+ qtd->length - QTD_LENGTH(token),
-+ qtd->length,
-+ qh->xacterrs);
-+
-+ /* reset the token in the qtd and the
-+ * qh overlay (which still contains
-+ * the qtd) so that we pick up from
-+ * where we left off
-+ */
-+ token &= ~QTD_STS_HALT;
-+ token |= QTD_STS_ACTIVE |
-+ (FOTG210_TUNE_CERR << 10);
-+ qtd->hw_token = cpu_to_hc32(fotg210,
-+ token);
-+ wmb();
-+ hw->hw_token = cpu_to_hc32(fotg210,
-+ token);
-+ goto retry_xacterr;
-+ }
-+ stopped = 1;
-+
-+ /* magic dummy for some short reads; qh won't advance.
-+ * that silicon quirk can kick in with this dummy too.
-+ *
-+ * other short reads won't stop the queue, including
-+ * control transfers (status stage handles that) or
-+ * most other single-qtd reads ... the queue stops if
-+ * URB_SHORT_NOT_OK was set so the driver submitting
-+ * the urbs could clean it up.
-+ */
-+ } else if (IS_SHORT_READ(token) &&
-+ !(qtd->hw_alt_next &
-+ FOTG210_LIST_END(fotg210))) {
-+ stopped = 1;
-+ }
-+
-+ /* stop scanning when we reach qtds the hc is using */
-+ } else if (likely(!stopped
-+ && fotg210->rh_state >= FOTG210_RH_RUNNING)) {
-+ break;
-+
-+ /* scan the whole queue for unlinks whenever it stops */
-+ } else {
-+ stopped = 1;
-+
-+ /* cancel everything if we halt, suspend, etc */
-+ if (fotg210->rh_state < FOTG210_RH_RUNNING)
-+ last_status = -ESHUTDOWN;
-+
-+ /* this qtd is active; skip it unless a previous qtd
-+ * for its urb faulted, or its urb was canceled.
-+ */
-+ else if (last_status == -EINPROGRESS && !urb->unlinked)
-+ continue;
-+
-+ /* qh unlinked; token in overlay may be most current */
-+ if (state == QH_STATE_IDLE &&
-+ cpu_to_hc32(fotg210, qtd->qtd_dma)
-+ == hw->hw_current) {
-+ token = hc32_to_cpu(fotg210, hw->hw_token);
-+
-+ /* An unlink may leave an incomplete
-+ * async transaction in the TT buffer.
-+ * We have to clear it.
-+ */
-+ fotg210_clear_tt_buffer(fotg210, qh, urb,
-+ token);
-+ }
-+ }
-+
-+ /* unless we already know the urb's status, collect qtd status
-+ * and update count of bytes transferred. in common short read
-+ * cases with only one data qtd (including control transfers),
-+ * queue processing won't halt. but with two or more qtds (for
-+ * example, with a 32 KB transfer), when the first qtd gets a
-+ * short read the second must be removed by hand.
-+ */
-+ if (last_status == -EINPROGRESS) {
-+ last_status = qtd_copy_status(fotg210, urb,
-+ qtd->length, token);
-+ if (last_status == -EREMOTEIO &&
-+ (qtd->hw_alt_next &
-+ FOTG210_LIST_END(fotg210)))
-+ last_status = -EINPROGRESS;
-+
-+ /* As part of low/full-speed endpoint-halt processing
-+ * we must clear the TT buffer (11.17.5).
-+ */
-+ if (unlikely(last_status != -EINPROGRESS &&
-+ last_status != -EREMOTEIO)) {
-+ /* The TT's in some hubs malfunction when they
-+ * receive this request following a STALL (they
-+ * stop sending isochronous packets). Since a
-+ * STALL can't leave the TT buffer in a busy
-+ * state (if you believe Figures 11-48 - 11-51
-+ * in the USB 2.0 spec), we won't clear the TT
-+ * buffer in this case. Strictly speaking this
-+ * is a violation of the spec.
-+ */
-+ if (last_status != -EPIPE)
-+ fotg210_clear_tt_buffer(fotg210, qh,
-+ urb, token);
-+ }
-+ }
-+
-+ /* if we're removing something not at the queue head,
-+ * patch the hardware queue pointer.
-+ */
-+ if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
-+ last = list_entry(qtd->qtd_list.prev,
-+ struct fotg210_qtd, qtd_list);
-+ last->hw_next = qtd->hw_next;
-+ }
-+
-+ /* remove qtd; it's recycled after possible urb completion */
-+ list_del(&qtd->qtd_list);
-+ last = qtd;
-+
-+ /* reinit the xacterr counter for the next qtd */
-+ qh->xacterrs = 0;
-+ }
-+
-+ /* last urb's completion might still need calling */
-+ if (likely(last != NULL)) {
-+ fotg210_urb_done(fotg210, last->urb, last_status);
-+ count++;
-+ fotg210_qtd_free(fotg210, last);
-+ }
-+
-+ /* Do we need to rescan for URBs dequeued during a giveback? */
-+ if (unlikely(qh->needs_rescan)) {
-+ /* If the QH is already unlinked, do the rescan now. */
-+ if (state == QH_STATE_IDLE)
-+ goto rescan;
-+
-+ /* Otherwise we have to wait until the QH is fully unlinked.
-+ * Our caller will start an unlink if qh->needs_rescan is
-+ * set. But if an unlink has already started, nothing needs
-+ * to be done.
-+ */
-+ if (state != QH_STATE_LINKED)
-+ qh->needs_rescan = 0;
-+ }
-+
-+ /* restore original state; caller must unlink or relink */
-+ qh->qh_state = state;
-+
-+ /* be sure the hardware's done with the qh before refreshing
-+ * it after fault cleanup, or recovering from silicon wrongly
-+ * overlaying the dummy qtd (which reduces DMA chatter).
-+ */
-+ if (stopped != 0 || hw->hw_qtd_next == FOTG210_LIST_END(fotg210)) {
-+ switch (state) {
-+ case QH_STATE_IDLE:
-+ qh_refresh(fotg210, qh);
-+ break;
-+ case QH_STATE_LINKED:
-+ /* We won't refresh a QH that's linked (after the HC
-+ * stopped the queue). That avoids a race:
-+ * - HC reads first part of QH;
-+ * - CPU updates that first part and the token;
-+ * - HC reads rest of that QH, including token
-+ * Result: HC gets an inconsistent image, and then
-+ * DMAs to/from the wrong memory (corrupting it).
-+ *
-+ * That should be rare for interrupt transfers,
-+ * except maybe high bandwidth ...
-+ */
-+
-+ /* Tell the caller to start an unlink */
-+ qh->needs_rescan = 1;
-+ break;
-+ /* otherwise, unlink already started */
-+ }
-+ }
-+
-+ return count;
-+}
-+
-+/* reverse of qh_urb_transaction: free a list of TDs.
-+ * used for cleanup after errors, before HC sees an URB's TDs.
-+ */
-+static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
-+ struct list_head *head)
-+{
-+ struct fotg210_qtd *qtd, *temp;
-+
-+ list_for_each_entry_safe(qtd, temp, head, qtd_list) {
-+ list_del(&qtd->qtd_list);
-+ fotg210_qtd_free(fotg210, qtd);
-+ }
-+}
-+
-+/* create a list of filled qtds for this URB; won't link into qh.
-+ */
-+static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
-+ struct urb *urb, struct list_head *head, gfp_t flags)
-+{
-+ struct fotg210_qtd *qtd, *qtd_prev;
-+ dma_addr_t buf;
-+ int len, this_sg_len, maxpacket;
-+ int is_input;
-+ u32 token;
-+ int i;
-+ struct scatterlist *sg;
-+
-+ /*
-+ * URBs map to sequences of QTDs: one logical transaction
-+ */
-+ qtd = fotg210_qtd_alloc(fotg210, flags);
-+ if (unlikely(!qtd))
-+ return NULL;
-+ list_add_tail(&qtd->qtd_list, head);
-+ qtd->urb = urb;
-+
-+ token = QTD_STS_ACTIVE;
-+ token |= (FOTG210_TUNE_CERR << 10);
-+ /* for split transactions, SplitXState initialized to zero */
-+
-+ len = urb->transfer_buffer_length;
-+ is_input = usb_pipein(urb->pipe);
-+ if (usb_pipecontrol(urb->pipe)) {
-+ /* SETUP pid */
-+ qtd_fill(fotg210, qtd, urb->setup_dma,
-+ sizeof(struct usb_ctrlrequest),
-+ token | (2 /* "setup" */ << 8), 8);
-+
-+ /* ... and always at least one more pid */
-+ token ^= QTD_TOGGLE;
-+ qtd_prev = qtd;
-+ qtd = fotg210_qtd_alloc(fotg210, flags);
-+ if (unlikely(!qtd))
-+ goto cleanup;
-+ qtd->urb = urb;
-+ qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-+ list_add_tail(&qtd->qtd_list, head);
-+
-+ /* for zero length DATA stages, STATUS is always IN */
-+ if (len == 0)
-+ token |= (1 /* "in" */ << 8);
-+ }
-+
-+ /*
-+ * data transfer stage: buffer setup
-+ */
-+ i = urb->num_mapped_sgs;
-+ if (len > 0 && i > 0) {
-+ sg = urb->sg;
-+ buf = sg_dma_address(sg);
-+
-+ /* urb->transfer_buffer_length may be smaller than the
-+ * size of the scatterlist (or vice versa)
-+ */
-+ this_sg_len = min_t(int, sg_dma_len(sg), len);
-+ } else {
-+ sg = NULL;
-+ buf = urb->transfer_dma;
-+ this_sg_len = len;
-+ }
-+
-+ if (is_input)
-+ token |= (1 /* "in" */ << 8);
-+ /* else it's already initted to "out" pid (0 << 8) */
-+
-+ maxpacket = usb_maxpacket(urb->dev, urb->pipe);
-+
-+ /*
-+ * buffer gets wrapped in one or more qtds;
-+ * last one may be "short" (including zero len)
-+ * and may serve as a control status ack
-+ */
-+ for (;;) {
-+ int this_qtd_len;
-+
-+ this_qtd_len = qtd_fill(fotg210, qtd, buf, this_sg_len, token,
-+ maxpacket);
-+ this_sg_len -= this_qtd_len;
-+ len -= this_qtd_len;
-+ buf += this_qtd_len;
-+
-+ /*
-+ * short reads advance to a "magic" dummy instead of the next
-+ * qtd ... that forces the queue to stop, for manual cleanup.
-+ * (this will usually be overridden later.)
-+ */
-+ if (is_input)
-+ qtd->hw_alt_next = fotg210->async->hw->hw_alt_next;
-+
-+ /* qh makes control packets use qtd toggle; maybe switch it */
-+ if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
-+ token ^= QTD_TOGGLE;
-+
-+ if (likely(this_sg_len <= 0)) {
-+ if (--i <= 0 || len <= 0)
-+ break;
-+ sg = sg_next(sg);
-+ buf = sg_dma_address(sg);
-+ this_sg_len = min_t(int, sg_dma_len(sg), len);
-+ }
-+
-+ qtd_prev = qtd;
-+ qtd = fotg210_qtd_alloc(fotg210, flags);
-+ if (unlikely(!qtd))
-+ goto cleanup;
-+ qtd->urb = urb;
-+ qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-+ list_add_tail(&qtd->qtd_list, head);
-+ }
-+
-+ /*
-+ * unless the caller requires manual cleanup after short reads,
-+ * have the alt_next mechanism keep the queue running after the
-+ * last data qtd (the only one, for control and most other cases).
-+ */
-+ if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 ||
-+ usb_pipecontrol(urb->pipe)))
-+ qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
-+
-+ /*
-+ * control requests may need a terminating data "status" ack;
-+ * other OUT ones may need a terminating short packet
-+ * (zero length).
-+ */
-+ if (likely(urb->transfer_buffer_length != 0)) {
-+ int one_more = 0;
-+
-+ if (usb_pipecontrol(urb->pipe)) {
-+ one_more = 1;
-+ token ^= 0x0100; /* "in" <--> "out" */
-+ token |= QTD_TOGGLE; /* force DATA1 */
-+ } else if (usb_pipeout(urb->pipe)
-+ && (urb->transfer_flags & URB_ZERO_PACKET)
-+ && !(urb->transfer_buffer_length % maxpacket)) {
-+ one_more = 1;
-+ }
-+ if (one_more) {
-+ qtd_prev = qtd;
-+ qtd = fotg210_qtd_alloc(fotg210, flags);
-+ if (unlikely(!qtd))
-+ goto cleanup;
-+ qtd->urb = urb;
-+ qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-+ list_add_tail(&qtd->qtd_list, head);
-+
-+ /* never any data in such packets */
-+ qtd_fill(fotg210, qtd, 0, 0, token, 0);
-+ }
-+ }
-+
-+ /* by default, enable interrupt on urb completion */
-+ if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
-+ qtd->hw_token |= cpu_to_hc32(fotg210, QTD_IOC);
-+ return head;
-+
-+cleanup:
-+ qtd_list_free(fotg210, urb, head);
-+ return NULL;
-+}
-+
-+/* Would be best to create all qh's from config descriptors,
-+ * when each interface/altsetting is established. Unlink
-+ * any previous qh and cancel its urbs first; endpoints are
-+ * implicitly reset then (data toggle too).
-+ * That'd mean updating how usbcore talks to HCDs. (2.7?)
-+ */
-+
-+
-+/* Each QH holds a qtd list; a QH is used for everything except iso.
-+ *
-+ * For interrupt urbs, the scheduler must set the microframe scheduling
-+ * mask(s) each time the QH gets scheduled. For highspeed, that's
-+ * just one microframe in the s-mask. For split interrupt transactions
-+ * there are additional complications: c-mask, maybe FSTNs.
-+ */
-+static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
-+ gfp_t flags)
-+{
-+ struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags);
-+ struct usb_host_endpoint *ep;
-+ u32 info1 = 0, info2 = 0;
-+ int is_input, type;
-+ int maxp = 0;
-+ int mult;
-+ struct usb_tt *tt = urb->dev->tt;
-+ struct fotg210_qh_hw *hw;
-+
-+ if (!qh)
-+ return qh;
-+
-+ /*
-+ * init endpoint/device data for this QH
-+ */
-+ info1 |= usb_pipeendpoint(urb->pipe) << 8;
-+ info1 |= usb_pipedevice(urb->pipe) << 0;
-+
-+ is_input = usb_pipein(urb->pipe);
-+ type = usb_pipetype(urb->pipe);
-+ ep = usb_pipe_endpoint(urb->dev, urb->pipe);
-+ maxp = usb_endpoint_maxp(&ep->desc);
-+ mult = usb_endpoint_maxp_mult(&ep->desc);
-+
-+ /* 1024 byte maxpacket is a hardware ceiling. High bandwidth
-+ * acts like up to 3KB, but is built from smaller packets.
-+ */
-+ if (maxp > 1024) {
-+ fotg210_dbg(fotg210, "bogus qh maxpacket %d\n", maxp);
-+ goto done;
-+ }
-+
-+ /* Compute interrupt scheduling parameters just once, and save.
-+ * - allowing for high bandwidth, how many nsec/uframe are used?
-+ * - split transactions need a second CSPLIT uframe; same question
-+ * - splits also need a schedule gap (for full/low speed I/O)
-+ * - qh has a polling interval
-+ *
-+ * For control/bulk requests, the HC or TT handles these.
-+ */
-+ if (type == PIPE_INTERRUPT) {
-+ qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
-+ is_input, 0, mult * maxp));
-+ qh->start = NO_FRAME;
-+
-+ if (urb->dev->speed == USB_SPEED_HIGH) {
-+ qh->c_usecs = 0;
-+ qh->gap_uf = 0;
-+
-+ qh->period = urb->interval >> 3;
-+ if (qh->period == 0 && urb->interval != 1) {
-+ /* NOTE interval 2 or 4 uframes could work.
-+ * But interval 1 scheduling is simpler, and
-+ * includes high bandwidth.
-+ */
-+ urb->interval = 1;
-+ } else if (qh->period > fotg210->periodic_size) {
-+ qh->period = fotg210->periodic_size;
-+ urb->interval = qh->period << 3;
-+ }
-+ } else {
-+ int think_time;
-+
-+ /* gap is f(FS/LS transfer times) */
-+ qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed,
-+ is_input, 0, maxp) / (125 * 1000);
-+
-+ /* FIXME this just approximates SPLIT/CSPLIT times */
-+ if (is_input) { /* SPLIT, gap, CSPLIT+DATA */
-+ qh->c_usecs = qh->usecs + HS_USECS(0);
-+ qh->usecs = HS_USECS(1);
-+ } else { /* SPLIT+DATA, gap, CSPLIT */
-+ qh->usecs += HS_USECS(1);
-+ qh->c_usecs = HS_USECS(0);
-+ }
-+
-+ think_time = tt ? tt->think_time : 0;
-+ qh->tt_usecs = NS_TO_US(think_time +
-+ usb_calc_bus_time(urb->dev->speed,
-+ is_input, 0, maxp));
-+ qh->period = urb->interval;
-+ if (qh->period > fotg210->periodic_size) {
-+ qh->period = fotg210->periodic_size;
-+ urb->interval = qh->period;
-+ }
-+ }
-+ }
-+
-+ /* support for tt scheduling, and access to toggles */
-+ qh->dev = urb->dev;
-+
-+ /* using TT? */
-+ switch (urb->dev->speed) {
-+ case USB_SPEED_LOW:
-+ info1 |= QH_LOW_SPEED;
-+ fallthrough;
-+
-+ case USB_SPEED_FULL:
-+ /* EPS 0 means "full" */
-+ if (type != PIPE_INTERRUPT)
-+ info1 |= (FOTG210_TUNE_RL_TT << 28);
-+ if (type == PIPE_CONTROL) {
-+ info1 |= QH_CONTROL_EP; /* for TT */
-+ info1 |= QH_TOGGLE_CTL; /* toggle from qtd */
-+ }
-+ info1 |= maxp << 16;
-+
-+ info2 |= (FOTG210_TUNE_MULT_TT << 30);
-+
-+ /* Some Freescale processors have an erratum in which the
-+ * port number in the queue head was 0..N-1 instead of 1..N.
-+ */
-+ if (fotg210_has_fsl_portno_bug(fotg210))
-+ info2 |= (urb->dev->ttport-1) << 23;
-+ else
-+ info2 |= urb->dev->ttport << 23;
-+
-+ /* set the address of the TT; for TDI's integrated
-+ * root hub tt, leave it zeroed.
-+ */
-+ if (tt && tt->hub != fotg210_to_hcd(fotg210)->self.root_hub)
-+ info2 |= tt->hub->devnum << 16;
-+
-+ /* NOTE: if (PIPE_INTERRUPT) { scheduler sets c-mask } */
-+
-+ break;
-+
-+ case USB_SPEED_HIGH: /* no TT involved */
-+ info1 |= QH_HIGH_SPEED;
-+ if (type == PIPE_CONTROL) {
-+ info1 |= (FOTG210_TUNE_RL_HS << 28);
-+ info1 |= 64 << 16; /* usb2 fixed maxpacket */
-+ info1 |= QH_TOGGLE_CTL; /* toggle from qtd */
-+ info2 |= (FOTG210_TUNE_MULT_HS << 30);
-+ } else if (type == PIPE_BULK) {
-+ info1 |= (FOTG210_TUNE_RL_HS << 28);
-+ /* The USB spec says that high speed bulk endpoints
-+ * always use 512 byte maxpacket. But some device
-+ * vendors decided to ignore that, and MSFT is happy
-+ * to help them do so. So now people expect to use
-+ * such nonconformant devices with Linux too; sigh.
-+ */
-+ info1 |= maxp << 16;
-+ info2 |= (FOTG210_TUNE_MULT_HS << 30);
-+ } else { /* PIPE_INTERRUPT */
-+ info1 |= maxp << 16;
-+ info2 |= mult << 30;
-+ }
-+ break;
-+ default:
-+ fotg210_dbg(fotg210, "bogus dev %p speed %d\n", urb->dev,
-+ urb->dev->speed);
-+done:
-+ qh_destroy(fotg210, qh);
-+ return NULL;
-+ }
-+
-+ /* NOTE: if (PIPE_INTERRUPT) { scheduler sets s-mask } */
-+
-+ /* init as live, toggle clear, advance to dummy */
-+ qh->qh_state = QH_STATE_IDLE;
-+ hw = qh->hw;
-+ hw->hw_info1 = cpu_to_hc32(fotg210, info1);
-+ hw->hw_info2 = cpu_to_hc32(fotg210, info2);
-+ qh->is_out = !is_input;
-+ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, 1);
-+ qh_refresh(fotg210, qh);
-+ return qh;
-+}
-+
-+static void enable_async(struct fotg210_hcd *fotg210)
-+{
-+ if (fotg210->async_count++)
-+ return;
-+
-+ /* Stop waiting to turn off the async schedule */
-+ fotg210->enabled_hrtimer_events &= ~BIT(FOTG210_HRTIMER_DISABLE_ASYNC);
-+
-+ /* Don't start the schedule until ASS is 0 */
-+ fotg210_poll_ASS(fotg210);
-+ turn_on_io_watchdog(fotg210);
-+}
-+
-+static void disable_async(struct fotg210_hcd *fotg210)
-+{
-+ if (--fotg210->async_count)
-+ return;
-+
-+ /* The async schedule and async_unlink list are supposed to be empty */
-+ WARN_ON(fotg210->async->qh_next.qh || fotg210->async_unlink);
-+
-+ /* Don't turn off the schedule until ASS is 1 */
-+ fotg210_poll_ASS(fotg210);
-+}
-+
-+/* move qh (and its qtds) onto async queue; maybe enable queue. */
-+
-+static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-+{
-+ __hc32 dma = QH_NEXT(fotg210, qh->qh_dma);
-+ struct fotg210_qh *head;
-+
-+ /* Don't link a QH if there's a Clear-TT-Buffer pending */
-+ if (unlikely(qh->clearing_tt))
-+ return;
-+
-+ WARN_ON(qh->qh_state != QH_STATE_IDLE);
-+
-+ /* clear halt and/or toggle; and maybe recover from silicon quirk */
-+ qh_refresh(fotg210, qh);
-+
-+ /* splice right after start */
-+ head = fotg210->async;
-+ qh->qh_next = head->qh_next;
-+ qh->hw->hw_next = head->hw->hw_next;
-+ wmb();
-+
-+ head->qh_next.qh = qh;
-+ head->hw->hw_next = dma;
-+
-+ qh->xacterrs = 0;
-+ qh->qh_state = QH_STATE_LINKED;
-+ /* qtd completions reported later by interrupt */
-+
-+ enable_async(fotg210);
-+}
-+
-+/* For control/bulk/interrupt, return QH with these TDs appended.
-+ * Allocates and initializes the QH if necessary.
-+ * Returns null if it can't allocate a QH it needs to.
-+ * If the QH has TDs (urbs) already, that's great.
-+ */
-+static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
-+ struct urb *urb, struct list_head *qtd_list,
-+ int epnum, void **ptr)
-+{
-+ struct fotg210_qh *qh = NULL;
-+ __hc32 qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
-+
-+ qh = (struct fotg210_qh *) *ptr;
-+ if (unlikely(qh == NULL)) {
-+ /* can't sleep here, we have fotg210->lock... */
-+ qh = qh_make(fotg210, urb, GFP_ATOMIC);
-+ *ptr = qh;
-+ }
-+ if (likely(qh != NULL)) {
-+ struct fotg210_qtd *qtd;
-+
-+ if (unlikely(list_empty(qtd_list)))
-+ qtd = NULL;
-+ else
-+ qtd = list_entry(qtd_list->next, struct fotg210_qtd,
-+ qtd_list);
-+
-+ /* control qh may need patching ... */
-+ if (unlikely(epnum == 0)) {
-+ /* usb_reset_device() briefly reverts to address 0 */
-+ if (usb_pipedevice(urb->pipe) == 0)
-+ qh->hw->hw_info1 &= ~qh_addr_mask;
-+ }
-+
-+ /* just one way to queue requests: swap with the dummy qtd.
-+ * only hc or qh_refresh() ever modify the overlay.
-+ */
-+ if (likely(qtd != NULL)) {
-+ struct fotg210_qtd *dummy;
-+ dma_addr_t dma;
-+ __hc32 token;
-+
-+ /* to avoid racing the HC, use the dummy td instead of
-+ * the first td of our list (becomes new dummy). both
-+ * tds stay deactivated until we're done, when the
-+ * HC is allowed to fetch the old dummy (4.10.2).
-+ */
-+ token = qtd->hw_token;
-+ qtd->hw_token = HALT_BIT(fotg210);
-+
-+ dummy = qh->dummy;
-+
-+ dma = dummy->qtd_dma;
-+ *dummy = *qtd;
-+ dummy->qtd_dma = dma;
-+
-+ list_del(&qtd->qtd_list);
-+ list_add(&dummy->qtd_list, qtd_list);
-+ list_splice_tail(qtd_list, &qh->qtd_list);
-+
-+ fotg210_qtd_init(fotg210, qtd, qtd->qtd_dma);
-+ qh->dummy = qtd;
-+
-+ /* hc must see the new dummy at list end */
-+ dma = qtd->qtd_dma;
-+ qtd = list_entry(qh->qtd_list.prev,
-+ struct fotg210_qtd, qtd_list);
-+ qtd->hw_next = QTD_NEXT(fotg210, dma);
-+
-+ /* let the hc process these next qtds */
-+ wmb();
-+ dummy->hw_token = token;
-+
-+ urb->hcpriv = qh;
-+ }
-+ }
-+ return qh;
-+}
-+
-+static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
-+ struct list_head *qtd_list, gfp_t mem_flags)
-+{
-+ int epnum;
-+ unsigned long flags;
-+ struct fotg210_qh *qh = NULL;
-+ int rc;
-+
-+ epnum = urb->ep->desc.bEndpointAddress;
-+
-+#ifdef FOTG210_URB_TRACE
-+ {
-+ struct fotg210_qtd *qtd;
-+
-+ qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
-+ fotg210_dbg(fotg210,
-+ "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-+ __func__, urb->dev->devpath, urb,
-+ epnum & 0x0f, (epnum & USB_DIR_IN)
-+ ? "in" : "out",
-+ urb->transfer_buffer_length,
-+ qtd, urb->ep->hcpriv);
-+ }
-+#endif
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
-+ rc = -ESHUTDOWN;
-+ goto done;
-+ }
-+ rc = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
-+ if (unlikely(rc))
-+ goto done;
-+
-+ qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
-+ if (unlikely(qh == NULL)) {
-+ usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-+ rc = -ENOMEM;
-+ goto done;
-+ }
-+
-+ /* Control/bulk operations through TTs don't need scheduling,
-+ * the HC and TT handle it when the TT has a buffer ready.
-+ */
-+ if (likely(qh->qh_state == QH_STATE_IDLE))
-+ qh_link_async(fotg210, qh);
-+done:
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ if (unlikely(qh == NULL))
-+ qtd_list_free(fotg210, urb, qtd_list);
-+ return rc;
-+}
-+
-+static void single_unlink_async(struct fotg210_hcd *fotg210,
-+ struct fotg210_qh *qh)
-+{
-+ struct fotg210_qh *prev;
-+
-+ /* Add to the end of the list of QHs waiting for the next IAAD */
-+ qh->qh_state = QH_STATE_UNLINK;
-+ if (fotg210->async_unlink)
-+ fotg210->async_unlink_last->unlink_next = qh;
-+ else
-+ fotg210->async_unlink = qh;
-+ fotg210->async_unlink_last = qh;
-+
-+ /* Unlink it from the schedule */
-+ prev = fotg210->async;
-+ while (prev->qh_next.qh != qh)
-+ prev = prev->qh_next.qh;
-+
-+ prev->hw->hw_next = qh->hw->hw_next;
-+ prev->qh_next = qh->qh_next;
-+ if (fotg210->qh_scan_next == qh)
-+ fotg210->qh_scan_next = qh->qh_next.qh;
-+}
-+
-+static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
-+{
-+ /*
-+ * Do nothing if an IAA cycle is already running or
-+ * if one will be started shortly.
-+ */
-+ if (fotg210->async_iaa || fotg210->async_unlinking)
-+ return;
-+
-+ /* Do all the waiting QHs at once */
-+ fotg210->async_iaa = fotg210->async_unlink;
-+ fotg210->async_unlink = NULL;
-+
-+ /* If the controller isn't running, we don't have to wait for it */
-+ if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING)) {
-+ if (!nested) /* Avoid recursion */
-+ end_unlink_async(fotg210);
-+
-+ /* Otherwise start a new IAA cycle */
-+ } else if (likely(fotg210->rh_state == FOTG210_RH_RUNNING)) {
-+ /* Make sure the unlinks are all visible to the hardware */
-+ wmb();
-+
-+ fotg210_writel(fotg210, fotg210->command | CMD_IAAD,
-+ &fotg210->regs->command);
-+ fotg210_readl(fotg210, &fotg210->regs->command);
-+ fotg210_enable_event(fotg210, FOTG210_HRTIMER_IAA_WATCHDOG,
-+ true);
-+ }
-+}
-+
-+/* the async qh for the qtds being unlinked are now gone from the HC */
-+
-+static void end_unlink_async(struct fotg210_hcd *fotg210)
-+{
-+ struct fotg210_qh *qh;
-+
-+ /* Process the idle QHs */
-+restart:
-+ fotg210->async_unlinking = true;
-+ while (fotg210->async_iaa) {
-+ qh = fotg210->async_iaa;
-+ fotg210->async_iaa = qh->unlink_next;
-+ qh->unlink_next = NULL;
-+
-+ qh->qh_state = QH_STATE_IDLE;
-+ qh->qh_next.qh = NULL;
-+
-+ qh_completions(fotg210, qh);
-+ if (!list_empty(&qh->qtd_list) &&
-+ fotg210->rh_state == FOTG210_RH_RUNNING)
-+ qh_link_async(fotg210, qh);
-+ disable_async(fotg210);
-+ }
-+ fotg210->async_unlinking = false;
-+
-+ /* Start a new IAA cycle if any QHs are waiting for it */
-+ if (fotg210->async_unlink) {
-+ start_iaa_cycle(fotg210, true);
-+ if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING))
-+ goto restart;
-+ }
-+}
-+
-+static void unlink_empty_async(struct fotg210_hcd *fotg210)
-+{
-+ struct fotg210_qh *qh, *next;
-+ bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
-+ bool check_unlinks_later = false;
-+
-+ /* Unlink all the async QHs that have been empty for a timer cycle */
-+ next = fotg210->async->qh_next.qh;
-+ while (next) {
-+ qh = next;
-+ next = qh->qh_next.qh;
-+
-+ if (list_empty(&qh->qtd_list) &&
-+ qh->qh_state == QH_STATE_LINKED) {
-+ if (!stopped && qh->unlink_cycle ==
-+ fotg210->async_unlink_cycle)
-+ check_unlinks_later = true;
-+ else
-+ single_unlink_async(fotg210, qh);
-+ }
-+ }
-+
-+ /* Start a new IAA cycle if any QHs are waiting for it */
-+ if (fotg210->async_unlink)
-+ start_iaa_cycle(fotg210, false);
-+
-+ /* QHs that haven't been empty for long enough will be handled later */
-+ if (check_unlinks_later) {
-+ fotg210_enable_event(fotg210, FOTG210_HRTIMER_ASYNC_UNLINKS,
-+ true);
-+ ++fotg210->async_unlink_cycle;
-+ }
-+}
-+
-+/* makes sure the async qh will become idle */
-+/* caller must own fotg210->lock */
-+
-+static void start_unlink_async(struct fotg210_hcd *fotg210,
-+ struct fotg210_qh *qh)
-+{
-+ /*
-+ * If the QH isn't linked then there's nothing we can do
-+ * unless we were called during a giveback, in which case
-+ * qh_completions() has to deal with it.
-+ */
-+ if (qh->qh_state != QH_STATE_LINKED) {
-+ if (qh->qh_state == QH_STATE_COMPLETING)
-+ qh->needs_rescan = 1;
-+ return;
-+ }
-+
-+ single_unlink_async(fotg210, qh);
-+ start_iaa_cycle(fotg210, false);
-+}
-+
-+static void scan_async(struct fotg210_hcd *fotg210)
-+{
-+ struct fotg210_qh *qh;
-+ bool check_unlinks_later = false;
-+
-+ fotg210->qh_scan_next = fotg210->async->qh_next.qh;
-+ while (fotg210->qh_scan_next) {
-+ qh = fotg210->qh_scan_next;
-+ fotg210->qh_scan_next = qh->qh_next.qh;
-+rescan:
-+ /* clean any finished work for this qh */
-+ if (!list_empty(&qh->qtd_list)) {
-+ int temp;
-+
-+ /*
-+ * Unlinks could happen here; completion reporting
-+ * drops the lock. That's why fotg210->qh_scan_next
-+ * always holds the next qh to scan; if the next qh
-+ * gets unlinked then fotg210->qh_scan_next is adjusted
-+ * in single_unlink_async().
-+ */
-+ temp = qh_completions(fotg210, qh);
-+ if (qh->needs_rescan) {
-+ start_unlink_async(fotg210, qh);
-+ } else if (list_empty(&qh->qtd_list)
-+ && qh->qh_state == QH_STATE_LINKED) {
-+ qh->unlink_cycle = fotg210->async_unlink_cycle;
-+ check_unlinks_later = true;
-+ } else if (temp != 0)
-+ goto rescan;
-+ }
-+ }
-+
-+ /*
-+ * Unlink empty entries, reducing DMA usage as well
-+ * as HCD schedule-scanning costs. Delay for any qh
-+ * we just scanned, there's a not-unusual case that it
-+ * doesn't stay idle for long.
-+ */
-+ if (check_unlinks_later && fotg210->rh_state == FOTG210_RH_RUNNING &&
-+ !(fotg210->enabled_hrtimer_events &
-+ BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
-+ fotg210_enable_event(fotg210,
-+ FOTG210_HRTIMER_ASYNC_UNLINKS, true);
-+ ++fotg210->async_unlink_cycle;
-+ }
-+}
-+/* EHCI scheduled transaction support: interrupt, iso, split iso
-+ * These are called "periodic" transactions in the EHCI spec.
-+ *
-+ * Note that for interrupt transfers, the QH/QTD manipulation is shared
-+ * with the "asynchronous" transaction support (control/bulk transfers).
-+ * The only real difference is in how interrupt transfers are scheduled.
-+ *
-+ * For ISO, we make an "iso_stream" head to serve the same role as a QH.
-+ * It keeps track of every ITD (or SITD) that's linked, and holds enough
-+ * pre-calculated schedule data to make appending to the queue be quick.
-+ */
-+static int fotg210_get_frame(struct usb_hcd *hcd);
-+
-+/* periodic_next_shadow - return "next" pointer on shadow list
-+ * @periodic: host pointer to qh/itd
-+ * @tag: hardware tag for type of this record
-+ */
-+static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
-+ union fotg210_shadow *periodic, __hc32 tag)
-+{
-+ switch (hc32_to_cpu(fotg210, tag)) {
-+ case Q_TYPE_QH:
-+ return &periodic->qh->qh_next;
-+ case Q_TYPE_FSTN:
-+ return &periodic->fstn->fstn_next;
-+ default:
-+ return &periodic->itd->itd_next;
-+ }
-+}
-+
-+static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
-+ union fotg210_shadow *periodic, __hc32 tag)
-+{
-+ switch (hc32_to_cpu(fotg210, tag)) {
-+ /* our fotg210_shadow.qh is actually software part */
-+ case Q_TYPE_QH:
-+ return &periodic->qh->hw->hw_next;
-+ /* others are hw parts */
-+ default:
-+ return periodic->hw_next;
-+ }
-+}
-+
-+/* caller must hold fotg210->lock */
-+static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
-+ void *ptr)
-+{
-+ union fotg210_shadow *prev_p = &fotg210->pshadow[frame];
-+ __hc32 *hw_p = &fotg210->periodic[frame];
-+ union fotg210_shadow here = *prev_p;
-+
-+ /* find predecessor of "ptr"; hw and shadow lists are in sync */
-+ while (here.ptr && here.ptr != ptr) {
-+ prev_p = periodic_next_shadow(fotg210, prev_p,
-+ Q_NEXT_TYPE(fotg210, *hw_p));
-+ hw_p = shadow_next_periodic(fotg210, &here,
-+ Q_NEXT_TYPE(fotg210, *hw_p));
-+ here = *prev_p;
-+ }
-+ /* an interrupt entry (at list end) could have been shared */
-+ if (!here.ptr)
-+ return;
-+
-+ /* update shadow and hardware lists ... the old "next" pointers
-+ * from ptr may still be in use, the caller updates them.
-+ */
-+ *prev_p = *periodic_next_shadow(fotg210, &here,
-+ Q_NEXT_TYPE(fotg210, *hw_p));
-+
-+ *hw_p = *shadow_next_periodic(fotg210, &here,
-+ Q_NEXT_TYPE(fotg210, *hw_p));
-+}
-+
-+/* how many of the uframe's 125 usecs are allocated? */
-+static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
-+ unsigned frame, unsigned uframe)
-+{
-+ __hc32 *hw_p = &fotg210->periodic[frame];
-+ union fotg210_shadow *q = &fotg210->pshadow[frame];
-+ unsigned usecs = 0;
-+ struct fotg210_qh_hw *hw;
-+
-+ while (q->ptr) {
-+ switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
-+ case Q_TYPE_QH:
-+ hw = q->qh->hw;
-+ /* is it in the S-mask? */
-+ if (hw->hw_info2 & cpu_to_hc32(fotg210, 1 << uframe))
-+ usecs += q->qh->usecs;
-+ /* ... or C-mask? */
-+ if (hw->hw_info2 & cpu_to_hc32(fotg210,
-+ 1 << (8 + uframe)))
-+ usecs += q->qh->c_usecs;
-+ hw_p = &hw->hw_next;
-+ q = &q->qh->qh_next;
-+ break;
-+ /* case Q_TYPE_FSTN: */
-+ default:
-+ /* for "save place" FSTNs, count the relevant INTR
-+ * bandwidth from the previous frame
-+ */
-+ if (q->fstn->hw_prev != FOTG210_LIST_END(fotg210))
-+ fotg210_dbg(fotg210, "ignoring FSTN cost ...\n");
-+
-+ hw_p = &q->fstn->hw_next;
-+ q = &q->fstn->fstn_next;
-+ break;
-+ case Q_TYPE_ITD:
-+ if (q->itd->hw_transaction[uframe])
-+ usecs += q->itd->stream->usecs;
-+ hw_p = &q->itd->hw_next;
-+ q = &q->itd->itd_next;
-+ break;
-+ }
-+ }
-+ if (usecs > fotg210->uframe_periodic_max)
-+ fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",
-+ frame * 8 + uframe, usecs);
-+ return usecs;
-+}
-+
-+static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
-+{
-+ if (!dev1->tt || !dev2->tt)
-+ return 0;
-+ if (dev1->tt != dev2->tt)
-+ return 0;
-+ if (dev1->tt->multi)
-+ return dev1->ttport == dev2->ttport;
-+ else
-+ return 1;
-+}
-+
-+/* return true iff the device's transaction translator is available
-+ * for a periodic transfer starting at the specified frame, using
-+ * all the uframes in the mask.
-+ */
-+static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
-+ struct usb_device *dev, unsigned frame, u32 uf_mask)
-+{
-+ if (period == 0) /* error */
-+ return 0;
-+
-+ /* note bandwidth wastage: split never follows csplit
-+ * (different dev or endpoint) until the next uframe.
-+ * calling convention doesn't make that distinction.
-+ */
-+ for (; frame < fotg210->periodic_size; frame += period) {
-+ union fotg210_shadow here;
-+ __hc32 type;
-+ struct fotg210_qh_hw *hw;
-+
-+ here = fotg210->pshadow[frame];
-+ type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
-+ while (here.ptr) {
-+ switch (hc32_to_cpu(fotg210, type)) {
-+ case Q_TYPE_ITD:
-+ type = Q_NEXT_TYPE(fotg210, here.itd->hw_next);
-+ here = here.itd->itd_next;
-+ continue;
-+ case Q_TYPE_QH:
-+ hw = here.qh->hw;
-+ if (same_tt(dev, here.qh->dev)) {
-+ u32 mask;
-+
-+ mask = hc32_to_cpu(fotg210,
-+ hw->hw_info2);
-+ /* "knows" no gap is needed */
-+ mask |= mask >> 8;
-+ if (mask & uf_mask)
-+ break;
-+ }
-+ type = Q_NEXT_TYPE(fotg210, hw->hw_next);
-+ here = here.qh->qh_next;
-+ continue;
-+ /* case Q_TYPE_FSTN: */
-+ default:
-+ fotg210_dbg(fotg210,
-+ "periodic frame %d bogus type %d\n",
-+ frame, type);
-+ }
-+
-+ /* collision or error */
-+ return 0;
-+ }
-+ }
-+
-+ /* no collision */
-+ return 1;
-+}
-+
-+static void enable_periodic(struct fotg210_hcd *fotg210)
-+{
-+ if (fotg210->periodic_count++)
-+ return;
-+
-+ /* Stop waiting to turn off the periodic schedule */
-+ fotg210->enabled_hrtimer_events &=
-+ ~BIT(FOTG210_HRTIMER_DISABLE_PERIODIC);
-+
-+ /* Don't start the schedule until PSS is 0 */
-+ fotg210_poll_PSS(fotg210);
-+ turn_on_io_watchdog(fotg210);
-+}
-+
-+static void disable_periodic(struct fotg210_hcd *fotg210)
-+{
-+ if (--fotg210->periodic_count)
-+ return;
-+
-+ /* Don't turn off the schedule until PSS is 1 */
-+ fotg210_poll_PSS(fotg210);
-+}
-+
-+/* periodic schedule slots have iso tds (normal or split) first, then a
-+ * sparse tree for active interrupt transfers.
-+ *
-+ * this just links in a qh; caller guarantees uframe masks are set right.
-+ * no FSTN support (yet; fotg210 0.96+)
-+ */
-+static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-+{
-+ unsigned i;
-+ unsigned period = qh->period;
-+
-+ dev_dbg(&qh->dev->dev,
-+ "link qh%d-%04x/%p start %d [%d/%d us]\n", period,
-+ hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
-+ (QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
-+ qh->c_usecs);
-+
-+ /* high bandwidth, or otherwise every microframe */
-+ if (period == 0)
-+ period = 1;
-+
-+ for (i = qh->start; i < fotg210->periodic_size; i += period) {
-+ union fotg210_shadow *prev = &fotg210->pshadow[i];
-+ __hc32 *hw_p = &fotg210->periodic[i];
-+ union fotg210_shadow here = *prev;
-+ __hc32 type = 0;
-+
-+ /* skip the iso nodes at list head */
-+ while (here.ptr) {
-+ type = Q_NEXT_TYPE(fotg210, *hw_p);
-+ if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
-+ break;
-+ prev = periodic_next_shadow(fotg210, prev, type);
-+ hw_p = shadow_next_periodic(fotg210, &here, type);
-+ here = *prev;
-+ }
-+
-+ /* sorting each branch by period (slow-->fast)
-+ * enables sharing interior tree nodes
-+ */
-+ while (here.ptr && qh != here.qh) {
-+ if (qh->period > here.qh->period)
-+ break;
-+ prev = &here.qh->qh_next;
-+ hw_p = &here.qh->hw->hw_next;
-+ here = *prev;
-+ }
-+ /* link in this qh, unless some earlier pass did that */
-+ if (qh != here.qh) {
-+ qh->qh_next = here;
-+ if (here.qh)
-+ qh->hw->hw_next = *hw_p;
-+ wmb();
-+ prev->qh = qh;
-+ *hw_p = QH_NEXT(fotg210, qh->qh_dma);
-+ }
-+ }
-+ qh->qh_state = QH_STATE_LINKED;
-+ qh->xacterrs = 0;
-+
-+ /* update per-qh bandwidth for usbfs */
-+ fotg210_to_hcd(fotg210)->self.bandwidth_allocated += qh->period
-+ ? ((qh->usecs + qh->c_usecs) / qh->period)
-+ : (qh->usecs * 8);
-+
-+ list_add(&qh->intr_node, &fotg210->intr_qh_list);
-+
-+ /* maybe enable periodic schedule processing */
-+ ++fotg210->intr_count;
-+ enable_periodic(fotg210);
-+}
-+
-+static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
-+ struct fotg210_qh *qh)
-+{
-+ unsigned i;
-+ unsigned period;
-+
-+ /*
-+ * If qh is for a low/full-speed device, simply unlinking it
-+ * could interfere with an ongoing split transaction. To unlink
-+ * it safely would require setting the QH_INACTIVATE bit and
-+ * waiting at least one frame, as described in EHCI 4.12.2.5.
-+ *
-+ * We won't bother with any of this. Instead, we assume that the
-+ * only reason for unlinking an interrupt QH while the current URB
-+ * is still active is to dequeue all the URBs (flush the whole
-+ * endpoint queue).
-+ *
-+ * If rebalancing the periodic schedule is ever implemented, this
-+ * approach will no longer be valid.
-+ */
-+
-+ /* high bandwidth, or otherwise part of every microframe */
-+ period = qh->period;
-+ if (!period)
-+ period = 1;
-+
-+ for (i = qh->start; i < fotg210->periodic_size; i += period)
-+ periodic_unlink(fotg210, i, qh);
-+
-+ /* update per-qh bandwidth for usbfs */
-+ fotg210_to_hcd(fotg210)->self.bandwidth_allocated -= qh->period
-+ ? ((qh->usecs + qh->c_usecs) / qh->period)
-+ : (qh->usecs * 8);
-+
-+ dev_dbg(&qh->dev->dev,
-+ "unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-+ qh->period, hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
-+ (QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
-+ qh->c_usecs);
-+
-+ /* qh->qh_next still "live" to HC */
-+ qh->qh_state = QH_STATE_UNLINK;
-+ qh->qh_next.ptr = NULL;
-+
-+ if (fotg210->qh_scan_next == qh)
-+ fotg210->qh_scan_next = list_entry(qh->intr_node.next,
-+ struct fotg210_qh, intr_node);
-+ list_del(&qh->intr_node);
-+}
-+
-+static void start_unlink_intr(struct fotg210_hcd *fotg210,
-+ struct fotg210_qh *qh)
-+{
-+ /* If the QH isn't linked then there's nothing we can do
-+ * unless we were called during a giveback, in which case
-+ * qh_completions() has to deal with it.
-+ */
-+ if (qh->qh_state != QH_STATE_LINKED) {
-+ if (qh->qh_state == QH_STATE_COMPLETING)
-+ qh->needs_rescan = 1;
-+ return;
-+ }
-+
-+ qh_unlink_periodic(fotg210, qh);
-+
-+ /* Make sure the unlinks are visible before starting the timer */
-+ wmb();
-+
-+ /*
-+ * The EHCI spec doesn't say how long it takes the controller to
-+ * stop accessing an unlinked interrupt QH. The timer delay is
-+ * 9 uframes; presumably that will be long enough.
-+ */
-+ qh->unlink_cycle = fotg210->intr_unlink_cycle;
-+
-+ /* New entries go at the end of the intr_unlink list */
-+ if (fotg210->intr_unlink)
-+ fotg210->intr_unlink_last->unlink_next = qh;
-+ else
-+ fotg210->intr_unlink = qh;
-+ fotg210->intr_unlink_last = qh;
-+
-+ if (fotg210->intr_unlinking)
-+ ; /* Avoid recursive calls */
-+ else if (fotg210->rh_state < FOTG210_RH_RUNNING)
-+ fotg210_handle_intr_unlinks(fotg210);
-+ else if (fotg210->intr_unlink == qh) {
-+ fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-+ true);
-+ ++fotg210->intr_unlink_cycle;
-+ }
-+}
-+
-+static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-+{
-+ struct fotg210_qh_hw *hw = qh->hw;
-+ int rc;
-+
-+ qh->qh_state = QH_STATE_IDLE;
-+ hw->hw_next = FOTG210_LIST_END(fotg210);
-+
-+ qh_completions(fotg210, qh);
-+
-+ /* reschedule QH iff another request is queued */
-+ if (!list_empty(&qh->qtd_list) &&
-+ fotg210->rh_state == FOTG210_RH_RUNNING) {
-+ rc = qh_schedule(fotg210, qh);
-+
-+ /* An error here likely indicates handshake failure
-+ * or no space left in the schedule. Neither fault
-+ * should happen often ...
-+ *
-+ * FIXME kill the now-dysfunctional queued urbs
-+ */
-+ if (rc != 0)
-+ fotg210_err(fotg210, "can't reschedule qh %p, err %d\n",
-+ qh, rc);
-+ }
-+
-+ /* maybe turn off periodic schedule */
-+ --fotg210->intr_count;
-+ disable_periodic(fotg210);
-+}
-+
-+static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
-+ unsigned uframe, unsigned period, unsigned usecs)
-+{
-+ int claimed;
-+
-+ /* complete split running into next frame?
-+ * given FSTN support, we could sometimes check...
-+ */
-+ if (uframe >= 8)
-+ return 0;
-+
-+ /* convert "usecs we need" to "max already claimed" */
-+ usecs = fotg210->uframe_periodic_max - usecs;
-+
-+ /* we "know" 2 and 4 uframe intervals were rejected; so
-+ * for period 0, check _every_ microframe in the schedule.
-+ */
-+ if (unlikely(period == 0)) {
-+ do {
-+ for (uframe = 0; uframe < 7; uframe++) {
-+ claimed = periodic_usecs(fotg210, frame,
-+ uframe);
-+ if (claimed > usecs)
-+ return 0;
-+ }
-+ } while ((frame += 1) < fotg210->periodic_size);
-+
-+ /* just check the specified uframe, at that period */
-+ } else {
-+ do {
-+ claimed = periodic_usecs(fotg210, frame, uframe);
-+ if (claimed > usecs)
-+ return 0;
-+ } while ((frame += period) < fotg210->periodic_size);
-+ }
-+
-+ /* success! */
-+ return 1;
-+}
-+
-+static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
-+ unsigned uframe, const struct fotg210_qh *qh, __hc32 *c_maskp)
-+{
-+ int retval = -ENOSPC;
-+ u8 mask = 0;
-+
-+ if (qh->c_usecs && uframe >= 6) /* FSTN territory? */
-+ goto done;
-+
-+ if (!check_period(fotg210, frame, uframe, qh->period, qh->usecs))
-+ goto done;
-+ if (!qh->c_usecs) {
-+ retval = 0;
-+ *c_maskp = 0;
-+ goto done;
-+ }
-+
-+ /* Make sure this tt's buffer is also available for CSPLITs.
-+ * We pessimize a bit; probably the typical full speed case
-+ * doesn't need the second CSPLIT.
-+ *
-+ * NOTE: both SPLIT and CSPLIT could be checked in just
-+ * one smart pass...
-+ */
-+ mask = 0x03 << (uframe + qh->gap_uf);
-+ *c_maskp = cpu_to_hc32(fotg210, mask << 8);
-+
-+ mask |= 1 << uframe;
-+ if (tt_no_collision(fotg210, qh->period, qh->dev, frame, mask)) {
-+ if (!check_period(fotg210, frame, uframe + qh->gap_uf + 1,
-+ qh->period, qh->c_usecs))
-+ goto done;
-+ if (!check_period(fotg210, frame, uframe + qh->gap_uf,
-+ qh->period, qh->c_usecs))
-+ goto done;
-+ retval = 0;
-+ }
-+done:
-+ return retval;
-+}
-+
-+/* "first fit" scheduling policy used the first time through,
-+ * or when the previous schedule slot can't be re-used.
-+ */
-+static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-+{
-+ int status;
-+ unsigned uframe;
-+ __hc32 c_mask;
-+ unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */
-+ struct fotg210_qh_hw *hw = qh->hw;
-+
-+ qh_refresh(fotg210, qh);
-+ hw->hw_next = FOTG210_LIST_END(fotg210);
-+ frame = qh->start;
-+
-+ /* reuse the previous schedule slots, if we can */
-+ if (frame < qh->period) {
-+ uframe = ffs(hc32_to_cpup(fotg210, &hw->hw_info2) & QH_SMASK);
-+ status = check_intr_schedule(fotg210, frame, --uframe,
-+ qh, &c_mask);
-+ } else {
-+ uframe = 0;
-+ c_mask = 0;
-+ status = -ENOSPC;
-+ }
-+
-+ /* else scan the schedule to find a group of slots such that all
-+ * uframes have enough periodic bandwidth available.
-+ */
-+ if (status) {
-+ /* "normal" case, uframing flexible except with splits */
-+ if (qh->period) {
-+ int i;
-+
-+ for (i = qh->period; status && i > 0; --i) {
-+ frame = ++fotg210->random_frame % qh->period;
-+ for (uframe = 0; uframe < 8; uframe++) {
-+ status = check_intr_schedule(fotg210,
-+ frame, uframe, qh,
-+ &c_mask);
-+ if (status == 0)
-+ break;
-+ }
-+ }
-+
-+ /* qh->period == 0 means every uframe */
-+ } else {
-+ frame = 0;
-+ status = check_intr_schedule(fotg210, 0, 0, qh,
-+ &c_mask);
-+ }
-+ if (status)
-+ goto done;
-+ qh->start = frame;
-+
-+ /* reset S-frame and (maybe) C-frame masks */
-+ hw->hw_info2 &= cpu_to_hc32(fotg210, ~(QH_CMASK | QH_SMASK));
-+ hw->hw_info2 |= qh->period
-+ ? cpu_to_hc32(fotg210, 1 << uframe)
-+ : cpu_to_hc32(fotg210, QH_SMASK);
-+ hw->hw_info2 |= c_mask;
-+ } else
-+ fotg210_dbg(fotg210, "reused qh %p schedule\n", qh);
-+
-+ /* stuff into the periodic schedule */
-+ qh_link_periodic(fotg210, qh);
-+done:
-+ return status;
-+}
-+
-+static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-+ struct list_head *qtd_list, gfp_t mem_flags)
-+{
-+ unsigned epnum;
-+ unsigned long flags;
-+ struct fotg210_qh *qh;
-+ int status;
-+ struct list_head empty;
-+
-+ /* get endpoint and transfer/schedule data */
-+ epnum = urb->ep->desc.bEndpointAddress;
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+
-+ if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
-+ status = -ESHUTDOWN;
-+ goto done_not_linked;
-+ }
-+ status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
-+ if (unlikely(status))
-+ goto done_not_linked;
-+
-+ /* get qh and force any scheduling errors */
-+ INIT_LIST_HEAD(&empty);
-+ qh = qh_append_tds(fotg210, urb, &empty, epnum, &urb->ep->hcpriv);
-+ if (qh == NULL) {
-+ status = -ENOMEM;
-+ goto done;
-+ }
-+ if (qh->qh_state == QH_STATE_IDLE) {
-+ status = qh_schedule(fotg210, qh);
-+ if (status)
-+ goto done;
-+ }
-+
-+ /* then queue the urb's tds to the qh */
-+ qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
-+ BUG_ON(qh == NULL);
-+
-+ /* ... update usbfs periodic stats */
-+ fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs++;
-+
-+done:
-+ if (unlikely(status))
-+ usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-+done_not_linked:
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ if (status)
-+ qtd_list_free(fotg210, urb, qtd_list);
-+
-+ return status;
-+}
-+
-+static void scan_intr(struct fotg210_hcd *fotg210)
-+{
-+ struct fotg210_qh *qh;
-+
-+ list_for_each_entry_safe(qh, fotg210->qh_scan_next,
-+ &fotg210->intr_qh_list, intr_node) {
-+rescan:
-+ /* clean any finished work for this qh */
-+ if (!list_empty(&qh->qtd_list)) {
-+ int temp;
-+
-+ /*
-+ * Unlinks could happen here; completion reporting
-+ * drops the lock. That's why fotg210->qh_scan_next
-+ * always holds the next qh to scan; if the next qh
-+ * gets unlinked then fotg210->qh_scan_next is adjusted
-+ * in qh_unlink_periodic().
-+ */
-+ temp = qh_completions(fotg210, qh);
-+ if (unlikely(qh->needs_rescan ||
-+ (list_empty(&qh->qtd_list) &&
-+ qh->qh_state == QH_STATE_LINKED)))
-+ start_unlink_intr(fotg210, qh);
-+ else if (temp != 0)
-+ goto rescan;
-+ }
-+ }
-+}
-+
-+/* fotg210_iso_stream ops work with both ITD and SITD */
-+
-+static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
-+{
-+ struct fotg210_iso_stream *stream;
-+
-+ stream = kzalloc(sizeof(*stream), mem_flags);
-+ if (likely(stream != NULL)) {
-+ INIT_LIST_HEAD(&stream->td_list);
-+ INIT_LIST_HEAD(&stream->free_list);
-+ stream->next_uframe = -1;
-+ }
-+ return stream;
-+}
-+
-+static void iso_stream_init(struct fotg210_hcd *fotg210,
-+ struct fotg210_iso_stream *stream, struct usb_device *dev,
-+ int pipe, unsigned interval)
-+{
-+ u32 buf1;
-+ unsigned epnum, maxp;
-+ int is_input;
-+ long bandwidth;
-+ unsigned multi;
-+ struct usb_host_endpoint *ep;
-+
-+ /*
-+ * this might be a "high bandwidth" highspeed endpoint,
-+ * as encoded in the ep descriptor's wMaxPacket field
-+ */
-+ epnum = usb_pipeendpoint(pipe);
-+ is_input = usb_pipein(pipe) ? USB_DIR_IN : 0;
-+ ep = usb_pipe_endpoint(dev, pipe);
-+ maxp = usb_endpoint_maxp(&ep->desc);
-+ if (is_input)
-+ buf1 = (1 << 11);
-+ else
-+ buf1 = 0;
-+
-+ multi = usb_endpoint_maxp_mult(&ep->desc);
-+ buf1 |= maxp;
-+ maxp *= multi;
-+
-+ stream->buf0 = cpu_to_hc32(fotg210, (epnum << 8) | dev->devnum);
-+ stream->buf1 = cpu_to_hc32(fotg210, buf1);
-+ stream->buf2 = cpu_to_hc32(fotg210, multi);
-+
-+ /* usbfs wants to report the average usecs per frame tied up
-+ * when transfers on this endpoint are scheduled ...
-+ */
-+ if (dev->speed == USB_SPEED_FULL) {
-+ interval <<= 3;
-+ stream->usecs = NS_TO_US(usb_calc_bus_time(dev->speed,
-+ is_input, 1, maxp));
-+ stream->usecs /= 8;
-+ } else {
-+ stream->highspeed = 1;
-+ stream->usecs = HS_USECS_ISO(maxp);
-+ }
-+ bandwidth = stream->usecs * 8;
-+ bandwidth /= interval;
-+
-+ stream->bandwidth = bandwidth;
-+ stream->udev = dev;
-+ stream->bEndpointAddress = is_input | epnum;
-+ stream->interval = interval;
-+ stream->maxp = maxp;
-+}
-+
-+static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
-+ struct urb *urb)
-+{
-+ unsigned epnum;
-+ struct fotg210_iso_stream *stream;
-+ struct usb_host_endpoint *ep;
-+ unsigned long flags;
-+
-+ epnum = usb_pipeendpoint(urb->pipe);
-+ if (usb_pipein(urb->pipe))
-+ ep = urb->dev->ep_in[epnum];
-+ else
-+ ep = urb->dev->ep_out[epnum];
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ stream = ep->hcpriv;
-+
-+ if (unlikely(stream == NULL)) {
-+ stream = iso_stream_alloc(GFP_ATOMIC);
-+ if (likely(stream != NULL)) {
-+ ep->hcpriv = stream;
-+ stream->ep = ep;
-+ iso_stream_init(fotg210, stream, urb->dev, urb->pipe,
-+ urb->interval);
-+ }
-+
-+ /* if dev->ep[epnum] is a QH, hw is set */
-+ } else if (unlikely(stream->hw != NULL)) {
-+ fotg210_dbg(fotg210, "dev %s ep%d%s, not iso??\n",
-+ urb->dev->devpath, epnum,
-+ usb_pipein(urb->pipe) ? "in" : "out");
-+ stream = NULL;
-+ }
-+
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ return stream;
-+}
-+
-+/* fotg210_iso_sched ops can be ITD-only or SITD-only */
-+
-+static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
-+ gfp_t mem_flags)
-+{
-+ struct fotg210_iso_sched *iso_sched;
-+
-+ iso_sched = kzalloc(struct_size(iso_sched, packet, packets), mem_flags);
-+ if (likely(iso_sched != NULL))
-+ INIT_LIST_HEAD(&iso_sched->td_list);
-+
-+ return iso_sched;
-+}
-+
-+static inline void itd_sched_init(struct fotg210_hcd *fotg210,
-+ struct fotg210_iso_sched *iso_sched,
-+ struct fotg210_iso_stream *stream, struct urb *urb)
-+{
-+ unsigned i;
-+ dma_addr_t dma = urb->transfer_dma;
-+
-+ /* how many uframes are needed for these transfers */
-+ iso_sched->span = urb->number_of_packets * stream->interval;
-+
-+ /* figure out per-uframe itd fields that we'll need later
-+ * when we fit new itds into the schedule.
-+ */
-+ for (i = 0; i < urb->number_of_packets; i++) {
-+ struct fotg210_iso_packet *uframe = &iso_sched->packet[i];
-+ unsigned length;
-+ dma_addr_t buf;
-+ u32 trans;
-+
-+ length = urb->iso_frame_desc[i].length;
-+ buf = dma + urb->iso_frame_desc[i].offset;
-+
-+ trans = FOTG210_ISOC_ACTIVE;
-+ trans |= buf & 0x0fff;
-+ if (unlikely(((i + 1) == urb->number_of_packets))
-+ && !(urb->transfer_flags & URB_NO_INTERRUPT))
-+ trans |= FOTG210_ITD_IOC;
-+ trans |= length << 16;
-+ uframe->transaction = cpu_to_hc32(fotg210, trans);
-+
-+ /* might need to cross a buffer page within a uframe */
-+ uframe->bufp = (buf & ~(u64)0x0fff);
-+ buf += length;
-+ if (unlikely((uframe->bufp != (buf & ~(u64)0x0fff))))
-+ uframe->cross = 1;
-+ }
-+}
-+
-+static void iso_sched_free(struct fotg210_iso_stream *stream,
-+ struct fotg210_iso_sched *iso_sched)
-+{
-+ if (!iso_sched)
-+ return;
-+ /* caller must hold fotg210->lock!*/
-+ list_splice(&iso_sched->td_list, &stream->free_list);
-+ kfree(iso_sched);
-+}
-+
-+static int itd_urb_transaction(struct fotg210_iso_stream *stream,
-+ struct fotg210_hcd *fotg210, struct urb *urb, gfp_t mem_flags)
-+{
-+ struct fotg210_itd *itd;
-+ dma_addr_t itd_dma;
-+ int i;
-+ unsigned num_itds;
-+ struct fotg210_iso_sched *sched;
-+ unsigned long flags;
-+
-+ sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
-+ if (unlikely(sched == NULL))
-+ return -ENOMEM;
-+
-+ itd_sched_init(fotg210, sched, stream, urb);
-+
-+ if (urb->interval < 8)
-+ num_itds = 1 + (sched->span + 7) / 8;
-+ else
-+ num_itds = urb->number_of_packets;
-+
-+ /* allocate/init ITDs */
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ for (i = 0; i < num_itds; i++) {
-+
-+ /*
-+ * Use iTDs from the free list, but not iTDs that may
-+ * still be in use by the hardware.
-+ */
-+ if (likely(!list_empty(&stream->free_list))) {
-+ itd = list_first_entry(&stream->free_list,
-+ struct fotg210_itd, itd_list);
-+ if (itd->frame == fotg210->now_frame)
-+ goto alloc_itd;
-+ list_del(&itd->itd_list);
-+ itd_dma = itd->itd_dma;
-+ } else {
-+alloc_itd:
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
-+ &itd_dma);
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ if (!itd) {
-+ iso_sched_free(stream, sched);
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ return -ENOMEM;
-+ }
-+ }
-+
-+ memset(itd, 0, sizeof(*itd));
-+ itd->itd_dma = itd_dma;
-+ list_add(&itd->itd_list, &sched->td_list);
-+ }
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+
-+ /* temporarily store schedule info in hcpriv */
-+ urb->hcpriv = sched;
-+ urb->error_count = 0;
-+ return 0;
-+}
-+
-+static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
-+ u8 usecs, u32 period)
-+{
-+ uframe %= period;
-+ do {
-+ /* can't commit more than uframe_periodic_max usec */
-+ if (periodic_usecs(fotg210, uframe >> 3, uframe & 0x7)
-+ > (fotg210->uframe_periodic_max - usecs))
-+ return 0;
-+
-+ /* we know urb->interval is 2^N uframes */
-+ uframe += period;
-+ } while (uframe < mod);
-+ return 1;
-+}
-+
-+/* This scheduler plans almost as far into the future as it has actual
-+ * periodic schedule slots. (Affected by TUNE_FLS, which defaults to
-+ * "as small as possible" to be cache-friendlier.) That limits the size
-+ * transfers you can stream reliably; avoid more than 64 msec per urb.
-+ * Also avoid queue depths of less than fotg210's worst irq latency (affected
-+ * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
-+ * and other factors); or more than about 230 msec total (for portability,
-+ * given FOTG210_TUNE_FLS and the slop). Or, write a smarter scheduler!
-+ */
-+
-+#define SCHEDULE_SLOP 80 /* microframes */
-+
-+static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
-+ struct fotg210_iso_stream *stream)
-+{
-+ u32 now, next, start, period, span;
-+ int status;
-+ unsigned mod = fotg210->periodic_size << 3;
-+ struct fotg210_iso_sched *sched = urb->hcpriv;
-+
-+ period = urb->interval;
-+ span = sched->span;
-+
-+ if (span > mod - SCHEDULE_SLOP) {
-+ fotg210_dbg(fotg210, "iso request %p too long\n", urb);
-+ status = -EFBIG;
-+ goto fail;
-+ }
-+
-+ now = fotg210_read_frame_index(fotg210) & (mod - 1);
-+
-+ /* Typical case: reuse current schedule, stream is still active.
-+ * Hopefully there are no gaps from the host falling behind
-+ * (irq delays etc), but if there are we'll take the next
-+ * slot in the schedule, implicitly assuming URB_ISO_ASAP.
-+ */
-+ if (likely(!list_empty(&stream->td_list))) {
-+ u32 excess;
-+
-+ /* For high speed devices, allow scheduling within the
-+ * isochronous scheduling threshold. For full speed devices
-+ * and Intel PCI-based controllers, don't (work around for
-+ * Intel ICH9 bug).
-+ */
-+ if (!stream->highspeed && fotg210->fs_i_thresh)
-+ next = now + fotg210->i_thresh;
-+ else
-+ next = now;
-+
-+ /* Fell behind (by up to twice the slop amount)?
-+ * We decide based on the time of the last currently-scheduled
-+ * slot, not the time of the next available slot.
-+ */
-+ excess = (stream->next_uframe - period - next) & (mod - 1);
-+ if (excess >= mod - 2 * SCHEDULE_SLOP)
-+ start = next + excess - mod + period *
-+ DIV_ROUND_UP(mod - excess, period);
-+ else
-+ start = next + excess + period;
-+ if (start - now >= mod) {
-+ fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
-+ urb, start - now - period, period,
-+ mod);
-+ status = -EFBIG;
-+ goto fail;
-+ }
-+ }
-+
-+ /* need to schedule; when's the next (u)frame we could start?
-+ * this is bigger than fotg210->i_thresh allows; scheduling itself
-+ * isn't free, the slop should handle reasonably slow cpus. it
-+ * can also help high bandwidth if the dma and irq loads don't
-+ * jump until after the queue is primed.
-+ */
-+ else {
-+ int done = 0;
-+
-+ start = SCHEDULE_SLOP + (now & ~0x07);
-+
-+ /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
-+
-+ /* find a uframe slot with enough bandwidth.
-+ * Early uframes are more precious because full-speed
-+ * iso IN transfers can't use late uframes,
-+ * and therefore they should be allocated last.
-+ */
-+ next = start;
-+ start += period;
-+ do {
-+ start--;
-+ /* check schedule: enough space? */
-+ if (itd_slot_ok(fotg210, mod, start,
-+ stream->usecs, period))
-+ done = 1;
-+ } while (start > next && !done);
-+
-+ /* no room in the schedule */
-+ if (!done) {
-+ fotg210_dbg(fotg210, "iso resched full %p (now %d max %d)\n",
-+ urb, now, now + mod);
-+ status = -ENOSPC;
-+ goto fail;
-+ }
-+ }
-+
-+ /* Tried to schedule too far into the future? */
-+ if (unlikely(start - now + span - period >=
-+ mod - 2 * SCHEDULE_SLOP)) {
-+ fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
-+ urb, start - now, span - period,
-+ mod - 2 * SCHEDULE_SLOP);
-+ status = -EFBIG;
-+ goto fail;
-+ }
-+
-+ stream->next_uframe = start & (mod - 1);
-+
-+ /* report high speed start in uframes; full speed, in frames */
-+ urb->start_frame = stream->next_uframe;
-+ if (!stream->highspeed)
-+ urb->start_frame >>= 3;
-+
-+ /* Make sure scan_isoc() sees these */
-+ if (fotg210->isoc_count == 0)
-+ fotg210->next_frame = now >> 3;
-+ return 0;
-+
-+fail:
-+ iso_sched_free(stream, sched);
-+ urb->hcpriv = NULL;
-+ return status;
-+}
-+
-+static inline void itd_init(struct fotg210_hcd *fotg210,
-+ struct fotg210_iso_stream *stream, struct fotg210_itd *itd)
-+{
-+ int i;
-+
-+ /* it's been recently zeroed */
-+ itd->hw_next = FOTG210_LIST_END(fotg210);
-+ itd->hw_bufp[0] = stream->buf0;
-+ itd->hw_bufp[1] = stream->buf1;
-+ itd->hw_bufp[2] = stream->buf2;
-+
-+ for (i = 0; i < 8; i++)
-+ itd->index[i] = -1;
-+
-+ /* All other fields are filled when scheduling */
-+}
-+
-+static inline void itd_patch(struct fotg210_hcd *fotg210,
-+ struct fotg210_itd *itd, struct fotg210_iso_sched *iso_sched,
-+ unsigned index, u16 uframe)
-+{
-+ struct fotg210_iso_packet *uf = &iso_sched->packet[index];
-+ unsigned pg = itd->pg;
-+
-+ uframe &= 0x07;
-+ itd->index[uframe] = index;
-+
-+ itd->hw_transaction[uframe] = uf->transaction;
-+ itd->hw_transaction[uframe] |= cpu_to_hc32(fotg210, pg << 12);
-+ itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, uf->bufp & ~(u32)0);
-+ itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(uf->bufp >> 32));
-+
-+ /* iso_frame_desc[].offset must be strictly increasing */
-+ if (unlikely(uf->cross)) {
-+ u64 bufp = uf->bufp + 4096;
-+
-+ itd->pg = ++pg;
-+ itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
-+ itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(bufp >> 32));
-+ }
-+}
-+
-+static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
-+ struct fotg210_itd *itd)
-+{
-+ union fotg210_shadow *prev = &fotg210->pshadow[frame];
-+ __hc32 *hw_p = &fotg210->periodic[frame];
-+ union fotg210_shadow here = *prev;
-+ __hc32 type = 0;
-+
-+ /* skip any iso nodes which might belong to previous microframes */
-+ while (here.ptr) {
-+ type = Q_NEXT_TYPE(fotg210, *hw_p);
-+ if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
-+ break;
-+ prev = periodic_next_shadow(fotg210, prev, type);
-+ hw_p = shadow_next_periodic(fotg210, &here, type);
-+ here = *prev;
-+ }
-+
-+ itd->itd_next = here;
-+ itd->hw_next = *hw_p;
-+ prev->itd = itd;
-+ itd->frame = frame;
-+ wmb();
-+ *hw_p = cpu_to_hc32(fotg210, itd->itd_dma | Q_TYPE_ITD);
-+}
-+
-+/* fit urb's itds into the selected schedule slot; activate as needed */
-+static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
-+ unsigned mod, struct fotg210_iso_stream *stream)
-+{
-+ int packet;
-+ unsigned next_uframe, uframe, frame;
-+ struct fotg210_iso_sched *iso_sched = urb->hcpriv;
-+ struct fotg210_itd *itd;
-+
-+ next_uframe = stream->next_uframe & (mod - 1);
-+
-+ if (unlikely(list_empty(&stream->td_list))) {
-+ fotg210_to_hcd(fotg210)->self.bandwidth_allocated
-+ += stream->bandwidth;
-+ fotg210_dbg(fotg210,
-+ "schedule devp %s ep%d%s-iso period %d start %d.%d\n",
-+ urb->dev->devpath, stream->bEndpointAddress & 0x0f,
-+ (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
-+ urb->interval,
-+ next_uframe >> 3, next_uframe & 0x7);
-+ }
-+
-+ /* fill iTDs uframe by uframe */
-+ for (packet = 0, itd = NULL; packet < urb->number_of_packets;) {
-+ if (itd == NULL) {
-+ /* ASSERT: we have all necessary itds */
-+
-+ /* ASSERT: no itds for this endpoint in this uframe */
-+
-+ itd = list_entry(iso_sched->td_list.next,
-+ struct fotg210_itd, itd_list);
-+ list_move_tail(&itd->itd_list, &stream->td_list);
-+ itd->stream = stream;
-+ itd->urb = urb;
-+ itd_init(fotg210, stream, itd);
-+ }
-+
-+ uframe = next_uframe & 0x07;
-+ frame = next_uframe >> 3;
-+
-+ itd_patch(fotg210, itd, iso_sched, packet, uframe);
-+
-+ next_uframe += stream->interval;
-+ next_uframe &= mod - 1;
-+ packet++;
-+
-+ /* link completed itds into the schedule */
-+ if (((next_uframe >> 3) != frame)
-+ || packet == urb->number_of_packets) {
-+ itd_link(fotg210, frame & (fotg210->periodic_size - 1),
-+ itd);
-+ itd = NULL;
-+ }
-+ }
-+ stream->next_uframe = next_uframe;
-+
-+ /* don't need that schedule data any more */
-+ iso_sched_free(stream, iso_sched);
-+ urb->hcpriv = NULL;
-+
-+ ++fotg210->isoc_count;
-+ enable_periodic(fotg210);
-+}
-+
-+#define ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
-+ FOTG210_ISOC_XACTERR)
-+
-+/* Process and recycle a completed ITD. Return true iff its urb completed,
-+ * and hence its completion callback probably added things to the hardware
-+ * schedule.
-+ *
-+ * Note that we carefully avoid recycling this descriptor until after any
-+ * completion callback runs, so that it won't be reused quickly. That is,
-+ * assuming (a) no more than two urbs per frame on this endpoint, and also
-+ * (b) only this endpoint's completions submit URBs. It seems some silicon
-+ * corrupts things if you reuse completed descriptors very quickly...
-+ */
-+static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
-+{
-+ struct urb *urb = itd->urb;
-+ struct usb_iso_packet_descriptor *desc;
-+ u32 t;
-+ unsigned uframe;
-+ int urb_index = -1;
-+ struct fotg210_iso_stream *stream = itd->stream;
-+ struct usb_device *dev;
-+ bool retval = false;
-+
-+ /* for each uframe with a packet */
-+ for (uframe = 0; uframe < 8; uframe++) {
-+ if (likely(itd->index[uframe] == -1))
-+ continue;
-+ urb_index = itd->index[uframe];
-+ desc = &urb->iso_frame_desc[urb_index];
-+
-+ t = hc32_to_cpup(fotg210, &itd->hw_transaction[uframe]);
-+ itd->hw_transaction[uframe] = 0;
-+
-+ /* report transfer status */
-+ if (unlikely(t & ISO_ERRS)) {
-+ urb->error_count++;
-+ if (t & FOTG210_ISOC_BUF_ERR)
-+ desc->status = usb_pipein(urb->pipe)
-+ ? -ENOSR /* hc couldn't read */
-+ : -ECOMM; /* hc couldn't write */
-+ else if (t & FOTG210_ISOC_BABBLE)
-+ desc->status = -EOVERFLOW;
-+ else /* (t & FOTG210_ISOC_XACTERR) */
-+ desc->status = -EPROTO;
-+
-+ /* HC need not update length with this error */
-+ if (!(t & FOTG210_ISOC_BABBLE)) {
-+ desc->actual_length = FOTG210_ITD_LENGTH(t);
-+ urb->actual_length += desc->actual_length;
-+ }
-+ } else if (likely((t & FOTG210_ISOC_ACTIVE) == 0)) {
-+ desc->status = 0;
-+ desc->actual_length = FOTG210_ITD_LENGTH(t);
-+ urb->actual_length += desc->actual_length;
-+ } else {
-+ /* URB was too late */
-+ desc->status = -EXDEV;
-+ }
-+ }
-+
-+ /* handle completion now? */
-+ if (likely((urb_index + 1) != urb->number_of_packets))
-+ goto done;
-+
-+ /* ASSERT: it's really the last itd for this urb
-+ * list_for_each_entry (itd, &stream->td_list, itd_list)
-+ * BUG_ON (itd->urb == urb);
-+ */
-+
-+ /* give urb back to the driver; completion often (re)submits */
-+ dev = urb->dev;
-+ fotg210_urb_done(fotg210, urb, 0);
-+ retval = true;
-+ urb = NULL;
-+
-+ --fotg210->isoc_count;
-+ disable_periodic(fotg210);
-+
-+ if (unlikely(list_is_singular(&stream->td_list))) {
-+ fotg210_to_hcd(fotg210)->self.bandwidth_allocated
-+ -= stream->bandwidth;
-+ fotg210_dbg(fotg210,
-+ "deschedule devp %s ep%d%s-iso\n",
-+ dev->devpath, stream->bEndpointAddress & 0x0f,
-+ (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
-+ }
-+
-+done:
-+ itd->urb = NULL;
-+
-+ /* Add to the end of the free list for later reuse */
-+ list_move_tail(&itd->itd_list, &stream->free_list);
-+
-+ /* Recycle the iTDs when the pipeline is empty (ep no longer in use) */
-+ if (list_empty(&stream->td_list)) {
-+ list_splice_tail_init(&stream->free_list,
-+ &fotg210->cached_itd_list);
-+ start_free_itds(fotg210);
-+ }
-+
-+ return retval;
-+}
-+
-+static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-+ gfp_t mem_flags)
-+{
-+ int status = -EINVAL;
-+ unsigned long flags;
-+ struct fotg210_iso_stream *stream;
-+
-+ /* Get iso_stream head */
-+ stream = iso_stream_find(fotg210, urb);
-+ if (unlikely(stream == NULL)) {
-+ fotg210_dbg(fotg210, "can't get iso stream\n");
-+ return -ENOMEM;
-+ }
-+ if (unlikely(urb->interval != stream->interval &&
-+ fotg210_port_speed(fotg210, 0) ==
-+ USB_PORT_STAT_HIGH_SPEED)) {
-+ fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
-+ stream->interval, urb->interval);
-+ goto done;
-+ }
-+
-+#ifdef FOTG210_URB_TRACE
-+ fotg210_dbg(fotg210,
-+ "%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
-+ __func__, urb->dev->devpath, urb,
-+ usb_pipeendpoint(urb->pipe),
-+ usb_pipein(urb->pipe) ? "in" : "out",
-+ urb->transfer_buffer_length,
-+ urb->number_of_packets, urb->interval,
-+ stream);
-+#endif
-+
-+ /* allocate ITDs w/o locking anything */
-+ status = itd_urb_transaction(stream, fotg210, urb, mem_flags);
-+ if (unlikely(status < 0)) {
-+ fotg210_dbg(fotg210, "can't init itds\n");
-+ goto done;
-+ }
-+
-+ /* schedule ... need to lock */
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
-+ status = -ESHUTDOWN;
-+ goto done_not_linked;
-+ }
-+ status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
-+ if (unlikely(status))
-+ goto done_not_linked;
-+ status = iso_stream_schedule(fotg210, urb, stream);
-+ if (likely(status == 0))
-+ itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
-+ else
-+ usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-+done_not_linked:
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+done:
-+ return status;
-+}
-+
-+static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
-+ unsigned now_frame, bool live)
-+{
-+ unsigned uf;
-+ bool modified;
-+ union fotg210_shadow q, *q_p;
-+ __hc32 type, *hw_p;
-+
-+ /* scan each element in frame's queue for completions */
-+ q_p = &fotg210->pshadow[frame];
-+ hw_p = &fotg210->periodic[frame];
-+ q.ptr = q_p->ptr;
-+ type = Q_NEXT_TYPE(fotg210, *hw_p);
-+ modified = false;
-+
-+ while (q.ptr) {
-+ switch (hc32_to_cpu(fotg210, type)) {
-+ case Q_TYPE_ITD:
-+ /* If this ITD is still active, leave it for
-+ * later processing ... check the next entry.
-+ * No need to check for activity unless the
-+ * frame is current.
-+ */
-+ if (frame == now_frame && live) {
-+ rmb();
-+ for (uf = 0; uf < 8; uf++) {
-+ if (q.itd->hw_transaction[uf] &
-+ ITD_ACTIVE(fotg210))
-+ break;
-+ }
-+ if (uf < 8) {
-+ q_p = &q.itd->itd_next;
-+ hw_p = &q.itd->hw_next;
-+ type = Q_NEXT_TYPE(fotg210,
-+ q.itd->hw_next);
-+ q = *q_p;
-+ break;
-+ }
-+ }
-+
-+ /* Take finished ITDs out of the schedule
-+ * and process them: recycle, maybe report
-+ * URB completion. HC won't cache the
-+ * pointer for much longer, if at all.
-+ */
-+ *q_p = q.itd->itd_next;
-+ *hw_p = q.itd->hw_next;
-+ type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
-+ wmb();
-+ modified = itd_complete(fotg210, q.itd);
-+ q = *q_p;
-+ break;
-+ default:
-+ fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
-+ type, frame, q.ptr);
-+ fallthrough;
-+ case Q_TYPE_QH:
-+ case Q_TYPE_FSTN:
-+ /* End of the iTDs and siTDs */
-+ q.ptr = NULL;
-+ break;
-+ }
-+
-+ /* assume completion callbacks modify the queue */
-+ if (unlikely(modified && fotg210->isoc_count > 0))
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+static void scan_isoc(struct fotg210_hcd *fotg210)
-+{
-+ unsigned uf, now_frame, frame, ret;
-+ unsigned fmask = fotg210->periodic_size - 1;
-+ bool live;
-+
-+ /*
-+ * When running, scan from last scan point up to "now"
-+ * else clean up by scanning everything that's left.
-+ * Touches as few pages as possible: cache-friendly.
-+ */
-+ if (fotg210->rh_state >= FOTG210_RH_RUNNING) {
-+ uf = fotg210_read_frame_index(fotg210);
-+ now_frame = (uf >> 3) & fmask;
-+ live = true;
-+ } else {
-+ now_frame = (fotg210->next_frame - 1) & fmask;
-+ live = false;
-+ }
-+ fotg210->now_frame = now_frame;
-+
-+ frame = fotg210->next_frame;
-+ for (;;) {
-+ ret = 1;
-+ while (ret != 0)
-+ ret = scan_frame_queue(fotg210, frame,
-+ now_frame, live);
-+
-+ /* Stop when we have reached the current frame */
-+ if (frame == now_frame)
-+ break;
-+ frame = (frame + 1) & fmask;
-+ }
-+ fotg210->next_frame = now_frame;
-+}
-+
-+/* Display / Set uframe_periodic_max
-+ */
-+static ssize_t uframe_periodic_max_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct fotg210_hcd *fotg210;
-+ int n;
-+
-+ fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
-+ n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
-+ return n;
-+}
-+
-+
-+static ssize_t uframe_periodic_max_store(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct fotg210_hcd *fotg210;
-+ unsigned uframe_periodic_max;
-+ unsigned frame, uframe;
-+ unsigned short allocated_max;
-+ unsigned long flags;
-+ ssize_t ret;
-+
-+ fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
-+ if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
-+ return -EINVAL;
-+
-+ if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
-+ fotg210_info(fotg210, "rejecting invalid request for uframe_periodic_max=%u\n",
-+ uframe_periodic_max);
-+ return -EINVAL;
-+ }
-+
-+ ret = -EINVAL;
-+
-+ /*
-+ * lock, so that our checking does not race with possible periodic
-+ * bandwidth allocation through submitting new urbs.
-+ */
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+
-+ /*
-+ * for request to decrease max periodic bandwidth, we have to check
-+ * every microframe in the schedule to see whether the decrease is
-+ * possible.
-+ */
-+ if (uframe_periodic_max < fotg210->uframe_periodic_max) {
-+ allocated_max = 0;
-+
-+ for (frame = 0; frame < fotg210->periodic_size; ++frame)
-+ for (uframe = 0; uframe < 7; ++uframe)
-+ allocated_max = max(allocated_max,
-+ periodic_usecs(fotg210, frame,
-+ uframe));
-+
-+ if (allocated_max > uframe_periodic_max) {
-+ fotg210_info(fotg210,
-+ "cannot decrease uframe_periodic_max because periodic bandwidth is already allocated (%u > %u)\n",
-+ allocated_max, uframe_periodic_max);
-+ goto out_unlock;
-+ }
-+ }
-+
-+ /* increasing is always ok */
-+
-+ fotg210_info(fotg210,
-+ "setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
-+ 100 * uframe_periodic_max/125, uframe_periodic_max);
-+
-+ if (uframe_periodic_max != 100)
-+ fotg210_warn(fotg210, "max periodic bandwidth set is non-standard\n");
-+
-+ fotg210->uframe_periodic_max = uframe_periodic_max;
-+ ret = count;
-+
-+out_unlock:
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ return ret;
-+}
-+
-+static DEVICE_ATTR_RW(uframe_periodic_max);
-+
-+static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
-+{
-+ struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
-+
-+ return device_create_file(controller, &dev_attr_uframe_periodic_max);
-+}
-+
-+static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
-+{
-+ struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
-+
-+ device_remove_file(controller, &dev_attr_uframe_periodic_max);
-+}
-+/* On some systems, leaving remote wakeup enabled prevents system shutdown.
-+ * The firmware seems to think that powering off is a wakeup event!
-+ * This routine turns off remote wakeup and everything else, on all ports.
-+ */
-+static void fotg210_turn_off_all_ports(struct fotg210_hcd *fotg210)
-+{
-+ u32 __iomem *status_reg = &fotg210->regs->port_status;
-+
-+ fotg210_writel(fotg210, PORT_RWC_BITS, status_reg);
-+}
-+
-+/* Halt HC, turn off all ports, and let the BIOS use the companion controllers.
-+ * Must be called with interrupts enabled and the lock not held.
-+ */
-+static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
-+{
-+ fotg210_halt(fotg210);
-+
-+ spin_lock_irq(&fotg210->lock);
-+ fotg210->rh_state = FOTG210_RH_HALTED;
-+ fotg210_turn_off_all_ports(fotg210);
-+ spin_unlock_irq(&fotg210->lock);
-+}
-+
-+/* fotg210_shutdown kick in for silicon on any bus (not just pci, etc).
-+ * This forcibly disables dma and IRQs, helping kexec and other cases
-+ * where the next system software may expect clean state.
-+ */
-+static void fotg210_shutdown(struct usb_hcd *hcd)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+
-+ spin_lock_irq(&fotg210->lock);
-+ fotg210->shutdown = true;
-+ fotg210->rh_state = FOTG210_RH_STOPPING;
-+ fotg210->enabled_hrtimer_events = 0;
-+ spin_unlock_irq(&fotg210->lock);
-+
-+ fotg210_silence_controller(fotg210);
-+
-+ hrtimer_cancel(&fotg210->hrtimer);
-+}
-+
-+/* fotg210_work is called from some interrupts, timers, and so on.
-+ * it calls driver completion functions, after dropping fotg210->lock.
-+ */
-+static void fotg210_work(struct fotg210_hcd *fotg210)
-+{
-+ /* another CPU may drop fotg210->lock during a schedule scan while
-+ * it reports urb completions. this flag guards against bogus
-+ * attempts at re-entrant schedule scanning.
-+ */
-+ if (fotg210->scanning) {
-+ fotg210->need_rescan = true;
-+ return;
-+ }
-+ fotg210->scanning = true;
-+
-+rescan:
-+ fotg210->need_rescan = false;
-+ if (fotg210->async_count)
-+ scan_async(fotg210);
-+ if (fotg210->intr_count > 0)
-+ scan_intr(fotg210);
-+ if (fotg210->isoc_count > 0)
-+ scan_isoc(fotg210);
-+ if (fotg210->need_rescan)
-+ goto rescan;
-+ fotg210->scanning = false;
-+
-+ /* the IO watchdog guards against hardware or driver bugs that
-+ * misplace IRQs, and should let us run completely without IRQs.
-+ * such lossage has been observed on both VT6202 and VT8235.
-+ */
-+ turn_on_io_watchdog(fotg210);
-+}
-+
-+/* Called when the fotg210_hcd module is removed.
-+ */
-+static void fotg210_stop(struct usb_hcd *hcd)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+
-+ fotg210_dbg(fotg210, "stop\n");
-+
-+ /* no more interrupts ... */
-+
-+ spin_lock_irq(&fotg210->lock);
-+ fotg210->enabled_hrtimer_events = 0;
-+ spin_unlock_irq(&fotg210->lock);
-+
-+ fotg210_quiesce(fotg210);
-+ fotg210_silence_controller(fotg210);
-+ fotg210_reset(fotg210);
-+
-+ hrtimer_cancel(&fotg210->hrtimer);
-+ remove_sysfs_files(fotg210);
-+ remove_debug_files(fotg210);
-+
-+ /* root hub is shut down separately (first, when possible) */
-+ spin_lock_irq(&fotg210->lock);
-+ end_free_itds(fotg210);
-+ spin_unlock_irq(&fotg210->lock);
-+ fotg210_mem_cleanup(fotg210);
-+
-+#ifdef FOTG210_STATS
-+ fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-+ fotg210->stats.normal, fotg210->stats.error,
-+ fotg210->stats.iaa, fotg210->stats.lost_iaa);
-+ fotg210_dbg(fotg210, "complete %ld unlink %ld\n",
-+ fotg210->stats.complete, fotg210->stats.unlink);
-+#endif
-+
-+ dbg_status(fotg210, "fotg210_stop completed",
-+ fotg210_readl(fotg210, &fotg210->regs->status));
-+}
-+
-+/* one-time init, only for memory state */
-+static int hcd_fotg210_init(struct usb_hcd *hcd)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ u32 temp;
-+ int retval;
-+ u32 hcc_params;
-+ struct fotg210_qh_hw *hw;
-+
-+ spin_lock_init(&fotg210->lock);
-+
-+ /*
-+ * keep io watchdog by default, those good HCDs could turn off it later
-+ */
-+ fotg210->need_io_watchdog = 1;
-+
-+ hrtimer_init(&fotg210->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-+ fotg210->hrtimer.function = fotg210_hrtimer_func;
-+ fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
-+
-+ hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
-+
-+ /*
-+ * by default set standard 80% (== 100 usec/uframe) max periodic
-+ * bandwidth as required by USB 2.0
-+ */
-+ fotg210->uframe_periodic_max = 100;
-+
-+ /*
-+ * hw default: 1K periodic list heads, one per frame.
-+ * periodic_size can shrink by USBCMD update if hcc_params allows.
-+ */
-+ fotg210->periodic_size = DEFAULT_I_TDPS;
-+ INIT_LIST_HEAD(&fotg210->intr_qh_list);
-+ INIT_LIST_HEAD(&fotg210->cached_itd_list);
-+
-+ if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-+ /* periodic schedule size can be smaller than default */
-+ switch (FOTG210_TUNE_FLS) {
-+ case 0:
-+ fotg210->periodic_size = 1024;
-+ break;
-+ case 1:
-+ fotg210->periodic_size = 512;
-+ break;
-+ case 2:
-+ fotg210->periodic_size = 256;
-+ break;
-+ default:
-+ BUG();
-+ }
-+ }
-+ retval = fotg210_mem_init(fotg210, GFP_KERNEL);
-+ if (retval < 0)
-+ return retval;
-+
-+ /* controllers may cache some of the periodic schedule ... */
-+ fotg210->i_thresh = 2;
-+
-+ /*
-+ * dedicate a qh for the async ring head, since we couldn't unlink
-+ * a 'real' qh without stopping the async schedule [4.8]. use it
-+ * as the 'reclamation list head' too.
-+ * its dummy is used in hw_alt_next of many tds, to prevent the qh
-+ * from automatically advancing to the next td after short reads.
-+ */
-+ fotg210->async->qh_next.qh = NULL;
-+ hw = fotg210->async->hw;
-+ hw->hw_next = QH_NEXT(fotg210, fotg210->async->qh_dma);
-+ hw->hw_info1 = cpu_to_hc32(fotg210, QH_HEAD);
-+ hw->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
-+ hw->hw_qtd_next = FOTG210_LIST_END(fotg210);
-+ fotg210->async->qh_state = QH_STATE_LINKED;
-+ hw->hw_alt_next = QTD_NEXT(fotg210, fotg210->async->dummy->qtd_dma);
-+
-+ /* clear interrupt enables, set irq latency */
-+ if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
-+ log2_irq_thresh = 0;
-+ temp = 1 << (16 + log2_irq_thresh);
-+ if (HCC_CANPARK(hcc_params)) {
-+ /* HW default park == 3, on hardware that supports it (like
-+ * NVidia and ALI silicon), maximizes throughput on the async
-+ * schedule by avoiding QH fetches between transfers.
-+ *
-+ * With fast usb storage devices and NForce2, "park" seems to
-+ * make problems: throughput reduction (!), data errors...
-+ */
-+ if (park) {
-+ park = min_t(unsigned, park, 3);
-+ temp |= CMD_PARK;
-+ temp |= park << 8;
-+ }
-+ fotg210_dbg(fotg210, "park %d\n", park);
-+ }
-+ if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-+ /* periodic schedule size can be smaller than default */
-+ temp &= ~(3 << 2);
-+ temp |= (FOTG210_TUNE_FLS << 2);
-+ }
-+ fotg210->command = temp;
-+
-+ /* Accept arbitrarily long scatter-gather lists */
-+ if (!hcd->localmem_pool)
-+ hcd->self.sg_tablesize = ~0;
-+ return 0;
-+}
-+
-+/* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
-+static int fotg210_run(struct usb_hcd *hcd)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ u32 temp;
-+
-+ hcd->uses_new_polling = 1;
-+
-+ /* EHCI spec section 4.1 */
-+
-+ fotg210_writel(fotg210, fotg210->periodic_dma,
-+ &fotg210->regs->frame_list);
-+ fotg210_writel(fotg210, (u32)fotg210->async->qh_dma,
-+ &fotg210->regs->async_next);
-+
-+ /*
-+ * hcc_params controls whether fotg210->regs->segment must (!!!)
-+ * be used; it constrains QH/ITD/SITD and QTD locations.
-+ * dma_pool consistent memory always uses segment zero.
-+ * streaming mappings for I/O buffers, like dma_map_single(),
-+ * can return segments above 4GB, if the device allows.
-+ *
-+ * NOTE: the dma mask is visible through dev->dma_mask, so
-+ * drivers can pass this info along ... like NETIF_F_HIGHDMA,
-+ * Scsi_Host.highmem_io, and so forth. It's readonly to all
-+ * host side drivers though.
-+ */
-+ fotg210_readl(fotg210, &fotg210->caps->hcc_params);
-+
-+ /*
-+ * Philips, Intel, and maybe others need CMD_RUN before the
-+ * root hub will detect new devices (why?); NEC doesn't
-+ */
-+ fotg210->command &= ~(CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
-+ fotg210->command |= CMD_RUN;
-+ fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-+ dbg_cmd(fotg210, "init", fotg210->command);
-+
-+ /*
-+ * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
-+ * are explicitly handed to companion controller(s), so no TT is
-+ * involved with the root hub. (Except where one is integrated,
-+ * and there's no companion controller unless maybe for USB OTG.)
-+ *
-+ * Turning on the CF flag will transfer ownership of all ports
-+ * from the companions to the EHCI controller. If any of the
-+ * companions are in the middle of a port reset at the time, it
-+ * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
-+ * guarantees that no resets are in progress. After we set CF,
-+ * a short delay lets the hardware catch up; new resets shouldn't
-+ * be started before the port switching actions could complete.
-+ */
-+ down_write(&ehci_cf_port_reset_rwsem);
-+ fotg210->rh_state = FOTG210_RH_RUNNING;
-+ /* unblock posted writes */
-+ fotg210_readl(fotg210, &fotg210->regs->command);
-+ usleep_range(5000, 10000);
-+ up_write(&ehci_cf_port_reset_rwsem);
-+ fotg210->last_periodic_enable = ktime_get_real();
-+
-+ temp = HC_VERSION(fotg210,
-+ fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
-+ fotg210_info(fotg210,
-+ "USB %x.%x started, EHCI %x.%02x\n",
-+ ((fotg210->sbrn & 0xf0) >> 4), (fotg210->sbrn & 0x0f),
-+ temp >> 8, temp & 0xff);
-+
-+ fotg210_writel(fotg210, INTR_MASK,
-+ &fotg210->regs->intr_enable); /* Turn On Interrupts */
-+
-+ /* GRR this is run-once init(), being done every time the HC starts.
-+ * So long as they're part of class devices, we can't do it init()
-+ * since the class device isn't created that early.
-+ */
-+ create_debug_files(fotg210);
-+ create_sysfs_files(fotg210);
-+
-+ return 0;
-+}
-+
-+static int fotg210_setup(struct usb_hcd *hcd)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ int retval;
-+
-+ fotg210->regs = (void __iomem *)fotg210->caps +
-+ HC_LENGTH(fotg210,
-+ fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
-+ dbg_hcs_params(fotg210, "reset");
-+ dbg_hcc_params(fotg210, "reset");
-+
-+ /* cache this readonly data; minimize chip reads */
-+ fotg210->hcs_params = fotg210_readl(fotg210,
-+ &fotg210->caps->hcs_params);
-+
-+ fotg210->sbrn = HCD_USB2;
-+
-+ /* data structure init */
-+ retval = hcd_fotg210_init(hcd);
-+ if (retval)
-+ return retval;
-+
-+ retval = fotg210_halt(fotg210);
-+ if (retval)
-+ return retval;
-+
-+ fotg210_reset(fotg210);
-+
-+ return 0;
-+}
-+
-+static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ u32 status, masked_status, pcd_status = 0, cmd;
-+ int bh;
-+
-+ spin_lock(&fotg210->lock);
-+
-+ status = fotg210_readl(fotg210, &fotg210->regs->status);
-+
-+ /* e.g. cardbus physical eject */
-+ if (status == ~(u32) 0) {
-+ fotg210_dbg(fotg210, "device removed\n");
-+ goto dead;
-+ }
-+
-+ /*
-+ * We don't use STS_FLR, but some controllers don't like it to
-+ * remain on, so mask it out along with the other status bits.
-+ */
-+ masked_status = status & (INTR_MASK | STS_FLR);
-+
-+ /* Shared IRQ? */
-+ if (!masked_status ||
-+ unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
-+ spin_unlock(&fotg210->lock);
-+ return IRQ_NONE;
-+ }
-+
-+ /* clear (just) interrupts */
-+ fotg210_writel(fotg210, masked_status, &fotg210->regs->status);
-+ cmd = fotg210_readl(fotg210, &fotg210->regs->command);
-+ bh = 0;
-+
-+ /* unrequested/ignored: Frame List Rollover */
-+ dbg_status(fotg210, "irq", status);
-+
-+ /* INT, ERR, and IAA interrupt rates can be throttled */
-+
-+ /* normal [4.15.1.2] or error [4.15.1.1] completion */
-+ if (likely((status & (STS_INT|STS_ERR)) != 0)) {
-+ if (likely((status & STS_ERR) == 0))
-+ INCR(fotg210->stats.normal);
-+ else
-+ INCR(fotg210->stats.error);
-+ bh = 1;
-+ }
-+
-+ /* complete the unlinking of some qh [4.15.2.3] */
-+ if (status & STS_IAA) {
-+
-+ /* Turn off the IAA watchdog */
-+ fotg210->enabled_hrtimer_events &=
-+ ~BIT(FOTG210_HRTIMER_IAA_WATCHDOG);
-+
-+ /*
-+ * Mild optimization: Allow another IAAD to reset the
-+ * hrtimer, if one occurs before the next expiration.
-+ * In theory we could always cancel the hrtimer, but
-+ * tests show that about half the time it will be reset
-+ * for some other event anyway.
-+ */
-+ if (fotg210->next_hrtimer_event == FOTG210_HRTIMER_IAA_WATCHDOG)
-+ ++fotg210->next_hrtimer_event;
-+
-+ /* guard against (alleged) silicon errata */
-+ if (cmd & CMD_IAAD)
-+ fotg210_dbg(fotg210, "IAA with IAAD still set?\n");
-+ if (fotg210->async_iaa) {
-+ INCR(fotg210->stats.iaa);
-+ end_unlink_async(fotg210);
-+ } else
-+ fotg210_dbg(fotg210, "IAA with nothing unlinked?\n");
-+ }
-+
-+ /* remote wakeup [4.3.1] */
-+ if (status & STS_PCD) {
-+ int pstatus;
-+ u32 __iomem *status_reg = &fotg210->regs->port_status;
-+
-+ /* kick root hub later */
-+ pcd_status = status;
-+
-+ /* resume root hub? */
-+ if (fotg210->rh_state == FOTG210_RH_SUSPENDED)
-+ usb_hcd_resume_root_hub(hcd);
-+
-+ pstatus = fotg210_readl(fotg210, status_reg);
-+
-+ if (test_bit(0, &fotg210->suspended_ports) &&
-+ ((pstatus & PORT_RESUME) ||
-+ !(pstatus & PORT_SUSPEND)) &&
-+ (pstatus & PORT_PE) &&
-+ fotg210->reset_done[0] == 0) {
-+
-+ /* start 20 msec resume signaling from this port,
-+ * and make hub_wq collect PORT_STAT_C_SUSPEND to
-+ * stop that signaling. Use 5 ms extra for safety,
-+ * like usb_port_resume() does.
-+ */
-+ fotg210->reset_done[0] = jiffies + msecs_to_jiffies(25);
-+ set_bit(0, &fotg210->resuming_ports);
-+ fotg210_dbg(fotg210, "port 1 remote wakeup\n");
-+ mod_timer(&hcd->rh_timer, fotg210->reset_done[0]);
-+ }
-+ }
-+
-+ /* PCI errors [4.15.2.4] */
-+ if (unlikely((status & STS_FATAL) != 0)) {
-+ fotg210_err(fotg210, "fatal error\n");
-+ dbg_cmd(fotg210, "fatal", cmd);
-+ dbg_status(fotg210, "fatal", status);
-+dead:
-+ usb_hc_died(hcd);
-+
-+ /* Don't let the controller do anything more */
-+ fotg210->shutdown = true;
-+ fotg210->rh_state = FOTG210_RH_STOPPING;
-+ fotg210->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
-+ fotg210_writel(fotg210, fotg210->command,
-+ &fotg210->regs->command);
-+ fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-+ fotg210_handle_controller_death(fotg210);
-+
-+ /* Handle completions when the controller stops */
-+ bh = 0;
-+ }
-+
-+ if (bh)
-+ fotg210_work(fotg210);
-+ spin_unlock(&fotg210->lock);
-+ if (pcd_status)
-+ usb_hcd_poll_rh_status(hcd);
-+ return IRQ_HANDLED;
-+}
-+
-+/* non-error returns are a promise to giveback() the urb later
-+ * we drop ownership so next owner (or urb unlink) can get it
-+ *
-+ * urb + dev is in hcd.self.controller.urb_list
-+ * we're queueing TDs onto software and hardware lists
-+ *
-+ * hcd-specific init for hcpriv hasn't been done yet
-+ *
-+ * NOTE: control, bulk, and interrupt share the same code to append TDs
-+ * to a (possibly active) QH, and the same QH scanning code.
-+ */
-+static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
-+ gfp_t mem_flags)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ struct list_head qtd_list;
-+
-+ INIT_LIST_HEAD(&qtd_list);
-+
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_CONTROL:
-+ /* qh_completions() code doesn't handle all the fault cases
-+ * in multi-TD control transfers. Even 1KB is rare anyway.
-+ */
-+ if (urb->transfer_buffer_length > (16 * 1024))
-+ return -EMSGSIZE;
-+ fallthrough;
-+ /* case PIPE_BULK: */
-+ default:
-+ if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
-+ return -ENOMEM;
-+ return submit_async(fotg210, urb, &qtd_list, mem_flags);
-+
-+ case PIPE_INTERRUPT:
-+ if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
-+ return -ENOMEM;
-+ return intr_submit(fotg210, urb, &qtd_list, mem_flags);
-+
-+ case PIPE_ISOCHRONOUS:
-+ return itd_submit(fotg210, urb, mem_flags);
-+ }
-+}
-+
-+/* remove from hardware lists
-+ * completions normally happen asynchronously
-+ */
-+
-+static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ struct fotg210_qh *qh;
-+ unsigned long flags;
-+ int rc;
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ rc = usb_hcd_check_unlink_urb(hcd, urb, status);
-+ if (rc)
-+ goto done;
-+
-+ switch (usb_pipetype(urb->pipe)) {
-+ /* case PIPE_CONTROL: */
-+ /* case PIPE_BULK:*/
-+ default:
-+ qh = (struct fotg210_qh *) urb->hcpriv;
-+ if (!qh)
-+ break;
-+ switch (qh->qh_state) {
-+ case QH_STATE_LINKED:
-+ case QH_STATE_COMPLETING:
-+ start_unlink_async(fotg210, qh);
-+ break;
-+ case QH_STATE_UNLINK:
-+ case QH_STATE_UNLINK_WAIT:
-+ /* already started */
-+ break;
-+ case QH_STATE_IDLE:
-+ /* QH might be waiting for a Clear-TT-Buffer */
-+ qh_completions(fotg210, qh);
-+ break;
-+ }
-+ break;
-+
-+ case PIPE_INTERRUPT:
-+ qh = (struct fotg210_qh *) urb->hcpriv;
-+ if (!qh)
-+ break;
-+ switch (qh->qh_state) {
-+ case QH_STATE_LINKED:
-+ case QH_STATE_COMPLETING:
-+ start_unlink_intr(fotg210, qh);
-+ break;
-+ case QH_STATE_IDLE:
-+ qh_completions(fotg210, qh);
-+ break;
-+ default:
-+ fotg210_dbg(fotg210, "bogus qh %p state %d\n",
-+ qh, qh->qh_state);
-+ goto done;
-+ }
-+ break;
-+
-+ case PIPE_ISOCHRONOUS:
-+ /* itd... */
-+
-+ /* wait till next completion, do it then. */
-+ /* completion irqs can wait up to 1024 msec, */
-+ break;
-+ }
-+done:
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ return rc;
-+}
-+
-+/* bulk qh holds the data toggle */
-+
-+static void fotg210_endpoint_disable(struct usb_hcd *hcd,
-+ struct usb_host_endpoint *ep)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ unsigned long flags;
-+ struct fotg210_qh *qh, *tmp;
-+
-+ /* ASSERT: any requests/urbs are being unlinked */
-+ /* ASSERT: nobody can be submitting urbs for this any more */
-+
-+rescan:
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ qh = ep->hcpriv;
-+ if (!qh)
-+ goto done;
-+
-+ /* endpoints can be iso streams. for now, we don't
-+ * accelerate iso completions ... so spin a while.
-+ */
-+ if (qh->hw == NULL) {
-+ struct fotg210_iso_stream *stream = ep->hcpriv;
-+
-+ if (!list_empty(&stream->td_list))
-+ goto idle_timeout;
-+
-+ /* BUG_ON(!list_empty(&stream->free_list)); */
-+ kfree(stream);
-+ goto done;
-+ }
-+
-+ if (fotg210->rh_state < FOTG210_RH_RUNNING)
-+ qh->qh_state = QH_STATE_IDLE;
-+ switch (qh->qh_state) {
-+ case QH_STATE_LINKED:
-+ case QH_STATE_COMPLETING:
-+ for (tmp = fotg210->async->qh_next.qh;
-+ tmp && tmp != qh;
-+ tmp = tmp->qh_next.qh)
-+ continue;
-+ /* periodic qh self-unlinks on empty, and a COMPLETING qh
-+ * may already be unlinked.
-+ */
-+ if (tmp)
-+ start_unlink_async(fotg210, qh);
-+ fallthrough;
-+ case QH_STATE_UNLINK: /* wait for hw to finish? */
-+ case QH_STATE_UNLINK_WAIT:
-+idle_timeout:
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+ schedule_timeout_uninterruptible(1);
-+ goto rescan;
-+ case QH_STATE_IDLE: /* fully unlinked */
-+ if (qh->clearing_tt)
-+ goto idle_timeout;
-+ if (list_empty(&qh->qtd_list)) {
-+ qh_destroy(fotg210, qh);
-+ break;
-+ }
-+ fallthrough;
-+ default:
-+ /* caller was supposed to have unlinked any requests;
-+ * that's not our job. just leak this memory.
-+ */
-+ fotg210_err(fotg210, "qh %p (#%02x) state %d%s\n",
-+ qh, ep->desc.bEndpointAddress, qh->qh_state,
-+ list_empty(&qh->qtd_list) ? "" : "(has tds)");
-+ break;
-+ }
-+done:
-+ ep->hcpriv = NULL;
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+}
-+
-+static void fotg210_endpoint_reset(struct usb_hcd *hcd,
-+ struct usb_host_endpoint *ep)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+ struct fotg210_qh *qh;
-+ int eptype = usb_endpoint_type(&ep->desc);
-+ int epnum = usb_endpoint_num(&ep->desc);
-+ int is_out = usb_endpoint_dir_out(&ep->desc);
-+ unsigned long flags;
-+
-+ if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
-+ return;
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+ qh = ep->hcpriv;
-+
-+ /* For Bulk and Interrupt endpoints we maintain the toggle state
-+ * in the hardware; the toggle bits in udev aren't used at all.
-+ * When an endpoint is reset by usb_clear_halt() we must reset
-+ * the toggle bit in the QH.
-+ */
-+ if (qh) {
-+ usb_settoggle(qh->dev, epnum, is_out, 0);
-+ if (!list_empty(&qh->qtd_list)) {
-+ WARN_ONCE(1, "clear_halt for a busy endpoint\n");
-+ } else if (qh->qh_state == QH_STATE_LINKED ||
-+ qh->qh_state == QH_STATE_COMPLETING) {
-+
-+ /* The toggle value in the QH can't be updated
-+ * while the QH is active. Unlink it now;
-+ * re-linking will call qh_refresh().
-+ */
-+ if (eptype == USB_ENDPOINT_XFER_BULK)
-+ start_unlink_async(fotg210, qh);
-+ else
-+ start_unlink_intr(fotg210, qh);
-+ }
-+ }
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+}
-+
-+static int fotg210_get_frame(struct usb_hcd *hcd)
-+{
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+
-+ return (fotg210_read_frame_index(fotg210) >> 3) %
-+ fotg210->periodic_size;
-+}
-+
-+/* The EHCI in ChipIdea HDRC cannot be a separate module or device,
-+ * because its registers (and irq) are shared between host/gadget/otg
-+ * functions and in order to facilitate role switching we cannot
-+ * give the fotg210 driver exclusive access to those.
-+ */
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_LICENSE("GPL");
-+
-+static const struct hc_driver fotg210_fotg210_hc_driver = {
-+ .description = hcd_name,
-+ .product_desc = "Faraday USB2.0 Host Controller",
-+ .hcd_priv_size = sizeof(struct fotg210_hcd),
-+
-+ /*
-+ * generic hardware linkage
-+ */
-+ .irq = fotg210_irq,
-+ .flags = HCD_MEMORY | HCD_DMA | HCD_USB2,
-+
-+ /*
-+ * basic lifecycle operations
-+ */
-+ .reset = hcd_fotg210_init,
-+ .start = fotg210_run,
-+ .stop = fotg210_stop,
-+ .shutdown = fotg210_shutdown,
-+
-+ /*
-+ * managing i/o requests and associated device resources
-+ */
-+ .urb_enqueue = fotg210_urb_enqueue,
-+ .urb_dequeue = fotg210_urb_dequeue,
-+ .endpoint_disable = fotg210_endpoint_disable,
-+ .endpoint_reset = fotg210_endpoint_reset,
-+
-+ /*
-+ * scheduling support
-+ */
-+ .get_frame_number = fotg210_get_frame,
-+
-+ /*
-+ * root hub support
-+ */
-+ .hub_status_data = fotg210_hub_status_data,
-+ .hub_control = fotg210_hub_control,
-+ .bus_suspend = fotg210_bus_suspend,
-+ .bus_resume = fotg210_bus_resume,
-+
-+ .relinquish_port = fotg210_relinquish_port,
-+ .port_handed_over = fotg210_port_handed_over,
-+
-+ .clear_tt_buffer_complete = fotg210_clear_tt_buffer_complete,
-+};
-+
-+static void fotg210_init(struct fotg210_hcd *fotg210)
-+{
-+ u32 value;
-+
-+ iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
-+ &fotg210->regs->gmir);
-+
-+ value = ioread32(&fotg210->regs->otgcsr);
-+ value &= ~OTGCSR_A_BUS_DROP;
-+ value |= OTGCSR_A_BUS_REQ;
-+ iowrite32(value, &fotg210->regs->otgcsr);
-+}
-+
-+/*
-+ * fotg210_hcd_probe - initialize faraday FOTG210 HCDs
-+ *
-+ * Allocates basic resources for this USB host controller, and
-+ * then invokes the start() method for the HCD associated with it
-+ * through the hotplug entry's driver_data.
-+ */
-+static int fotg210_hcd_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct usb_hcd *hcd;
-+ struct resource *res;
-+ int irq;
-+ int retval;
-+ struct fotg210_hcd *fotg210;
-+
-+ if (usb_disabled())
-+ return -ENODEV;
-+
-+ pdev->dev.power.power_state = PMSG_ON;
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0)
-+ return irq;
-+
-+ hcd = usb_create_hcd(&fotg210_fotg210_hc_driver, dev,
-+ dev_name(dev));
-+ if (!hcd) {
-+ dev_err(dev, "failed to create hcd\n");
-+ retval = -ENOMEM;
-+ goto fail_create_hcd;
-+ }
-+
-+ hcd->has_tt = 1;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ hcd->regs = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(hcd->regs)) {
-+ retval = PTR_ERR(hcd->regs);
-+ goto failed_put_hcd;
-+ }
-+
-+ hcd->rsrc_start = res->start;
-+ hcd->rsrc_len = resource_size(res);
-+
-+ fotg210 = hcd_to_fotg210(hcd);
-+
-+ fotg210->caps = hcd->regs;
-+
-+ /* It's OK not to supply this clock */
-+ fotg210->pclk = clk_get(dev, "PCLK");
-+ if (!IS_ERR(fotg210->pclk)) {
-+ retval = clk_prepare_enable(fotg210->pclk);
-+ if (retval) {
-+ dev_err(dev, "failed to enable PCLK\n");
-+ goto failed_put_hcd;
-+ }
-+ } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
-+ /*
-+ * Percolate deferrals, for anything else,
-+ * just live without the clocking.
-+ */
-+ retval = PTR_ERR(fotg210->pclk);
-+ goto failed_dis_clk;
-+ }
-+
-+ retval = fotg210_setup(hcd);
-+ if (retval)
-+ goto failed_dis_clk;
-+
-+ fotg210_init(fotg210);
-+
-+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
-+ if (retval) {
-+ dev_err(dev, "failed to add hcd with err %d\n", retval);
-+ goto failed_dis_clk;
-+ }
-+ device_wakeup_enable(hcd->self.controller);
-+ platform_set_drvdata(pdev, hcd);
-+
-+ return retval;
-+
-+failed_dis_clk:
-+ if (!IS_ERR(fotg210->pclk)) {
-+ clk_disable_unprepare(fotg210->pclk);
-+ clk_put(fotg210->pclk);
-+ }
-+failed_put_hcd:
-+ usb_put_hcd(hcd);
-+fail_create_hcd:
-+ dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
-+ return retval;
-+}
-+
-+/*
-+ * fotg210_hcd_remove - shutdown processing for EHCI HCDs
-+ * @dev: USB Host Controller being removed
-+ *
-+ */
-+static int fotg210_hcd_remove(struct platform_device *pdev)
-+{
-+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
-+ struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-+
-+ if (!IS_ERR(fotg210->pclk)) {
-+ clk_disable_unprepare(fotg210->pclk);
-+ clk_put(fotg210->pclk);
-+ }
-+
-+ usb_remove_hcd(hcd);
-+ usb_put_hcd(hcd);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_OF
-+static const struct of_device_id fotg210_of_match[] = {
-+ { .compatible = "faraday,fotg210" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, fotg210_of_match);
-+#endif
-+
-+static struct platform_driver fotg210_hcd_driver = {
-+ .driver = {
-+ .name = "fotg210-hcd",
-+ .of_match_table = of_match_ptr(fotg210_of_match),
-+ },
-+ .probe = fotg210_hcd_probe,
-+ .remove = fotg210_hcd_remove,
-+};
-+
-+static int __init fotg210_hcd_init(void)
-+{
-+ int retval = 0;
-+
-+ if (usb_disabled())
-+ return -ENODEV;
-+
-+ set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-+ if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
-+ test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-+ pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
-+
-+ pr_debug("%s: block sizes: qh %zd qtd %zd itd %zd\n",
-+ hcd_name, sizeof(struct fotg210_qh),
-+ sizeof(struct fotg210_qtd),
-+ sizeof(struct fotg210_itd));
-+
-+ fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
-+
-+ retval = platform_driver_register(&fotg210_hcd_driver);
-+ if (retval < 0)
-+ goto clean;
-+ return retval;
-+
-+clean:
-+ debugfs_remove(fotg210_debug_root);
-+ fotg210_debug_root = NULL;
-+
-+ clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-+ return retval;
-+}
-+module_init(fotg210_hcd_init);
-+
-+static void __exit fotg210_hcd_cleanup(void)
-+{
-+ platform_driver_unregister(&fotg210_hcd_driver);
-+ debugfs_remove(fotg210_debug_root);
-+ clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-+}
-+module_exit(fotg210_hcd_cleanup);
---- a/drivers/usb/gadget/udc/fotg210-udc.c
-+++ /dev/null
-@@ -1,1239 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--/*
-- * FOTG210 UDC Driver supports Bulk transfer so far
-- *
-- * Copyright (C) 2013 Faraday Technology Corporation
-- *
-- * Author : Yuan-Hsin Chen <yhchen@faraday-tech.com>
-- */
--
--#include <linux/dma-mapping.h>
--#include <linux/err.h>
--#include <linux/interrupt.h>
--#include <linux/io.h>
--#include <linux/module.h>
--#include <linux/platform_device.h>
--#include <linux/usb/ch9.h>
--#include <linux/usb/gadget.h>
--
--#include "fotg210.h"
--
--#define DRIVER_DESC "FOTG210 USB Device Controller Driver"
--#define DRIVER_VERSION "30-April-2013"
--
--static const char udc_name[] = "fotg210_udc";
--static const char * const fotg210_ep_name[] = {
-- "ep0", "ep1", "ep2", "ep3", "ep4"};
--
--static void fotg210_disable_fifo_int(struct fotg210_ep *ep)
--{
-- u32 value = ioread32(ep->fotg210->reg + FOTG210_DMISGR1);
--
-- if (ep->dir_in)
-- value |= DMISGR1_MF_IN_INT(ep->epnum - 1);
-- else
-- value |= DMISGR1_MF_OUTSPK_INT(ep->epnum - 1);
-- iowrite32(value, ep->fotg210->reg + FOTG210_DMISGR1);
--}
--
--static void fotg210_enable_fifo_int(struct fotg210_ep *ep)
--{
-- u32 value = ioread32(ep->fotg210->reg + FOTG210_DMISGR1);
--
-- if (ep->dir_in)
-- value &= ~DMISGR1_MF_IN_INT(ep->epnum - 1);
-- else
-- value &= ~DMISGR1_MF_OUTSPK_INT(ep->epnum - 1);
-- iowrite32(value, ep->fotg210->reg + FOTG210_DMISGR1);
--}
--
--static void fotg210_set_cxdone(struct fotg210_udc *fotg210)
--{
-- u32 value = ioread32(fotg210->reg + FOTG210_DCFESR);
--
-- value |= DCFESR_CX_DONE;
-- iowrite32(value, fotg210->reg + FOTG210_DCFESR);
--}
--
--static void fotg210_done(struct fotg210_ep *ep, struct fotg210_request *req,
-- int status)
--{
-- list_del_init(&req->queue);
--
-- /* don't modify queue heads during completion callback */
-- if (ep->fotg210->gadget.speed == USB_SPEED_UNKNOWN)
-- req->req.status = -ESHUTDOWN;
-- else
-- req->req.status = status;
--
-- spin_unlock(&ep->fotg210->lock);
-- usb_gadget_giveback_request(&ep->ep, &req->req);
-- spin_lock(&ep->fotg210->lock);
--
-- if (ep->epnum) {
-- if (list_empty(&ep->queue))
-- fotg210_disable_fifo_int(ep);
-- } else {
-- fotg210_set_cxdone(ep->fotg210);
-- }
--}
--
--static void fotg210_fifo_ep_mapping(struct fotg210_ep *ep, u32 epnum,
-- u32 dir_in)
--{
-- struct fotg210_udc *fotg210 = ep->fotg210;
-- u32 val;
--
-- /* Driver should map an ep to a fifo and then map the fifo
-- * to the ep. What a brain-damaged design!
-- */
--
-- /* map a fifo to an ep */
-- val = ioread32(fotg210->reg + FOTG210_EPMAP);
-- val &= ~EPMAP_FIFONOMSK(epnum, dir_in);
-- val |= EPMAP_FIFONO(epnum, dir_in);
-- iowrite32(val, fotg210->reg + FOTG210_EPMAP);
--
-- /* map the ep to the fifo */
-- val = ioread32(fotg210->reg + FOTG210_FIFOMAP);
-- val &= ~FIFOMAP_EPNOMSK(epnum);
-- val |= FIFOMAP_EPNO(epnum);
-- iowrite32(val, fotg210->reg + FOTG210_FIFOMAP);
--
-- /* enable fifo */
-- val = ioread32(fotg210->reg + FOTG210_FIFOCF);
-- val |= FIFOCF_FIFO_EN(epnum - 1);
-- iowrite32(val, fotg210->reg + FOTG210_FIFOCF);
--}
--
--static void fotg210_set_fifo_dir(struct fotg210_ep *ep, u32 epnum, u32 dir_in)
--{
-- struct fotg210_udc *fotg210 = ep->fotg210;
-- u32 val;
--
-- val = ioread32(fotg210->reg + FOTG210_FIFOMAP);
-- val |= (dir_in ? FIFOMAP_DIRIN(epnum - 1) : FIFOMAP_DIROUT(epnum - 1));
-- iowrite32(val, fotg210->reg + FOTG210_FIFOMAP);
--}
--
--static void fotg210_set_tfrtype(struct fotg210_ep *ep, u32 epnum, u32 type)
--{
-- struct fotg210_udc *fotg210 = ep->fotg210;
-- u32 val;
--
-- val = ioread32(fotg210->reg + FOTG210_FIFOCF);
-- val |= FIFOCF_TYPE(type, epnum - 1);
-- iowrite32(val, fotg210->reg + FOTG210_FIFOCF);
--}
--
--static void fotg210_set_mps(struct fotg210_ep *ep, u32 epnum, u32 mps,
-- u32 dir_in)
--{
-- struct fotg210_udc *fotg210 = ep->fotg210;
-- u32 val;
-- u32 offset = dir_in ? FOTG210_INEPMPSR(epnum) :
-- FOTG210_OUTEPMPSR(epnum);
--
-- val = ioread32(fotg210->reg + offset);
-- val |= INOUTEPMPSR_MPS(mps);
-- iowrite32(val, fotg210->reg + offset);
--}
--
--static int fotg210_config_ep(struct fotg210_ep *ep,
-- const struct usb_endpoint_descriptor *desc)
--{
-- struct fotg210_udc *fotg210 = ep->fotg210;
--
-- fotg210_set_fifo_dir(ep, ep->epnum, ep->dir_in);
-- fotg210_set_tfrtype(ep, ep->epnum, ep->type);
-- fotg210_set_mps(ep, ep->epnum, ep->ep.maxpacket, ep->dir_in);
-- fotg210_fifo_ep_mapping(ep, ep->epnum, ep->dir_in);
--
-- fotg210->ep[ep->epnum] = ep;
--
-- return 0;
--}
--
--static int fotg210_ep_enable(struct usb_ep *_ep,
-- const struct usb_endpoint_descriptor *desc)
--{
-- struct fotg210_ep *ep;
--
-- ep = container_of(_ep, struct fotg210_ep, ep);
--
-- ep->desc = desc;
-- ep->epnum = usb_endpoint_num(desc);
-- ep->type = usb_endpoint_type(desc);
-- ep->dir_in = usb_endpoint_dir_in(desc);
-- ep->ep.maxpacket = usb_endpoint_maxp(desc);
--
-- return fotg210_config_ep(ep, desc);
--}
--
--static void fotg210_reset_tseq(struct fotg210_udc *fotg210, u8 epnum)
--{
-- struct fotg210_ep *ep = fotg210->ep[epnum];
-- u32 value;
-- void __iomem *reg;
--
-- reg = (ep->dir_in) ?
-- fotg210->reg + FOTG210_INEPMPSR(epnum) :
-- fotg210->reg + FOTG210_OUTEPMPSR(epnum);
--
-- /* Note: Driver needs to set and clear INOUTEPMPSR_RESET_TSEQ
-- * bit. Controller wouldn't clear this bit. WTF!!!
-- */
--
-- value = ioread32(reg);
-- value |= INOUTEPMPSR_RESET_TSEQ;
-- iowrite32(value, reg);
--
-- value = ioread32(reg);
-- value &= ~INOUTEPMPSR_RESET_TSEQ;
-- iowrite32(value, reg);
--}
--
--static int fotg210_ep_release(struct fotg210_ep *ep)
--{
-- if (!ep->epnum)
-- return 0;
-- ep->epnum = 0;
-- ep->stall = 0;
-- ep->wedged = 0;
--
-- fotg210_reset_tseq(ep->fotg210, ep->epnum);
--
-- return 0;
--}
--
--static int fotg210_ep_disable(struct usb_ep *_ep)
--{
-- struct fotg210_ep *ep;
-- struct fotg210_request *req;
-- unsigned long flags;
--
-- BUG_ON(!_ep);
--
-- ep = container_of(_ep, struct fotg210_ep, ep);
--
-- while (!list_empty(&ep->queue)) {
-- req = list_entry(ep->queue.next,
-- struct fotg210_request, queue);
-- spin_lock_irqsave(&ep->fotg210->lock, flags);
-- fotg210_done(ep, req, -ECONNRESET);
-- spin_unlock_irqrestore(&ep->fotg210->lock, flags);
-- }
--
-- return fotg210_ep_release(ep);
--}
--
--static struct usb_request *fotg210_ep_alloc_request(struct usb_ep *_ep,
-- gfp_t gfp_flags)
--{
-- struct fotg210_request *req;
--
-- req = kzalloc(sizeof(struct fotg210_request), gfp_flags);
-- if (!req)
-- return NULL;
--
-- INIT_LIST_HEAD(&req->queue);
--
-- return &req->req;
--}
--
--static void fotg210_ep_free_request(struct usb_ep *_ep,
-- struct usb_request *_req)
--{
-- struct fotg210_request *req;
--
-- req = container_of(_req, struct fotg210_request, req);
-- kfree(req);
--}
--
--static void fotg210_enable_dma(struct fotg210_ep *ep,
-- dma_addr_t d, u32 len)
--{
-- u32 value;
-- struct fotg210_udc *fotg210 = ep->fotg210;
--
-- /* set transfer length and direction */
-- value = ioread32(fotg210->reg + FOTG210_DMACPSR1);
-- value &= ~(DMACPSR1_DMA_LEN(0xFFFF) | DMACPSR1_DMA_TYPE(1));
-- value |= DMACPSR1_DMA_LEN(len) | DMACPSR1_DMA_TYPE(ep->dir_in);
-- iowrite32(value, fotg210->reg + FOTG210_DMACPSR1);
--
-- /* set device DMA target FIFO number */
-- value = ioread32(fotg210->reg + FOTG210_DMATFNR);
-- if (ep->epnum)
-- value |= DMATFNR_ACC_FN(ep->epnum - 1);
-- else
-- value |= DMATFNR_ACC_CXF;
-- iowrite32(value, fotg210->reg + FOTG210_DMATFNR);
--
-- /* set DMA memory address */
-- iowrite32(d, fotg210->reg + FOTG210_DMACPSR2);
--
-- /* enable MDMA_EROR and MDMA_CMPLT interrupt */
-- value = ioread32(fotg210->reg + FOTG210_DMISGR2);
-- value &= ~(DMISGR2_MDMA_CMPLT | DMISGR2_MDMA_ERROR);
-- iowrite32(value, fotg210->reg + FOTG210_DMISGR2);
--
-- /* start DMA */
-- value = ioread32(fotg210->reg + FOTG210_DMACPSR1);
-- value |= DMACPSR1_DMA_START;
-- iowrite32(value, fotg210->reg + FOTG210_DMACPSR1);
--}
--
--static void fotg210_disable_dma(struct fotg210_ep *ep)
--{
-- iowrite32(DMATFNR_DISDMA, ep->fotg210->reg + FOTG210_DMATFNR);
--}
--
--static void fotg210_wait_dma_done(struct fotg210_ep *ep)
--{
-- u32 value;
--
-- do {
-- value = ioread32(ep->fotg210->reg + FOTG210_DISGR2);
-- if ((value & DISGR2_USBRST_INT) ||
-- (value & DISGR2_DMA_ERROR))
-- goto dma_reset;
-- } while (!(value & DISGR2_DMA_CMPLT));
--
-- value &= ~DISGR2_DMA_CMPLT;
-- iowrite32(value, ep->fotg210->reg + FOTG210_DISGR2);
-- return;
--
--dma_reset:
-- value = ioread32(ep->fotg210->reg + FOTG210_DMACPSR1);
-- value |= DMACPSR1_DMA_ABORT;
-- iowrite32(value, ep->fotg210->reg + FOTG210_DMACPSR1);
--
-- /* reset fifo */
-- if (ep->epnum) {
-- value = ioread32(ep->fotg210->reg +
-- FOTG210_FIBCR(ep->epnum - 1));
-- value |= FIBCR_FFRST;
-- iowrite32(value, ep->fotg210->reg +
-- FOTG210_FIBCR(ep->epnum - 1));
-- } else {
-- value = ioread32(ep->fotg210->reg + FOTG210_DCFESR);
-- value |= DCFESR_CX_CLR;
-- iowrite32(value, ep->fotg210->reg + FOTG210_DCFESR);
-- }
--}
--
--static void fotg210_start_dma(struct fotg210_ep *ep,
-- struct fotg210_request *req)
--{
-- struct device *dev = &ep->fotg210->gadget.dev;
-- dma_addr_t d;
-- u8 *buffer;
-- u32 length;
--
-- if (ep->epnum) {
-- if (ep->dir_in) {
-- buffer = req->req.buf;
-- length = req->req.length;
-- } else {
-- buffer = req->req.buf + req->req.actual;
-- length = ioread32(ep->fotg210->reg +
-- FOTG210_FIBCR(ep->epnum - 1)) & FIBCR_BCFX;
-- if (length > req->req.length - req->req.actual)
-- length = req->req.length - req->req.actual;
-- }
-- } else {
-- buffer = req->req.buf + req->req.actual;
-- if (req->req.length - req->req.actual > ep->ep.maxpacket)
-- length = ep->ep.maxpacket;
-- else
-- length = req->req.length - req->req.actual;
-- }
--
-- d = dma_map_single(dev, buffer, length,
-- ep->dir_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
--
-- if (dma_mapping_error(dev, d)) {
-- pr_err("dma_mapping_error\n");
-- return;
-- }
--
-- fotg210_enable_dma(ep, d, length);
--
-- /* check if dma is done */
-- fotg210_wait_dma_done(ep);
--
-- fotg210_disable_dma(ep);
--
-- /* update actual transfer length */
-- req->req.actual += length;
--
-- dma_unmap_single(dev, d, length, DMA_TO_DEVICE);
--}
--
--static void fotg210_ep0_queue(struct fotg210_ep *ep,
-- struct fotg210_request *req)
--{
-- if (!req->req.length) {
-- fotg210_done(ep, req, 0);
-- return;
-- }
-- if (ep->dir_in) { /* if IN */
-- fotg210_start_dma(ep, req);
-- if (req->req.length == req->req.actual)
-- fotg210_done(ep, req, 0);
-- } else { /* OUT */
-- u32 value = ioread32(ep->fotg210->reg + FOTG210_DMISGR0);
--
-- value &= ~DMISGR0_MCX_OUT_INT;
-- iowrite32(value, ep->fotg210->reg + FOTG210_DMISGR0);
-- }
--}
--
--static int fotg210_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
-- gfp_t gfp_flags)
--{
-- struct fotg210_ep *ep;
-- struct fotg210_request *req;
-- unsigned long flags;
-- int request = 0;
--
-- ep = container_of(_ep, struct fotg210_ep, ep);
-- req = container_of(_req, struct fotg210_request, req);
--
-- if (ep->fotg210->gadget.speed == USB_SPEED_UNKNOWN)
-- return -ESHUTDOWN;
--
-- spin_lock_irqsave(&ep->fotg210->lock, flags);
--
-- if (list_empty(&ep->queue))
-- request = 1;
--
-- list_add_tail(&req->queue, &ep->queue);
--
-- req->req.actual = 0;
-- req->req.status = -EINPROGRESS;
--
-- if (!ep->epnum) /* ep0 */
-- fotg210_ep0_queue(ep, req);
-- else if (request && !ep->stall)
-- fotg210_enable_fifo_int(ep);
--
-- spin_unlock_irqrestore(&ep->fotg210->lock, flags);
--
-- return 0;
--}
--
--static int fotg210_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
--{
-- struct fotg210_ep *ep;
-- struct fotg210_request *req;
-- unsigned long flags;
--
-- ep = container_of(_ep, struct fotg210_ep, ep);
-- req = container_of(_req, struct fotg210_request, req);
--
-- spin_lock_irqsave(&ep->fotg210->lock, flags);
-- if (!list_empty(&ep->queue))
-- fotg210_done(ep, req, -ECONNRESET);
-- spin_unlock_irqrestore(&ep->fotg210->lock, flags);
--
-- return 0;
--}
--
--static void fotg210_set_epnstall(struct fotg210_ep *ep)
--{
-- struct fotg210_udc *fotg210 = ep->fotg210;
-- u32 value;
-- void __iomem *reg;
--
-- /* check if IN FIFO is empty before stall */
-- if (ep->dir_in) {
-- do {
-- value = ioread32(fotg210->reg + FOTG210_DCFESR);
-- } while (!(value & DCFESR_FIFO_EMPTY(ep->epnum - 1)));
-- }
--
-- reg = (ep->dir_in) ?
-- fotg210->reg + FOTG210_INEPMPSR(ep->epnum) :
-- fotg210->reg + FOTG210_OUTEPMPSR(ep->epnum);
-- value = ioread32(reg);
-- value |= INOUTEPMPSR_STL_EP;
-- iowrite32(value, reg);
--}
--
--static void fotg210_clear_epnstall(struct fotg210_ep *ep)
--{
-- struct fotg210_udc *fotg210 = ep->fotg210;
-- u32 value;
-- void __iomem *reg;
--
-- reg = (ep->dir_in) ?
-- fotg210->reg + FOTG210_INEPMPSR(ep->epnum) :
-- fotg210->reg + FOTG210_OUTEPMPSR(ep->epnum);
-- value = ioread32(reg);
-- value &= ~INOUTEPMPSR_STL_EP;
-- iowrite32(value, reg);
--}
--
--static int fotg210_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedge)
--{
-- struct fotg210_ep *ep;
-- struct fotg210_udc *fotg210;
-- unsigned long flags;
--
-- ep = container_of(_ep, struct fotg210_ep, ep);
--
-- fotg210 = ep->fotg210;
--
-- spin_lock_irqsave(&ep->fotg210->lock, flags);
--
-- if (value) {
-- fotg210_set_epnstall(ep);
-- ep->stall = 1;
-- if (wedge)
-- ep->wedged = 1;
-- } else {
-- fotg210_reset_tseq(fotg210, ep->epnum);
-- fotg210_clear_epnstall(ep);
-- ep->stall = 0;
-- ep->wedged = 0;
-- if (!list_empty(&ep->queue))
-- fotg210_enable_fifo_int(ep);
-- }
--
-- spin_unlock_irqrestore(&ep->fotg210->lock, flags);
-- return 0;
--}
--
--static int fotg210_ep_set_halt(struct usb_ep *_ep, int value)
--{
-- return fotg210_set_halt_and_wedge(_ep, value, 0);
--}
--
--static int fotg210_ep_set_wedge(struct usb_ep *_ep)
--{
-- return fotg210_set_halt_and_wedge(_ep, 1, 1);
--}
--
--static void fotg210_ep_fifo_flush(struct usb_ep *_ep)
--{
--}
--
--static const struct usb_ep_ops fotg210_ep_ops = {
-- .enable = fotg210_ep_enable,
-- .disable = fotg210_ep_disable,
--
-- .alloc_request = fotg210_ep_alloc_request,
-- .free_request = fotg210_ep_free_request,
--
-- .queue = fotg210_ep_queue,
-- .dequeue = fotg210_ep_dequeue,
--
-- .set_halt = fotg210_ep_set_halt,
-- .fifo_flush = fotg210_ep_fifo_flush,
-- .set_wedge = fotg210_ep_set_wedge,
--};
--
--static void fotg210_clear_tx0byte(struct fotg210_udc *fotg210)
--{
-- u32 value = ioread32(fotg210->reg + FOTG210_TX0BYTE);
--
-- value &= ~(TX0BYTE_EP1 | TX0BYTE_EP2 | TX0BYTE_EP3
-- | TX0BYTE_EP4);
-- iowrite32(value, fotg210->reg + FOTG210_TX0BYTE);
--}
--
--static void fotg210_clear_rx0byte(struct fotg210_udc *fotg210)
--{
-- u32 value = ioread32(fotg210->reg + FOTG210_RX0BYTE);
--
-- value &= ~(RX0BYTE_EP1 | RX0BYTE_EP2 | RX0BYTE_EP3
-- | RX0BYTE_EP4);
-- iowrite32(value, fotg210->reg + FOTG210_RX0BYTE);
--}
--
--/* read 8-byte setup packet only */
--static void fotg210_rdsetupp(struct fotg210_udc *fotg210,
-- u8 *buffer)
--{
-- int i = 0;
-- u8 *tmp = buffer;
-- u32 data;
-- u32 length = 8;
--
-- iowrite32(DMATFNR_ACC_CXF, fotg210->reg + FOTG210_DMATFNR);
--
-- for (i = (length >> 2); i > 0; i--) {
-- data = ioread32(fotg210->reg + FOTG210_CXPORT);
-- *tmp = data & 0xFF;
-- *(tmp + 1) = (data >> 8) & 0xFF;
-- *(tmp + 2) = (data >> 16) & 0xFF;
-- *(tmp + 3) = (data >> 24) & 0xFF;
-- tmp = tmp + 4;
-- }
--
-- switch (length % 4) {
-- case 1:
-- data = ioread32(fotg210->reg + FOTG210_CXPORT);
-- *tmp = data & 0xFF;
-- break;
-- case 2:
-- data = ioread32(fotg210->reg + FOTG210_CXPORT);
-- *tmp = data & 0xFF;
-- *(tmp + 1) = (data >> 8) & 0xFF;
-- break;
-- case 3:
-- data = ioread32(fotg210->reg + FOTG210_CXPORT);
-- *tmp = data & 0xFF;
-- *(tmp + 1) = (data >> 8) & 0xFF;
-- *(tmp + 2) = (data >> 16) & 0xFF;
-- break;
-- default:
-- break;
-- }
--
-- iowrite32(DMATFNR_DISDMA, fotg210->reg + FOTG210_DMATFNR);
--}
--
--static void fotg210_set_configuration(struct fotg210_udc *fotg210)
--{
-- u32 value = ioread32(fotg210->reg + FOTG210_DAR);
--
-- value |= DAR_AFT_CONF;
-- iowrite32(value, fotg210->reg + FOTG210_DAR);
--}
--
--static void fotg210_set_dev_addr(struct fotg210_udc *fotg210, u32 addr)
--{
-- u32 value = ioread32(fotg210->reg + FOTG210_DAR);
--
-- value |= (addr & 0x7F);
-- iowrite32(value, fotg210->reg + FOTG210_DAR);
--}
--
--static void fotg210_set_cxstall(struct fotg210_udc *fotg210)
--{
-- u32 value = ioread32(fotg210->reg + FOTG210_DCFESR);
--
-- value |= DCFESR_CX_STL;
-- iowrite32(value, fotg210->reg + FOTG210_DCFESR);
--}
--
--static void fotg210_request_error(struct fotg210_udc *fotg210)
--{
-- fotg210_set_cxstall(fotg210);
-- pr_err("request error!!\n");
--}
--
--static void fotg210_set_address(struct fotg210_udc *fotg210,
-- struct usb_ctrlrequest *ctrl)
--{
-- if (le16_to_cpu(ctrl->wValue) >= 0x0100) {
-- fotg210_request_error(fotg210);
-- } else {
-- fotg210_set_dev_addr(fotg210, le16_to_cpu(ctrl->wValue));
-- fotg210_set_cxdone(fotg210);
-- }
--}
--
--static void fotg210_set_feature(struct fotg210_udc *fotg210,
-- struct usb_ctrlrequest *ctrl)
--{
-- switch (ctrl->bRequestType & USB_RECIP_MASK) {
-- case USB_RECIP_DEVICE:
-- fotg210_set_cxdone(fotg210);
-- break;
-- case USB_RECIP_INTERFACE:
-- fotg210_set_cxdone(fotg210);
-- break;
-- case USB_RECIP_ENDPOINT: {
-- u8 epnum;
-- epnum = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK;
-- if (epnum)
-- fotg210_set_epnstall(fotg210->ep[epnum]);
-- else
-- fotg210_set_cxstall(fotg210);
-- fotg210_set_cxdone(fotg210);
-- }
-- break;
-- default:
-- fotg210_request_error(fotg210);
-- break;
-- }
--}
--
--static void fotg210_clear_feature(struct fotg210_udc *fotg210,
-- struct usb_ctrlrequest *ctrl)
--{
-- struct fotg210_ep *ep =
-- fotg210->ep[ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK];
--
-- switch (ctrl->bRequestType & USB_RECIP_MASK) {
-- case USB_RECIP_DEVICE:
-- fotg210_set_cxdone(fotg210);
-- break;
-- case USB_RECIP_INTERFACE:
-- fotg210_set_cxdone(fotg210);
-- break;
-- case USB_RECIP_ENDPOINT:
-- if (ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK) {
-- if (ep->wedged) {
-- fotg210_set_cxdone(fotg210);
-- break;
-- }
-- if (ep->stall)
-- fotg210_set_halt_and_wedge(&ep->ep, 0, 0);
-- }
-- fotg210_set_cxdone(fotg210);
-- break;
-- default:
-- fotg210_request_error(fotg210);
-- break;
-- }
--}
--
--static int fotg210_is_epnstall(struct fotg210_ep *ep)
--{
-- struct fotg210_udc *fotg210 = ep->fotg210;
-- u32 value;
-- void __iomem *reg;
--
-- reg = (ep->dir_in) ?
-- fotg210->reg + FOTG210_INEPMPSR(ep->epnum) :
-- fotg210->reg + FOTG210_OUTEPMPSR(ep->epnum);
-- value = ioread32(reg);
-- return value & INOUTEPMPSR_STL_EP ? 1 : 0;
--}
--
--/* For EP0 requests triggered by this driver (currently GET_STATUS response) */
--static void fotg210_ep0_complete(struct usb_ep *_ep, struct usb_request *req)
--{
-- struct fotg210_ep *ep;
-- struct fotg210_udc *fotg210;
--
-- ep = container_of(_ep, struct fotg210_ep, ep);
-- fotg210 = ep->fotg210;
--
-- if (req->status || req->actual != req->length) {
-- dev_warn(&fotg210->gadget.dev, "EP0 request failed: %d\n", req->status);
-- }
--}
--
--static void fotg210_get_status(struct fotg210_udc *fotg210,
-- struct usb_ctrlrequest *ctrl)
--{
-- u8 epnum;
--
-- switch (ctrl->bRequestType & USB_RECIP_MASK) {
-- case USB_RECIP_DEVICE:
-- fotg210->ep0_data = cpu_to_le16(1 << USB_DEVICE_SELF_POWERED);
-- break;
-- case USB_RECIP_INTERFACE:
-- fotg210->ep0_data = cpu_to_le16(0);
-- break;
-- case USB_RECIP_ENDPOINT:
-- epnum = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK;
-- if (epnum)
-- fotg210->ep0_data =
-- cpu_to_le16(fotg210_is_epnstall(fotg210->ep[epnum])
-- << USB_ENDPOINT_HALT);
-- else
-- fotg210_request_error(fotg210);
-- break;
--
-- default:
-- fotg210_request_error(fotg210);
-- return; /* exit */
-- }
--
-- fotg210->ep0_req->buf = &fotg210->ep0_data;
-- fotg210->ep0_req->length = 2;
--
-- spin_unlock(&fotg210->lock);
-- fotg210_ep_queue(fotg210->gadget.ep0, fotg210->ep0_req, GFP_ATOMIC);
-- spin_lock(&fotg210->lock);
--}
--
--static int fotg210_setup_packet(struct fotg210_udc *fotg210,
-- struct usb_ctrlrequest *ctrl)
--{
-- u8 *p = (u8 *)ctrl;
-- u8 ret = 0;
--
-- fotg210_rdsetupp(fotg210, p);
--
-- fotg210->ep[0]->dir_in = ctrl->bRequestType & USB_DIR_IN;
--
-- if (fotg210->gadget.speed == USB_SPEED_UNKNOWN) {
-- u32 value = ioread32(fotg210->reg + FOTG210_DMCR);
-- fotg210->gadget.speed = value & DMCR_HS_EN ?
-- USB_SPEED_HIGH : USB_SPEED_FULL;
-- }
--
-- /* check request */
-- if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
-- switch (ctrl->bRequest) {
-- case USB_REQ_GET_STATUS:
-- fotg210_get_status(fotg210, ctrl);
-- break;
-- case USB_REQ_CLEAR_FEATURE:
-- fotg210_clear_feature(fotg210, ctrl);
-- break;
-- case USB_REQ_SET_FEATURE:
-- fotg210_set_feature(fotg210, ctrl);
-- break;
-- case USB_REQ_SET_ADDRESS:
-- fotg210_set_address(fotg210, ctrl);
-- break;
-- case USB_REQ_SET_CONFIGURATION:
-- fotg210_set_configuration(fotg210);
-- ret = 1;
-- break;
-- default:
-- ret = 1;
-- break;
-- }
-- } else {
-- ret = 1;
-- }
--
-- return ret;
--}
--
--static void fotg210_ep0out(struct fotg210_udc *fotg210)
--{
-- struct fotg210_ep *ep = fotg210->ep[0];
--
-- if (!list_empty(&ep->queue) && !ep->dir_in) {
-- struct fotg210_request *req;
--
-- req = list_first_entry(&ep->queue,
-- struct fotg210_request, queue);
--
-- if (req->req.length)
-- fotg210_start_dma(ep, req);
--
-- if ((req->req.length - req->req.actual) < ep->ep.maxpacket)
-- fotg210_done(ep, req, 0);
-- } else {
-- pr_err("%s : empty queue\n", __func__);
-- }
--}
--
--static void fotg210_ep0in(struct fotg210_udc *fotg210)
--{
-- struct fotg210_ep *ep = fotg210->ep[0];
--
-- if ((!list_empty(&ep->queue)) && (ep->dir_in)) {
-- struct fotg210_request *req;
--
-- req = list_entry(ep->queue.next,
-- struct fotg210_request, queue);
--
-- if (req->req.length)
-- fotg210_start_dma(ep, req);
--
-- if (req->req.actual == req->req.length)
-- fotg210_done(ep, req, 0);
-- } else {
-- fotg210_set_cxdone(fotg210);
-- }
--}
--
--static void fotg210_clear_comabt_int(struct fotg210_udc *fotg210)
--{
-- u32 value = ioread32(fotg210->reg + FOTG210_DISGR0);
--
-- value &= ~DISGR0_CX_COMABT_INT;
-- iowrite32(value, fotg210->reg + FOTG210_DISGR0);
--}
--
--static void fotg210_in_fifo_handler(struct fotg210_ep *ep)
--{
-- struct fotg210_request *req = list_entry(ep->queue.next,
-- struct fotg210_request, queue);
--
-- if (req->req.length)
-- fotg210_start_dma(ep, req);
-- fotg210_done(ep, req, 0);
--}
--
--static void fotg210_out_fifo_handler(struct fotg210_ep *ep)
--{
-- struct fotg210_request *req = list_entry(ep->queue.next,
-- struct fotg210_request, queue);
-- int disgr1 = ioread32(ep->fotg210->reg + FOTG210_DISGR1);
--
-- fotg210_start_dma(ep, req);
--
-- /* Complete the request when it's full or a short packet arrived.
-- * Like other drivers, short_not_ok isn't handled.
-- */
--
-- if (req->req.length == req->req.actual ||
-- (disgr1 & DISGR1_SPK_INT(ep->epnum - 1)))
-- fotg210_done(ep, req, 0);
--}
--
--static irqreturn_t fotg210_irq(int irq, void *_fotg210)
--{
-- struct fotg210_udc *fotg210 = _fotg210;
-- u32 int_grp = ioread32(fotg210->reg + FOTG210_DIGR);
-- u32 int_msk = ioread32(fotg210->reg + FOTG210_DMIGR);
--
-- int_grp &= ~int_msk;
--
-- spin_lock(&fotg210->lock);
--
-- if (int_grp & DIGR_INT_G2) {
-- void __iomem *reg = fotg210->reg + FOTG210_DISGR2;
-- u32 int_grp2 = ioread32(reg);
-- u32 int_msk2 = ioread32(fotg210->reg + FOTG210_DMISGR2);
-- u32 value;
--
-- int_grp2 &= ~int_msk2;
--
-- if (int_grp2 & DISGR2_USBRST_INT) {
-- usb_gadget_udc_reset(&fotg210->gadget,
-- fotg210->driver);
-- value = ioread32(reg);
-- value &= ~DISGR2_USBRST_INT;
-- iowrite32(value, reg);
-- pr_info("fotg210 udc reset\n");
-- }
-- if (int_grp2 & DISGR2_SUSP_INT) {
-- value = ioread32(reg);
-- value &= ~DISGR2_SUSP_INT;
-- iowrite32(value, reg);
-- pr_info("fotg210 udc suspend\n");
-- }
-- if (int_grp2 & DISGR2_RESM_INT) {
-- value = ioread32(reg);
-- value &= ~DISGR2_RESM_INT;
-- iowrite32(value, reg);
-- pr_info("fotg210 udc resume\n");
-- }
-- if (int_grp2 & DISGR2_ISO_SEQ_ERR_INT) {
-- value = ioread32(reg);
-- value &= ~DISGR2_ISO_SEQ_ERR_INT;
-- iowrite32(value, reg);
-- pr_info("fotg210 iso sequence error\n");
-- }
-- if (int_grp2 & DISGR2_ISO_SEQ_ABORT_INT) {
-- value = ioread32(reg);
-- value &= ~DISGR2_ISO_SEQ_ABORT_INT;
-- iowrite32(value, reg);
-- pr_info("fotg210 iso sequence abort\n");
-- }
-- if (int_grp2 & DISGR2_TX0BYTE_INT) {
-- fotg210_clear_tx0byte(fotg210);
-- value = ioread32(reg);
-- value &= ~DISGR2_TX0BYTE_INT;
-- iowrite32(value, reg);
-- pr_info("fotg210 transferred 0 byte\n");
-- }
-- if (int_grp2 & DISGR2_RX0BYTE_INT) {
-- fotg210_clear_rx0byte(fotg210);
-- value = ioread32(reg);
-- value &= ~DISGR2_RX0BYTE_INT;
-- iowrite32(value, reg);
-- pr_info("fotg210 received 0 byte\n");
-- }
-- if (int_grp2 & DISGR2_DMA_ERROR) {
-- value = ioread32(reg);
-- value &= ~DISGR2_DMA_ERROR;
-- iowrite32(value, reg);
-- }
-- }
--
-- if (int_grp & DIGR_INT_G0) {
-- void __iomem *reg = fotg210->reg + FOTG210_DISGR0;
-- u32 int_grp0 = ioread32(reg);
-- u32 int_msk0 = ioread32(fotg210->reg + FOTG210_DMISGR0);
-- struct usb_ctrlrequest ctrl;
--
-- int_grp0 &= ~int_msk0;
--
-- /* the highest priority in this source register */
-- if (int_grp0 & DISGR0_CX_COMABT_INT) {
-- fotg210_clear_comabt_int(fotg210);
-- pr_info("fotg210 CX command abort\n");
-- }
--
-- if (int_grp0 & DISGR0_CX_SETUP_INT) {
-- if (fotg210_setup_packet(fotg210, &ctrl)) {
-- spin_unlock(&fotg210->lock);
-- if (fotg210->driver->setup(&fotg210->gadget,
-- &ctrl) < 0)
-- fotg210_set_cxstall(fotg210);
-- spin_lock(&fotg210->lock);
-- }
-- }
-- if (int_grp0 & DISGR0_CX_COMEND_INT)
-- pr_info("fotg210 cmd end\n");
--
-- if (int_grp0 & DISGR0_CX_IN_INT)
-- fotg210_ep0in(fotg210);
--
-- if (int_grp0 & DISGR0_CX_OUT_INT)
-- fotg210_ep0out(fotg210);
--
-- if (int_grp0 & DISGR0_CX_COMFAIL_INT) {
-- fotg210_set_cxstall(fotg210);
-- pr_info("fotg210 ep0 fail\n");
-- }
-- }
--
-- if (int_grp & DIGR_INT_G1) {
-- void __iomem *reg = fotg210->reg + FOTG210_DISGR1;
-- u32 int_grp1 = ioread32(reg);
-- u32 int_msk1 = ioread32(fotg210->reg + FOTG210_DMISGR1);
-- int fifo;
--
-- int_grp1 &= ~int_msk1;
--
-- for (fifo = 0; fifo < FOTG210_MAX_FIFO_NUM; fifo++) {
-- if (int_grp1 & DISGR1_IN_INT(fifo))
-- fotg210_in_fifo_handler(fotg210->ep[fifo + 1]);
--
-- if ((int_grp1 & DISGR1_OUT_INT(fifo)) ||
-- (int_grp1 & DISGR1_SPK_INT(fifo)))
-- fotg210_out_fifo_handler(fotg210->ep[fifo + 1]);
-- }
-- }
--
-- spin_unlock(&fotg210->lock);
--
-- return IRQ_HANDLED;
--}
--
--static void fotg210_disable_unplug(struct fotg210_udc *fotg210)
--{
-- u32 reg = ioread32(fotg210->reg + FOTG210_PHYTMSR);
--
-- reg &= ~PHYTMSR_UNPLUG;
-- iowrite32(reg, fotg210->reg + FOTG210_PHYTMSR);
--}
--
--static int fotg210_udc_start(struct usb_gadget *g,
-- struct usb_gadget_driver *driver)
--{
-- struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
-- u32 value;
--
-- /* hook up the driver */
-- fotg210->driver = driver;
--
-- /* enable device global interrupt */
-- value = ioread32(fotg210->reg + FOTG210_DMCR);
-- value |= DMCR_GLINT_EN;
-- iowrite32(value, fotg210->reg + FOTG210_DMCR);
--
-- return 0;
--}
--
--static void fotg210_init(struct fotg210_udc *fotg210)
--{
-- u32 value;
--
-- /* disable global interrupt and set int polarity to active high */
-- iowrite32(GMIR_MHC_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
-- fotg210->reg + FOTG210_GMIR);
--
-- /* disable device global interrupt */
-- value = ioread32(fotg210->reg + FOTG210_DMCR);
-- value &= ~DMCR_GLINT_EN;
-- iowrite32(value, fotg210->reg + FOTG210_DMCR);
--
-- /* enable only grp2 irqs we handle */
-- iowrite32(~(DISGR2_DMA_ERROR | DISGR2_RX0BYTE_INT | DISGR2_TX0BYTE_INT
-- | DISGR2_ISO_SEQ_ABORT_INT | DISGR2_ISO_SEQ_ERR_INT
-- | DISGR2_RESM_INT | DISGR2_SUSP_INT | DISGR2_USBRST_INT),
-- fotg210->reg + FOTG210_DMISGR2);
--
-- /* disable all fifo interrupt */
-- iowrite32(~(u32)0, fotg210->reg + FOTG210_DMISGR1);
--
-- /* disable cmd end */
-- value = ioread32(fotg210->reg + FOTG210_DMISGR0);
-- value |= DMISGR0_MCX_COMEND;
-- iowrite32(value, fotg210->reg + FOTG210_DMISGR0);
--}
--
--static int fotg210_udc_stop(struct usb_gadget *g)
--{
-- struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
-- unsigned long flags;
--
-- spin_lock_irqsave(&fotg210->lock, flags);
--
-- fotg210_init(fotg210);
-- fotg210->driver = NULL;
--
-- spin_unlock_irqrestore(&fotg210->lock, flags);
--
-- return 0;
--}
--
--static const struct usb_gadget_ops fotg210_gadget_ops = {
-- .udc_start = fotg210_udc_start,
-- .udc_stop = fotg210_udc_stop,
--};
--
--static int fotg210_udc_remove(struct platform_device *pdev)
--{
-- struct fotg210_udc *fotg210 = platform_get_drvdata(pdev);
-- int i;
--
-- usb_del_gadget_udc(&fotg210->gadget);
-- iounmap(fotg210->reg);
-- free_irq(platform_get_irq(pdev, 0), fotg210);
--
-- fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
-- for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
-- kfree(fotg210->ep[i]);
-- kfree(fotg210);
--
-- return 0;
--}
--
--static int fotg210_udc_probe(struct platform_device *pdev)
--{
-- struct resource *res, *ires;
-- struct fotg210_udc *fotg210 = NULL;
-- struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP];
-- int ret = 0;
-- int i;
--
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- if (!res) {
-- pr_err("platform_get_resource error.\n");
-- return -ENODEV;
-- }
--
-- ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-- if (!ires) {
-- pr_err("platform_get_resource IORESOURCE_IRQ error.\n");
-- return -ENODEV;
-- }
--
-- ret = -ENOMEM;
--
-- /* initialize udc */
-- fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL);
-- if (fotg210 == NULL)
-- goto err;
--
-- for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
-- _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
-- if (_ep[i] == NULL)
-- goto err_alloc;
-- fotg210->ep[i] = _ep[i];
-- }
--
-- fotg210->reg = ioremap(res->start, resource_size(res));
-- if (fotg210->reg == NULL) {
-- pr_err("ioremap error.\n");
-- goto err_alloc;
-- }
--
-- spin_lock_init(&fotg210->lock);
--
-- platform_set_drvdata(pdev, fotg210);
--
-- fotg210->gadget.ops = &fotg210_gadget_ops;
--
-- fotg210->gadget.max_speed = USB_SPEED_HIGH;
-- fotg210->gadget.dev.parent = &pdev->dev;
-- fotg210->gadget.dev.dma_mask = pdev->dev.dma_mask;
-- fotg210->gadget.name = udc_name;
--
-- INIT_LIST_HEAD(&fotg210->gadget.ep_list);
--
-- for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
-- struct fotg210_ep *ep = fotg210->ep[i];
--
-- if (i) {
-- INIT_LIST_HEAD(&fotg210->ep[i]->ep.ep_list);
-- list_add_tail(&fotg210->ep[i]->ep.ep_list,
-- &fotg210->gadget.ep_list);
-- }
-- ep->fotg210 = fotg210;
-- INIT_LIST_HEAD(&ep->queue);
-- ep->ep.name = fotg210_ep_name[i];
-- ep->ep.ops = &fotg210_ep_ops;
-- usb_ep_set_maxpacket_limit(&ep->ep, (unsigned short) ~0);
--
-- if (i == 0) {
-- ep->ep.caps.type_control = true;
-- } else {
-- ep->ep.caps.type_iso = true;
-- ep->ep.caps.type_bulk = true;
-- ep->ep.caps.type_int = true;
-- }
--
-- ep->ep.caps.dir_in = true;
-- ep->ep.caps.dir_out = true;
-- }
-- usb_ep_set_maxpacket_limit(&fotg210->ep[0]->ep, 0x40);
-- fotg210->gadget.ep0 = &fotg210->ep[0]->ep;
-- INIT_LIST_HEAD(&fotg210->gadget.ep0->ep_list);
--
-- fotg210->ep0_req = fotg210_ep_alloc_request(&fotg210->ep[0]->ep,
-- GFP_KERNEL);
-- if (fotg210->ep0_req == NULL)
-- goto err_map;
--
-- fotg210->ep0_req->complete = fotg210_ep0_complete;
--
-- fotg210_init(fotg210);
--
-- fotg210_disable_unplug(fotg210);
--
-- ret = request_irq(ires->start, fotg210_irq, IRQF_SHARED,
-- udc_name, fotg210);
-- if (ret < 0) {
-- pr_err("request_irq error (%d)\n", ret);
-- goto err_req;
-- }
--
-- ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget);
-- if (ret)
-- goto err_add_udc;
--
-- dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
--
-- return 0;
--
--err_add_udc:
-- free_irq(ires->start, fotg210);
--
--err_req:
-- fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
--
--err_map:
-- iounmap(fotg210->reg);
--
--err_alloc:
-- for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
-- kfree(fotg210->ep[i]);
-- kfree(fotg210);
--
--err:
-- return ret;
--}
--
--static struct platform_driver fotg210_driver = {
-- .driver = {
-- .name = udc_name,
-- },
-- .probe = fotg210_udc_probe,
-- .remove = fotg210_udc_remove,
--};
--
--module_platform_driver(fotg210_driver);
--
--MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>");
--MODULE_LICENSE("GPL");
--MODULE_DESCRIPTION(DRIVER_DESC);
---- /dev/null
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -0,0 +1,1239 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * FOTG210 UDC Driver supports Bulk transfer so far
-+ *
-+ * Copyright (C) 2013 Faraday Technology Corporation
-+ *
-+ * Author : Yuan-Hsin Chen <yhchen@faraday-tech.com>
-+ */
-+
-+#include <linux/dma-mapping.h>
-+#include <linux/err.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/usb/ch9.h>
-+#include <linux/usb/gadget.h>
-+
-+#include "fotg210-udc.h"
-+
-+#define DRIVER_DESC "FOTG210 USB Device Controller Driver"
-+#define DRIVER_VERSION "30-April-2013"
-+
-+static const char udc_name[] = "fotg210_udc";
-+static const char * const fotg210_ep_name[] = {
-+ "ep0", "ep1", "ep2", "ep3", "ep4"};
-+
-+static void fotg210_disable_fifo_int(struct fotg210_ep *ep)
-+{
-+ u32 value = ioread32(ep->fotg210->reg + FOTG210_DMISGR1);
-+
-+ if (ep->dir_in)
-+ value |= DMISGR1_MF_IN_INT(ep->epnum - 1);
-+ else
-+ value |= DMISGR1_MF_OUTSPK_INT(ep->epnum - 1);
-+ iowrite32(value, ep->fotg210->reg + FOTG210_DMISGR1);
-+}
-+
-+static void fotg210_enable_fifo_int(struct fotg210_ep *ep)
-+{
-+ u32 value = ioread32(ep->fotg210->reg + FOTG210_DMISGR1);
-+
-+ if (ep->dir_in)
-+ value &= ~DMISGR1_MF_IN_INT(ep->epnum - 1);
-+ else
-+ value &= ~DMISGR1_MF_OUTSPK_INT(ep->epnum - 1);
-+ iowrite32(value, ep->fotg210->reg + FOTG210_DMISGR1);
-+}
-+
-+static void fotg210_set_cxdone(struct fotg210_udc *fotg210)
-+{
-+ u32 value = ioread32(fotg210->reg + FOTG210_DCFESR);
-+
-+ value |= DCFESR_CX_DONE;
-+ iowrite32(value, fotg210->reg + FOTG210_DCFESR);
-+}
-+
-+static void fotg210_done(struct fotg210_ep *ep, struct fotg210_request *req,
-+ int status)
-+{
-+ list_del_init(&req->queue);
-+
-+ /* don't modify queue heads during completion callback */
-+ if (ep->fotg210->gadget.speed == USB_SPEED_UNKNOWN)
-+ req->req.status = -ESHUTDOWN;
-+ else
-+ req->req.status = status;
-+
-+ spin_unlock(&ep->fotg210->lock);
-+ usb_gadget_giveback_request(&ep->ep, &req->req);
-+ spin_lock(&ep->fotg210->lock);
-+
-+ if (ep->epnum) {
-+ if (list_empty(&ep->queue))
-+ fotg210_disable_fifo_int(ep);
-+ } else {
-+ fotg210_set_cxdone(ep->fotg210);
-+ }
-+}
-+
-+static void fotg210_fifo_ep_mapping(struct fotg210_ep *ep, u32 epnum,
-+ u32 dir_in)
-+{
-+ struct fotg210_udc *fotg210 = ep->fotg210;
-+ u32 val;
-+
-+ /* Driver should map an ep to a fifo and then map the fifo
-+ * to the ep. What a brain-damaged design!
-+ */
-+
-+ /* map a fifo to an ep */
-+ val = ioread32(fotg210->reg + FOTG210_EPMAP);
-+ val &= ~EPMAP_FIFONOMSK(epnum, dir_in);
-+ val |= EPMAP_FIFONO(epnum, dir_in);
-+ iowrite32(val, fotg210->reg + FOTG210_EPMAP);
-+
-+ /* map the ep to the fifo */
-+ val = ioread32(fotg210->reg + FOTG210_FIFOMAP);
-+ val &= ~FIFOMAP_EPNOMSK(epnum);
-+ val |= FIFOMAP_EPNO(epnum);
-+ iowrite32(val, fotg210->reg + FOTG210_FIFOMAP);
-+
-+ /* enable fifo */
-+ val = ioread32(fotg210->reg + FOTG210_FIFOCF);
-+ val |= FIFOCF_FIFO_EN(epnum - 1);
-+ iowrite32(val, fotg210->reg + FOTG210_FIFOCF);
-+}
-+
-+static void fotg210_set_fifo_dir(struct fotg210_ep *ep, u32 epnum, u32 dir_in)
-+{
-+ struct fotg210_udc *fotg210 = ep->fotg210;
-+ u32 val;
-+
-+ val = ioread32(fotg210->reg + FOTG210_FIFOMAP);
-+ val |= (dir_in ? FIFOMAP_DIRIN(epnum - 1) : FIFOMAP_DIROUT(epnum - 1));
-+ iowrite32(val, fotg210->reg + FOTG210_FIFOMAP);
-+}
-+
-+static void fotg210_set_tfrtype(struct fotg210_ep *ep, u32 epnum, u32 type)
-+{
-+ struct fotg210_udc *fotg210 = ep->fotg210;
-+ u32 val;
-+
-+ val = ioread32(fotg210->reg + FOTG210_FIFOCF);
-+ val |= FIFOCF_TYPE(type, epnum - 1);
-+ iowrite32(val, fotg210->reg + FOTG210_FIFOCF);
-+}
-+
-+static void fotg210_set_mps(struct fotg210_ep *ep, u32 epnum, u32 mps,
-+ u32 dir_in)
-+{
-+ struct fotg210_udc *fotg210 = ep->fotg210;
-+ u32 val;
-+ u32 offset = dir_in ? FOTG210_INEPMPSR(epnum) :
-+ FOTG210_OUTEPMPSR(epnum);
-+
-+ val = ioread32(fotg210->reg + offset);
-+ val |= INOUTEPMPSR_MPS(mps);
-+ iowrite32(val, fotg210->reg + offset);
-+}
-+
-+static int fotg210_config_ep(struct fotg210_ep *ep,
-+ const struct usb_endpoint_descriptor *desc)
-+{
-+ struct fotg210_udc *fotg210 = ep->fotg210;
-+
-+ fotg210_set_fifo_dir(ep, ep->epnum, ep->dir_in);
-+ fotg210_set_tfrtype(ep, ep->epnum, ep->type);
-+ fotg210_set_mps(ep, ep->epnum, ep->ep.maxpacket, ep->dir_in);
-+ fotg210_fifo_ep_mapping(ep, ep->epnum, ep->dir_in);
-+
-+ fotg210->ep[ep->epnum] = ep;
-+
-+ return 0;
-+}
-+
-+static int fotg210_ep_enable(struct usb_ep *_ep,
-+ const struct usb_endpoint_descriptor *desc)
-+{
-+ struct fotg210_ep *ep;
-+
-+ ep = container_of(_ep, struct fotg210_ep, ep);
-+
-+ ep->desc = desc;
-+ ep->epnum = usb_endpoint_num(desc);
-+ ep->type = usb_endpoint_type(desc);
-+ ep->dir_in = usb_endpoint_dir_in(desc);
-+ ep->ep.maxpacket = usb_endpoint_maxp(desc);
-+
-+ return fotg210_config_ep(ep, desc);
-+}
-+
-+static void fotg210_reset_tseq(struct fotg210_udc *fotg210, u8 epnum)
-+{
-+ struct fotg210_ep *ep = fotg210->ep[epnum];
-+ u32 value;
-+ void __iomem *reg;
-+
-+ reg = (ep->dir_in) ?
-+ fotg210->reg + FOTG210_INEPMPSR(epnum) :
-+ fotg210->reg + FOTG210_OUTEPMPSR(epnum);
-+
-+ /* Note: Driver needs to set and clear INOUTEPMPSR_RESET_TSEQ
-+ * bit. Controller wouldn't clear this bit. WTF!!!
-+ */
-+
-+ value = ioread32(reg);
-+ value |= INOUTEPMPSR_RESET_TSEQ;
-+ iowrite32(value, reg);
-+
-+ value = ioread32(reg);
-+ value &= ~INOUTEPMPSR_RESET_TSEQ;
-+ iowrite32(value, reg);
-+}
-+
-+static int fotg210_ep_release(struct fotg210_ep *ep)
-+{
-+ if (!ep->epnum)
-+ return 0;
-+ ep->epnum = 0;
-+ ep->stall = 0;
-+ ep->wedged = 0;
-+
-+ fotg210_reset_tseq(ep->fotg210, ep->epnum);
-+
-+ return 0;
-+}
-+
-+static int fotg210_ep_disable(struct usb_ep *_ep)
-+{
-+ struct fotg210_ep *ep;
-+ struct fotg210_request *req;
-+ unsigned long flags;
-+
-+ BUG_ON(!_ep);
-+
-+ ep = container_of(_ep, struct fotg210_ep, ep);
-+
-+ while (!list_empty(&ep->queue)) {
-+ req = list_entry(ep->queue.next,
-+ struct fotg210_request, queue);
-+ spin_lock_irqsave(&ep->fotg210->lock, flags);
-+ fotg210_done(ep, req, -ECONNRESET);
-+ spin_unlock_irqrestore(&ep->fotg210->lock, flags);
-+ }
-+
-+ return fotg210_ep_release(ep);
-+}
-+
-+static struct usb_request *fotg210_ep_alloc_request(struct usb_ep *_ep,
-+ gfp_t gfp_flags)
-+{
-+ struct fotg210_request *req;
-+
-+ req = kzalloc(sizeof(struct fotg210_request), gfp_flags);
-+ if (!req)
-+ return NULL;
-+
-+ INIT_LIST_HEAD(&req->queue);
-+
-+ return &req->req;
-+}
-+
-+static void fotg210_ep_free_request(struct usb_ep *_ep,
-+ struct usb_request *_req)
-+{
-+ struct fotg210_request *req;
-+
-+ req = container_of(_req, struct fotg210_request, req);
-+ kfree(req);
-+}
-+
-+static void fotg210_enable_dma(struct fotg210_ep *ep,
-+ dma_addr_t d, u32 len)
-+{
-+ u32 value;
-+ struct fotg210_udc *fotg210 = ep->fotg210;
-+
-+ /* set transfer length and direction */
-+ value = ioread32(fotg210->reg + FOTG210_DMACPSR1);
-+ value &= ~(DMACPSR1_DMA_LEN(0xFFFF) | DMACPSR1_DMA_TYPE(1));
-+ value |= DMACPSR1_DMA_LEN(len) | DMACPSR1_DMA_TYPE(ep->dir_in);
-+ iowrite32(value, fotg210->reg + FOTG210_DMACPSR1);
-+
-+ /* set device DMA target FIFO number */
-+ value = ioread32(fotg210->reg + FOTG210_DMATFNR);
-+ if (ep->epnum)
-+ value |= DMATFNR_ACC_FN(ep->epnum - 1);
-+ else
-+ value |= DMATFNR_ACC_CXF;
-+ iowrite32(value, fotg210->reg + FOTG210_DMATFNR);
-+
-+ /* set DMA memory address */
-+ iowrite32(d, fotg210->reg + FOTG210_DMACPSR2);
-+
-+ /* enable MDMA_EROR and MDMA_CMPLT interrupt */
-+ value = ioread32(fotg210->reg + FOTG210_DMISGR2);
-+ value &= ~(DMISGR2_MDMA_CMPLT | DMISGR2_MDMA_ERROR);
-+ iowrite32(value, fotg210->reg + FOTG210_DMISGR2);
-+
-+ /* start DMA */
-+ value = ioread32(fotg210->reg + FOTG210_DMACPSR1);
-+ value |= DMACPSR1_DMA_START;
-+ iowrite32(value, fotg210->reg + FOTG210_DMACPSR1);
-+}
-+
-+static void fotg210_disable_dma(struct fotg210_ep *ep)
-+{
-+ iowrite32(DMATFNR_DISDMA, ep->fotg210->reg + FOTG210_DMATFNR);
-+}
-+
-+static void fotg210_wait_dma_done(struct fotg210_ep *ep)
-+{
-+ u32 value;
-+
-+ do {
-+ value = ioread32(ep->fotg210->reg + FOTG210_DISGR2);
-+ if ((value & DISGR2_USBRST_INT) ||
-+ (value & DISGR2_DMA_ERROR))
-+ goto dma_reset;
-+ } while (!(value & DISGR2_DMA_CMPLT));
-+
-+ value &= ~DISGR2_DMA_CMPLT;
-+ iowrite32(value, ep->fotg210->reg + FOTG210_DISGR2);
-+ return;
-+
-+dma_reset:
-+ value = ioread32(ep->fotg210->reg + FOTG210_DMACPSR1);
-+ value |= DMACPSR1_DMA_ABORT;
-+ iowrite32(value, ep->fotg210->reg + FOTG210_DMACPSR1);
-+
-+ /* reset fifo */
-+ if (ep->epnum) {
-+ value = ioread32(ep->fotg210->reg +
-+ FOTG210_FIBCR(ep->epnum - 1));
-+ value |= FIBCR_FFRST;
-+ iowrite32(value, ep->fotg210->reg +
-+ FOTG210_FIBCR(ep->epnum - 1));
-+ } else {
-+ value = ioread32(ep->fotg210->reg + FOTG210_DCFESR);
-+ value |= DCFESR_CX_CLR;
-+ iowrite32(value, ep->fotg210->reg + FOTG210_DCFESR);
-+ }
-+}
-+
-+static void fotg210_start_dma(struct fotg210_ep *ep,
-+ struct fotg210_request *req)
-+{
-+ struct device *dev = &ep->fotg210->gadget.dev;
-+ dma_addr_t d;
-+ u8 *buffer;
-+ u32 length;
-+
-+ if (ep->epnum) {
-+ if (ep->dir_in) {
-+ buffer = req->req.buf;
-+ length = req->req.length;
-+ } else {
-+ buffer = req->req.buf + req->req.actual;
-+ length = ioread32(ep->fotg210->reg +
-+ FOTG210_FIBCR(ep->epnum - 1)) & FIBCR_BCFX;
-+ if (length > req->req.length - req->req.actual)
-+ length = req->req.length - req->req.actual;
-+ }
-+ } else {
-+ buffer = req->req.buf + req->req.actual;
-+ if (req->req.length - req->req.actual > ep->ep.maxpacket)
-+ length = ep->ep.maxpacket;
-+ else
-+ length = req->req.length - req->req.actual;
-+ }
-+
-+ d = dma_map_single(dev, buffer, length,
-+ ep->dir_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-+
-+ if (dma_mapping_error(dev, d)) {
-+ pr_err("dma_mapping_error\n");
-+ return;
-+ }
-+
-+ fotg210_enable_dma(ep, d, length);
-+
-+ /* check if dma is done */
-+ fotg210_wait_dma_done(ep);
-+
-+ fotg210_disable_dma(ep);
-+
-+ /* update actual transfer length */
-+ req->req.actual += length;
-+
-+ dma_unmap_single(dev, d, length, DMA_TO_DEVICE);
-+}
-+
-+static void fotg210_ep0_queue(struct fotg210_ep *ep,
-+ struct fotg210_request *req)
-+{
-+ if (!req->req.length) {
-+ fotg210_done(ep, req, 0);
-+ return;
-+ }
-+ if (ep->dir_in) { /* if IN */
-+ fotg210_start_dma(ep, req);
-+ if (req->req.length == req->req.actual)
-+ fotg210_done(ep, req, 0);
-+ } else { /* OUT */
-+ u32 value = ioread32(ep->fotg210->reg + FOTG210_DMISGR0);
-+
-+ value &= ~DMISGR0_MCX_OUT_INT;
-+ iowrite32(value, ep->fotg210->reg + FOTG210_DMISGR0);
-+ }
-+}
-+
-+static int fotg210_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
-+ gfp_t gfp_flags)
-+{
-+ struct fotg210_ep *ep;
-+ struct fotg210_request *req;
-+ unsigned long flags;
-+ int request = 0;
-+
-+ ep = container_of(_ep, struct fotg210_ep, ep);
-+ req = container_of(_req, struct fotg210_request, req);
-+
-+ if (ep->fotg210->gadget.speed == USB_SPEED_UNKNOWN)
-+ return -ESHUTDOWN;
-+
-+ spin_lock_irqsave(&ep->fotg210->lock, flags);
-+
-+ if (list_empty(&ep->queue))
-+ request = 1;
-+
-+ list_add_tail(&req->queue, &ep->queue);
-+
-+ req->req.actual = 0;
-+ req->req.status = -EINPROGRESS;
-+
-+ if (!ep->epnum) /* ep0 */
-+ fotg210_ep0_queue(ep, req);
-+ else if (request && !ep->stall)
-+ fotg210_enable_fifo_int(ep);
-+
-+ spin_unlock_irqrestore(&ep->fotg210->lock, flags);
-+
-+ return 0;
-+}
-+
-+static int fotg210_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
-+{
-+ struct fotg210_ep *ep;
-+ struct fotg210_request *req;
-+ unsigned long flags;
-+
-+ ep = container_of(_ep, struct fotg210_ep, ep);
-+ req = container_of(_req, struct fotg210_request, req);
-+
-+ spin_lock_irqsave(&ep->fotg210->lock, flags);
-+ if (!list_empty(&ep->queue))
-+ fotg210_done(ep, req, -ECONNRESET);
-+ spin_unlock_irqrestore(&ep->fotg210->lock, flags);
-+
-+ return 0;
-+}
-+
-+static void fotg210_set_epnstall(struct fotg210_ep *ep)
-+{
-+ struct fotg210_udc *fotg210 = ep->fotg210;
-+ u32 value;
-+ void __iomem *reg;
-+
-+ /* check if IN FIFO is empty before stall */
-+ if (ep->dir_in) {
-+ do {
-+ value = ioread32(fotg210->reg + FOTG210_DCFESR);
-+ } while (!(value & DCFESR_FIFO_EMPTY(ep->epnum - 1)));
-+ }
-+
-+ reg = (ep->dir_in) ?
-+ fotg210->reg + FOTG210_INEPMPSR(ep->epnum) :
-+ fotg210->reg + FOTG210_OUTEPMPSR(ep->epnum);
-+ value = ioread32(reg);
-+ value |= INOUTEPMPSR_STL_EP;
-+ iowrite32(value, reg);
-+}
-+
-+static void fotg210_clear_epnstall(struct fotg210_ep *ep)
-+{
-+ struct fotg210_udc *fotg210 = ep->fotg210;
-+ u32 value;
-+ void __iomem *reg;
-+
-+ reg = (ep->dir_in) ?
-+ fotg210->reg + FOTG210_INEPMPSR(ep->epnum) :
-+ fotg210->reg + FOTG210_OUTEPMPSR(ep->epnum);
-+ value = ioread32(reg);
-+ value &= ~INOUTEPMPSR_STL_EP;
-+ iowrite32(value, reg);
-+}
-+
-+static int fotg210_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedge)
-+{
-+ struct fotg210_ep *ep;
-+ struct fotg210_udc *fotg210;
-+ unsigned long flags;
-+
-+ ep = container_of(_ep, struct fotg210_ep, ep);
-+
-+ fotg210 = ep->fotg210;
-+
-+ spin_lock_irqsave(&ep->fotg210->lock, flags);
-+
-+ if (value) {
-+ fotg210_set_epnstall(ep);
-+ ep->stall = 1;
-+ if (wedge)
-+ ep->wedged = 1;
-+ } else {
-+ fotg210_reset_tseq(fotg210, ep->epnum);
-+ fotg210_clear_epnstall(ep);
-+ ep->stall = 0;
-+ ep->wedged = 0;
-+ if (!list_empty(&ep->queue))
-+ fotg210_enable_fifo_int(ep);
-+ }
-+
-+ spin_unlock_irqrestore(&ep->fotg210->lock, flags);
-+ return 0;
-+}
-+
-+static int fotg210_ep_set_halt(struct usb_ep *_ep, int value)
-+{
-+ return fotg210_set_halt_and_wedge(_ep, value, 0);
-+}
-+
-+static int fotg210_ep_set_wedge(struct usb_ep *_ep)
-+{
-+ return fotg210_set_halt_and_wedge(_ep, 1, 1);
-+}
-+
-+static void fotg210_ep_fifo_flush(struct usb_ep *_ep)
-+{
-+}
-+
-+static const struct usb_ep_ops fotg210_ep_ops = {
-+ .enable = fotg210_ep_enable,
-+ .disable = fotg210_ep_disable,
-+
-+ .alloc_request = fotg210_ep_alloc_request,
-+ .free_request = fotg210_ep_free_request,
-+
-+ .queue = fotg210_ep_queue,
-+ .dequeue = fotg210_ep_dequeue,
-+
-+ .set_halt = fotg210_ep_set_halt,
-+ .fifo_flush = fotg210_ep_fifo_flush,
-+ .set_wedge = fotg210_ep_set_wedge,
-+};
-+
-+static void fotg210_clear_tx0byte(struct fotg210_udc *fotg210)
-+{
-+ u32 value = ioread32(fotg210->reg + FOTG210_TX0BYTE);
-+
-+ value &= ~(TX0BYTE_EP1 | TX0BYTE_EP2 | TX0BYTE_EP3
-+ | TX0BYTE_EP4);
-+ iowrite32(value, fotg210->reg + FOTG210_TX0BYTE);
-+}
-+
-+static void fotg210_clear_rx0byte(struct fotg210_udc *fotg210)
-+{
-+ u32 value = ioread32(fotg210->reg + FOTG210_RX0BYTE);
-+
-+ value &= ~(RX0BYTE_EP1 | RX0BYTE_EP2 | RX0BYTE_EP3
-+ | RX0BYTE_EP4);
-+ iowrite32(value, fotg210->reg + FOTG210_RX0BYTE);
-+}
-+
-+/* read 8-byte setup packet only */
-+static void fotg210_rdsetupp(struct fotg210_udc *fotg210,
-+ u8 *buffer)
-+{
-+ int i = 0;
-+ u8 *tmp = buffer;
-+ u32 data;
-+ u32 length = 8;
-+
-+ iowrite32(DMATFNR_ACC_CXF, fotg210->reg + FOTG210_DMATFNR);
-+
-+ for (i = (length >> 2); i > 0; i--) {
-+ data = ioread32(fotg210->reg + FOTG210_CXPORT);
-+ *tmp = data & 0xFF;
-+ *(tmp + 1) = (data >> 8) & 0xFF;
-+ *(tmp + 2) = (data >> 16) & 0xFF;
-+ *(tmp + 3) = (data >> 24) & 0xFF;
-+ tmp = tmp + 4;
-+ }
-+
-+ switch (length % 4) {
-+ case 1:
-+ data = ioread32(fotg210->reg + FOTG210_CXPORT);
-+ *tmp = data & 0xFF;
-+ break;
-+ case 2:
-+ data = ioread32(fotg210->reg + FOTG210_CXPORT);
-+ *tmp = data & 0xFF;
-+ *(tmp + 1) = (data >> 8) & 0xFF;
-+ break;
-+ case 3:
-+ data = ioread32(fotg210->reg + FOTG210_CXPORT);
-+ *tmp = data & 0xFF;
-+ *(tmp + 1) = (data >> 8) & 0xFF;
-+ *(tmp + 2) = (data >> 16) & 0xFF;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ iowrite32(DMATFNR_DISDMA, fotg210->reg + FOTG210_DMATFNR);
-+}
-+
-+static void fotg210_set_configuration(struct fotg210_udc *fotg210)
-+{
-+ u32 value = ioread32(fotg210->reg + FOTG210_DAR);
-+
-+ value |= DAR_AFT_CONF;
-+ iowrite32(value, fotg210->reg + FOTG210_DAR);
-+}
-+
-+static void fotg210_set_dev_addr(struct fotg210_udc *fotg210, u32 addr)
-+{
-+ u32 value = ioread32(fotg210->reg + FOTG210_DAR);
-+
-+ value |= (addr & 0x7F);
-+ iowrite32(value, fotg210->reg + FOTG210_DAR);
-+}
-+
-+static void fotg210_set_cxstall(struct fotg210_udc *fotg210)
-+{
-+ u32 value = ioread32(fotg210->reg + FOTG210_DCFESR);
-+
-+ value |= DCFESR_CX_STL;
-+ iowrite32(value, fotg210->reg + FOTG210_DCFESR);
-+}
-+
-+static void fotg210_request_error(struct fotg210_udc *fotg210)
-+{
-+ fotg210_set_cxstall(fotg210);
-+ pr_err("request error!!\n");
-+}
-+
-+static void fotg210_set_address(struct fotg210_udc *fotg210,
-+ struct usb_ctrlrequest *ctrl)
-+{
-+ if (le16_to_cpu(ctrl->wValue) >= 0x0100) {
-+ fotg210_request_error(fotg210);
-+ } else {
-+ fotg210_set_dev_addr(fotg210, le16_to_cpu(ctrl->wValue));
-+ fotg210_set_cxdone(fotg210);
-+ }
-+}
-+
-+static void fotg210_set_feature(struct fotg210_udc *fotg210,
-+ struct usb_ctrlrequest *ctrl)
-+{
-+ switch (ctrl->bRequestType & USB_RECIP_MASK) {
-+ case USB_RECIP_DEVICE:
-+ fotg210_set_cxdone(fotg210);
-+ break;
-+ case USB_RECIP_INTERFACE:
-+ fotg210_set_cxdone(fotg210);
-+ break;
-+ case USB_RECIP_ENDPOINT: {
-+ u8 epnum;
-+ epnum = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK;
-+ if (epnum)
-+ fotg210_set_epnstall(fotg210->ep[epnum]);
-+ else
-+ fotg210_set_cxstall(fotg210);
-+ fotg210_set_cxdone(fotg210);
-+ }
-+ break;
-+ default:
-+ fotg210_request_error(fotg210);
-+ break;
-+ }
-+}
-+
-+static void fotg210_clear_feature(struct fotg210_udc *fotg210,
-+ struct usb_ctrlrequest *ctrl)
-+{
-+ struct fotg210_ep *ep =
-+ fotg210->ep[ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK];
-+
-+ switch (ctrl->bRequestType & USB_RECIP_MASK) {
-+ case USB_RECIP_DEVICE:
-+ fotg210_set_cxdone(fotg210);
-+ break;
-+ case USB_RECIP_INTERFACE:
-+ fotg210_set_cxdone(fotg210);
-+ break;
-+ case USB_RECIP_ENDPOINT:
-+ if (ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK) {
-+ if (ep->wedged) {
-+ fotg210_set_cxdone(fotg210);
-+ break;
-+ }
-+ if (ep->stall)
-+ fotg210_set_halt_and_wedge(&ep->ep, 0, 0);
-+ }
-+ fotg210_set_cxdone(fotg210);
-+ break;
-+ default:
-+ fotg210_request_error(fotg210);
-+ break;
-+ }
-+}
-+
-+static int fotg210_is_epnstall(struct fotg210_ep *ep)
-+{
-+ struct fotg210_udc *fotg210 = ep->fotg210;
-+ u32 value;
-+ void __iomem *reg;
-+
-+ reg = (ep->dir_in) ?
-+ fotg210->reg + FOTG210_INEPMPSR(ep->epnum) :
-+ fotg210->reg + FOTG210_OUTEPMPSR(ep->epnum);
-+ value = ioread32(reg);
-+ return value & INOUTEPMPSR_STL_EP ? 1 : 0;
-+}
-+
-+/* For EP0 requests triggered by this driver (currently GET_STATUS response) */
-+static void fotg210_ep0_complete(struct usb_ep *_ep, struct usb_request *req)
-+{
-+ struct fotg210_ep *ep;
-+ struct fotg210_udc *fotg210;
-+
-+ ep = container_of(_ep, struct fotg210_ep, ep);
-+ fotg210 = ep->fotg210;
-+
-+ if (req->status || req->actual != req->length) {
-+ dev_warn(&fotg210->gadget.dev, "EP0 request failed: %d\n", req->status);
-+ }
-+}
-+
-+static void fotg210_get_status(struct fotg210_udc *fotg210,
-+ struct usb_ctrlrequest *ctrl)
-+{
-+ u8 epnum;
-+
-+ switch (ctrl->bRequestType & USB_RECIP_MASK) {
-+ case USB_RECIP_DEVICE:
-+ fotg210->ep0_data = cpu_to_le16(1 << USB_DEVICE_SELF_POWERED);
-+ break;
-+ case USB_RECIP_INTERFACE:
-+ fotg210->ep0_data = cpu_to_le16(0);
-+ break;
-+ case USB_RECIP_ENDPOINT:
-+ epnum = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK;
-+ if (epnum)
-+ fotg210->ep0_data =
-+ cpu_to_le16(fotg210_is_epnstall(fotg210->ep[epnum])
-+ << USB_ENDPOINT_HALT);
-+ else
-+ fotg210_request_error(fotg210);
-+ break;
-+
-+ default:
-+ fotg210_request_error(fotg210);
-+ return; /* exit */
-+ }
-+
-+ fotg210->ep0_req->buf = &fotg210->ep0_data;
-+ fotg210->ep0_req->length = 2;
-+
-+ spin_unlock(&fotg210->lock);
-+ fotg210_ep_queue(fotg210->gadget.ep0, fotg210->ep0_req, GFP_ATOMIC);
-+ spin_lock(&fotg210->lock);
-+}
-+
-+static int fotg210_setup_packet(struct fotg210_udc *fotg210,
-+ struct usb_ctrlrequest *ctrl)
-+{
-+ u8 *p = (u8 *)ctrl;
-+ u8 ret = 0;
-+
-+ fotg210_rdsetupp(fotg210, p);
-+
-+ fotg210->ep[0]->dir_in = ctrl->bRequestType & USB_DIR_IN;
-+
-+ if (fotg210->gadget.speed == USB_SPEED_UNKNOWN) {
-+ u32 value = ioread32(fotg210->reg + FOTG210_DMCR);
-+ fotg210->gadget.speed = value & DMCR_HS_EN ?
-+ USB_SPEED_HIGH : USB_SPEED_FULL;
-+ }
-+
-+ /* check request */
-+ if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
-+ switch (ctrl->bRequest) {
-+ case USB_REQ_GET_STATUS:
-+ fotg210_get_status(fotg210, ctrl);
-+ break;
-+ case USB_REQ_CLEAR_FEATURE:
-+ fotg210_clear_feature(fotg210, ctrl);
-+ break;
-+ case USB_REQ_SET_FEATURE:
-+ fotg210_set_feature(fotg210, ctrl);
-+ break;
-+ case USB_REQ_SET_ADDRESS:
-+ fotg210_set_address(fotg210, ctrl);
-+ break;
-+ case USB_REQ_SET_CONFIGURATION:
-+ fotg210_set_configuration(fotg210);
-+ ret = 1;
-+ break;
-+ default:
-+ ret = 1;
-+ break;
-+ }
-+ } else {
-+ ret = 1;
-+ }
-+
-+ return ret;
-+}
-+
-+static void fotg210_ep0out(struct fotg210_udc *fotg210)
-+{
-+ struct fotg210_ep *ep = fotg210->ep[0];
-+
-+ if (!list_empty(&ep->queue) && !ep->dir_in) {
-+ struct fotg210_request *req;
-+
-+ req = list_first_entry(&ep->queue,
-+ struct fotg210_request, queue);
-+
-+ if (req->req.length)
-+ fotg210_start_dma(ep, req);
-+
-+ if ((req->req.length - req->req.actual) < ep->ep.maxpacket)
-+ fotg210_done(ep, req, 0);
-+ } else {
-+ pr_err("%s : empty queue\n", __func__);
-+ }
-+}
-+
-+static void fotg210_ep0in(struct fotg210_udc *fotg210)
-+{
-+ struct fotg210_ep *ep = fotg210->ep[0];
-+
-+ if ((!list_empty(&ep->queue)) && (ep->dir_in)) {
-+ struct fotg210_request *req;
-+
-+ req = list_entry(ep->queue.next,
-+ struct fotg210_request, queue);
-+
-+ if (req->req.length)
-+ fotg210_start_dma(ep, req);
-+
-+ if (req->req.actual == req->req.length)
-+ fotg210_done(ep, req, 0);
-+ } else {
-+ fotg210_set_cxdone(fotg210);
-+ }
-+}
-+
-+static void fotg210_clear_comabt_int(struct fotg210_udc *fotg210)
-+{
-+ u32 value = ioread32(fotg210->reg + FOTG210_DISGR0);
-+
-+ value &= ~DISGR0_CX_COMABT_INT;
-+ iowrite32(value, fotg210->reg + FOTG210_DISGR0);
-+}
-+
-+static void fotg210_in_fifo_handler(struct fotg210_ep *ep)
-+{
-+ struct fotg210_request *req = list_entry(ep->queue.next,
-+ struct fotg210_request, queue);
-+
-+ if (req->req.length)
-+ fotg210_start_dma(ep, req);
-+ fotg210_done(ep, req, 0);
-+}
-+
-+static void fotg210_out_fifo_handler(struct fotg210_ep *ep)
-+{
-+ struct fotg210_request *req = list_entry(ep->queue.next,
-+ struct fotg210_request, queue);
-+ int disgr1 = ioread32(ep->fotg210->reg + FOTG210_DISGR1);
-+
-+ fotg210_start_dma(ep, req);
-+
-+ /* Complete the request when it's full or a short packet arrived.
-+ * Like other drivers, short_not_ok isn't handled.
-+ */
-+
-+ if (req->req.length == req->req.actual ||
-+ (disgr1 & DISGR1_SPK_INT(ep->epnum - 1)))
-+ fotg210_done(ep, req, 0);
-+}
-+
-+static irqreturn_t fotg210_irq(int irq, void *_fotg210)
-+{
-+ struct fotg210_udc *fotg210 = _fotg210;
-+ u32 int_grp = ioread32(fotg210->reg + FOTG210_DIGR);
-+ u32 int_msk = ioread32(fotg210->reg + FOTG210_DMIGR);
-+
-+ int_grp &= ~int_msk;
-+
-+ spin_lock(&fotg210->lock);
-+
-+ if (int_grp & DIGR_INT_G2) {
-+ void __iomem *reg = fotg210->reg + FOTG210_DISGR2;
-+ u32 int_grp2 = ioread32(reg);
-+ u32 int_msk2 = ioread32(fotg210->reg + FOTG210_DMISGR2);
-+ u32 value;
-+
-+ int_grp2 &= ~int_msk2;
-+
-+ if (int_grp2 & DISGR2_USBRST_INT) {
-+ usb_gadget_udc_reset(&fotg210->gadget,
-+ fotg210->driver);
-+ value = ioread32(reg);
-+ value &= ~DISGR2_USBRST_INT;
-+ iowrite32(value, reg);
-+ pr_info("fotg210 udc reset\n");
-+ }
-+ if (int_grp2 & DISGR2_SUSP_INT) {
-+ value = ioread32(reg);
-+ value &= ~DISGR2_SUSP_INT;
-+ iowrite32(value, reg);
-+ pr_info("fotg210 udc suspend\n");
-+ }
-+ if (int_grp2 & DISGR2_RESM_INT) {
-+ value = ioread32(reg);
-+ value &= ~DISGR2_RESM_INT;
-+ iowrite32(value, reg);
-+ pr_info("fotg210 udc resume\n");
-+ }
-+ if (int_grp2 & DISGR2_ISO_SEQ_ERR_INT) {
-+ value = ioread32(reg);
-+ value &= ~DISGR2_ISO_SEQ_ERR_INT;
-+ iowrite32(value, reg);
-+ pr_info("fotg210 iso sequence error\n");
-+ }
-+ if (int_grp2 & DISGR2_ISO_SEQ_ABORT_INT) {
-+ value = ioread32(reg);
-+ value &= ~DISGR2_ISO_SEQ_ABORT_INT;
-+ iowrite32(value, reg);
-+ pr_info("fotg210 iso sequence abort\n");
-+ }
-+ if (int_grp2 & DISGR2_TX0BYTE_INT) {
-+ fotg210_clear_tx0byte(fotg210);
-+ value = ioread32(reg);
-+ value &= ~DISGR2_TX0BYTE_INT;
-+ iowrite32(value, reg);
-+ pr_info("fotg210 transferred 0 byte\n");
-+ }
-+ if (int_grp2 & DISGR2_RX0BYTE_INT) {
-+ fotg210_clear_rx0byte(fotg210);
-+ value = ioread32(reg);
-+ value &= ~DISGR2_RX0BYTE_INT;
-+ iowrite32(value, reg);
-+ pr_info("fotg210 received 0 byte\n");
-+ }
-+ if (int_grp2 & DISGR2_DMA_ERROR) {
-+ value = ioread32(reg);
-+ value &= ~DISGR2_DMA_ERROR;
-+ iowrite32(value, reg);
-+ }
-+ }
-+
-+ if (int_grp & DIGR_INT_G0) {
-+ void __iomem *reg = fotg210->reg + FOTG210_DISGR0;
-+ u32 int_grp0 = ioread32(reg);
-+ u32 int_msk0 = ioread32(fotg210->reg + FOTG210_DMISGR0);
-+ struct usb_ctrlrequest ctrl;
-+
-+ int_grp0 &= ~int_msk0;
-+
-+ /* the highest priority in this source register */
-+ if (int_grp0 & DISGR0_CX_COMABT_INT) {
-+ fotg210_clear_comabt_int(fotg210);
-+ pr_info("fotg210 CX command abort\n");
-+ }
-+
-+ if (int_grp0 & DISGR0_CX_SETUP_INT) {
-+ if (fotg210_setup_packet(fotg210, &ctrl)) {
-+ spin_unlock(&fotg210->lock);
-+ if (fotg210->driver->setup(&fotg210->gadget,
-+ &ctrl) < 0)
-+ fotg210_set_cxstall(fotg210);
-+ spin_lock(&fotg210->lock);
-+ }
-+ }
-+ if (int_grp0 & DISGR0_CX_COMEND_INT)
-+ pr_info("fotg210 cmd end\n");
-+
-+ if (int_grp0 & DISGR0_CX_IN_INT)
-+ fotg210_ep0in(fotg210);
-+
-+ if (int_grp0 & DISGR0_CX_OUT_INT)
-+ fotg210_ep0out(fotg210);
-+
-+ if (int_grp0 & DISGR0_CX_COMFAIL_INT) {
-+ fotg210_set_cxstall(fotg210);
-+ pr_info("fotg210 ep0 fail\n");
-+ }
-+ }
-+
-+ if (int_grp & DIGR_INT_G1) {
-+ void __iomem *reg = fotg210->reg + FOTG210_DISGR1;
-+ u32 int_grp1 = ioread32(reg);
-+ u32 int_msk1 = ioread32(fotg210->reg + FOTG210_DMISGR1);
-+ int fifo;
-+
-+ int_grp1 &= ~int_msk1;
-+
-+ for (fifo = 0; fifo < FOTG210_MAX_FIFO_NUM; fifo++) {
-+ if (int_grp1 & DISGR1_IN_INT(fifo))
-+ fotg210_in_fifo_handler(fotg210->ep[fifo + 1]);
-+
-+ if ((int_grp1 & DISGR1_OUT_INT(fifo)) ||
-+ (int_grp1 & DISGR1_SPK_INT(fifo)))
-+ fotg210_out_fifo_handler(fotg210->ep[fifo + 1]);
-+ }
-+ }
-+
-+ spin_unlock(&fotg210->lock);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void fotg210_disable_unplug(struct fotg210_udc *fotg210)
-+{
-+ u32 reg = ioread32(fotg210->reg + FOTG210_PHYTMSR);
-+
-+ reg &= ~PHYTMSR_UNPLUG;
-+ iowrite32(reg, fotg210->reg + FOTG210_PHYTMSR);
-+}
-+
-+static int fotg210_udc_start(struct usb_gadget *g,
-+ struct usb_gadget_driver *driver)
-+{
-+ struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
-+ u32 value;
-+
-+ /* hook up the driver */
-+ fotg210->driver = driver;
-+
-+ /* enable device global interrupt */
-+ value = ioread32(fotg210->reg + FOTG210_DMCR);
-+ value |= DMCR_GLINT_EN;
-+ iowrite32(value, fotg210->reg + FOTG210_DMCR);
-+
-+ return 0;
-+}
-+
-+static void fotg210_init(struct fotg210_udc *fotg210)
-+{
-+ u32 value;
-+
-+ /* disable global interrupt and set int polarity to active high */
-+ iowrite32(GMIR_MHC_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
-+ fotg210->reg + FOTG210_GMIR);
-+
-+ /* disable device global interrupt */
-+ value = ioread32(fotg210->reg + FOTG210_DMCR);
-+ value &= ~DMCR_GLINT_EN;
-+ iowrite32(value, fotg210->reg + FOTG210_DMCR);
-+
-+ /* enable only grp2 irqs we handle */
-+ iowrite32(~(DISGR2_DMA_ERROR | DISGR2_RX0BYTE_INT | DISGR2_TX0BYTE_INT
-+ | DISGR2_ISO_SEQ_ABORT_INT | DISGR2_ISO_SEQ_ERR_INT
-+ | DISGR2_RESM_INT | DISGR2_SUSP_INT | DISGR2_USBRST_INT),
-+ fotg210->reg + FOTG210_DMISGR2);
-+
-+ /* disable all fifo interrupt */
-+ iowrite32(~(u32)0, fotg210->reg + FOTG210_DMISGR1);
-+
-+ /* disable cmd end */
-+ value = ioread32(fotg210->reg + FOTG210_DMISGR0);
-+ value |= DMISGR0_MCX_COMEND;
-+ iowrite32(value, fotg210->reg + FOTG210_DMISGR0);
-+}
-+
-+static int fotg210_udc_stop(struct usb_gadget *g)
-+{
-+ struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&fotg210->lock, flags);
-+
-+ fotg210_init(fotg210);
-+ fotg210->driver = NULL;
-+
-+ spin_unlock_irqrestore(&fotg210->lock, flags);
-+
-+ return 0;
-+}
-+
-+static const struct usb_gadget_ops fotg210_gadget_ops = {
-+ .udc_start = fotg210_udc_start,
-+ .udc_stop = fotg210_udc_stop,
-+};
-+
-+static int fotg210_udc_remove(struct platform_device *pdev)
-+{
-+ struct fotg210_udc *fotg210 = platform_get_drvdata(pdev);
-+ int i;
-+
-+ usb_del_gadget_udc(&fotg210->gadget);
-+ iounmap(fotg210->reg);
-+ free_irq(platform_get_irq(pdev, 0), fotg210);
-+
-+ fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
-+ for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
-+ kfree(fotg210->ep[i]);
-+ kfree(fotg210);
-+
-+ return 0;
-+}
-+
-+static int fotg210_udc_probe(struct platform_device *pdev)
-+{
-+ struct resource *res, *ires;
-+ struct fotg210_udc *fotg210 = NULL;
-+ struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP];
-+ int ret = 0;
-+ int i;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res) {
-+ pr_err("platform_get_resource error.\n");
-+ return -ENODEV;
-+ }
-+
-+ ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-+ if (!ires) {
-+ pr_err("platform_get_resource IORESOURCE_IRQ error.\n");
-+ return -ENODEV;
-+ }
-+
-+ ret = -ENOMEM;
-+
-+ /* initialize udc */
-+ fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL);
-+ if (fotg210 == NULL)
-+ goto err;
-+
-+ for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
-+ _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
-+ if (_ep[i] == NULL)
-+ goto err_alloc;
-+ fotg210->ep[i] = _ep[i];
-+ }
-+
-+ fotg210->reg = ioremap(res->start, resource_size(res));
-+ if (fotg210->reg == NULL) {
-+ pr_err("ioremap error.\n");
-+ goto err_alloc;
-+ }
-+
-+ spin_lock_init(&fotg210->lock);
-+
-+ platform_set_drvdata(pdev, fotg210);
-+
-+ fotg210->gadget.ops = &fotg210_gadget_ops;
-+
-+ fotg210->gadget.max_speed = USB_SPEED_HIGH;
-+ fotg210->gadget.dev.parent = &pdev->dev;
-+ fotg210->gadget.dev.dma_mask = pdev->dev.dma_mask;
-+ fotg210->gadget.name = udc_name;
-+
-+ INIT_LIST_HEAD(&fotg210->gadget.ep_list);
-+
-+ for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
-+ struct fotg210_ep *ep = fotg210->ep[i];
-+
-+ if (i) {
-+ INIT_LIST_HEAD(&fotg210->ep[i]->ep.ep_list);
-+ list_add_tail(&fotg210->ep[i]->ep.ep_list,
-+ &fotg210->gadget.ep_list);
-+ }
-+ ep->fotg210 = fotg210;
-+ INIT_LIST_HEAD(&ep->queue);
-+ ep->ep.name = fotg210_ep_name[i];
-+ ep->ep.ops = &fotg210_ep_ops;
-+ usb_ep_set_maxpacket_limit(&ep->ep, (unsigned short) ~0);
-+
-+ if (i == 0) {
-+ ep->ep.caps.type_control = true;
-+ } else {
-+ ep->ep.caps.type_iso = true;
-+ ep->ep.caps.type_bulk = true;
-+ ep->ep.caps.type_int = true;
-+ }
-+
-+ ep->ep.caps.dir_in = true;
-+ ep->ep.caps.dir_out = true;
-+ }
-+ usb_ep_set_maxpacket_limit(&fotg210->ep[0]->ep, 0x40);
-+ fotg210->gadget.ep0 = &fotg210->ep[0]->ep;
-+ INIT_LIST_HEAD(&fotg210->gadget.ep0->ep_list);
-+
-+ fotg210->ep0_req = fotg210_ep_alloc_request(&fotg210->ep[0]->ep,
-+ GFP_KERNEL);
-+ if (fotg210->ep0_req == NULL)
-+ goto err_map;
-+
-+ fotg210->ep0_req->complete = fotg210_ep0_complete;
-+
-+ fotg210_init(fotg210);
-+
-+ fotg210_disable_unplug(fotg210);
-+
-+ ret = request_irq(ires->start, fotg210_irq, IRQF_SHARED,
-+ udc_name, fotg210);
-+ if (ret < 0) {
-+ pr_err("request_irq error (%d)\n", ret);
-+ goto err_req;
-+ }
-+
-+ ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget);
-+ if (ret)
-+ goto err_add_udc;
-+
-+ dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
-+
-+ return 0;
-+
-+err_add_udc:
-+ free_irq(ires->start, fotg210);
-+
-+err_req:
-+ fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
-+
-+err_map:
-+ iounmap(fotg210->reg);
-+
-+err_alloc:
-+ for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
-+ kfree(fotg210->ep[i]);
-+ kfree(fotg210);
-+
-+err:
-+ return ret;
-+}
-+
-+static struct platform_driver fotg210_driver = {
-+ .driver = {
-+ .name = udc_name,
-+ },
-+ .probe = fotg210_udc_probe,
-+ .remove = fotg210_udc_remove,
-+};
-+
-+module_platform_driver(fotg210_driver);
-+
-+MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION(DRIVER_DESC);
---- a/drivers/usb/gadget/udc/Kconfig
-+++ b/drivers/usb/gadget/udc/Kconfig
-@@ -108,17 +108,6 @@ config USB_FUSB300
- help
- Faraday usb device controller FUSB300 driver
-
--config USB_FOTG210_UDC
-- depends on HAS_DMA
-- tristate "Faraday FOTG210 USB Peripheral Controller"
-- help
-- Faraday USB2.0 OTG controller which can be configured as
-- high speed or full speed USB device. This driver supppors
-- Bulk Transfer so far.
--
-- Say "y" to link the driver statically, or "m" to build a
-- dynamically linked module called "fotg210_udc".
--
- config USB_GR_UDC
- tristate "Aeroflex Gaisler GRUSBDC USB Peripheral Controller Driver"
- depends on HAS_DMA
---- a/drivers/usb/gadget/udc/Makefile
-+++ b/drivers/usb/gadget/udc/Makefile
-@@ -34,7 +34,6 @@ obj-$(CONFIG_USB_EG20T) += pch_udc.o
- obj-$(CONFIG_USB_MV_UDC) += mv_udc.o
- mv_udc-y := mv_udc_core.o
- obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o
--obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o
- obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o
- obj-$(CONFIG_USB_GR_UDC) += gr_udc.o
- obj-$(CONFIG_USB_GADGET_XILINX) += udc-xilinx.o
---- a/drivers/usb/host/Kconfig
-+++ b/drivers/usb/host/Kconfig
-@@ -389,17 +389,6 @@ config USB_ISP1362_HCD
- To compile this driver as a module, choose M here: the
- module will be called isp1362-hcd.
-
--config USB_FOTG210_HCD
-- tristate "FOTG210 HCD support"
-- depends on USB && HAS_DMA && HAS_IOMEM
-- help
-- Faraday FOTG210 is an OTG controller which can be configured as
-- an USB2.0 host. It is designed to meet USB2.0 EHCI specification
-- with minor modification.
--
-- To compile this driver as a module, choose M here: the
-- module will be called fotg210-hcd.
--
- config USB_MAX3421_HCD
- tristate "MAX3421 HCD (USB-over-SPI) support"
- depends on USB && SPI
---- a/drivers/usb/host/Makefile
-+++ b/drivers/usb/host/Makefile
-@@ -84,6 +84,5 @@ obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o
- obj-$(CONFIG_USB_EHCI_MV) += ehci-mv.o
- obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o
- obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o
--obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o
- obj-$(CONFIG_USB_MAX3421_HCD) += max3421-hcd.o
- obj-$(CONFIG_USB_XEN_HCD) += xen-hcd.o
---- /dev/null
-+++ b/drivers/usb/fotg210/fotg210-hcd.h
-@@ -0,0 +1,688 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __LINUX_FOTG210_H
-+#define __LINUX_FOTG210_H
-+
-+#include <linux/usb/ehci-dbgp.h>
-+
-+/* definitions used for the EHCI driver */
-+
-+/*
-+ * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
-+ * __leXX (normally) or __beXX (given FOTG210_BIG_ENDIAN_DESC), depending on
-+ * the host controller implementation.
-+ *
-+ * To facilitate the strongest possible byte-order checking from "sparse"
-+ * and so on, we use __leXX unless that's not practical.
-+ */
-+#define __hc32 __le32
-+#define __hc16 __le16
-+
-+/* statistics can be kept for tuning/monitoring */
-+struct fotg210_stats {
-+ /* irq usage */
-+ unsigned long normal;
-+ unsigned long error;
-+ unsigned long iaa;
-+ unsigned long lost_iaa;
-+
-+ /* termination of urbs from core */
-+ unsigned long complete;
-+ unsigned long unlink;
-+};
-+
-+/* fotg210_hcd->lock guards shared data against other CPUs:
-+ * fotg210_hcd: async, unlink, periodic (and shadow), ...
-+ * usb_host_endpoint: hcpriv
-+ * fotg210_qh: qh_next, qtd_list
-+ * fotg210_qtd: qtd_list
-+ *
-+ * Also, hold this lock when talking to HC registers or
-+ * when updating hw_* fields in shared qh/qtd/... structures.
-+ */
-+
-+#define FOTG210_MAX_ROOT_PORTS 1 /* see HCS_N_PORTS */
-+
-+/*
-+ * fotg210_rh_state values of FOTG210_RH_RUNNING or above mean that the
-+ * controller may be doing DMA. Lower values mean there's no DMA.
-+ */
-+enum fotg210_rh_state {
-+ FOTG210_RH_HALTED,
-+ FOTG210_RH_SUSPENDED,
-+ FOTG210_RH_RUNNING,
-+ FOTG210_RH_STOPPING
-+};
-+
-+/*
-+ * Timer events, ordered by increasing delay length.
-+ * Always update event_delays_ns[] and event_handlers[] (defined in
-+ * ehci-timer.c) in parallel with this list.
-+ */
-+enum fotg210_hrtimer_event {
-+ FOTG210_HRTIMER_POLL_ASS, /* Poll for async schedule off */
-+ FOTG210_HRTIMER_POLL_PSS, /* Poll for periodic schedule off */
-+ FOTG210_HRTIMER_POLL_DEAD, /* Wait for dead controller to stop */
-+ FOTG210_HRTIMER_UNLINK_INTR, /* Wait for interrupt QH unlink */
-+ FOTG210_HRTIMER_FREE_ITDS, /* Wait for unused iTDs and siTDs */
-+ FOTG210_HRTIMER_ASYNC_UNLINKS, /* Unlink empty async QHs */
-+ FOTG210_HRTIMER_IAA_WATCHDOG, /* Handle lost IAA interrupts */
-+ FOTG210_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */
-+ FOTG210_HRTIMER_DISABLE_ASYNC, /* Wait to disable async sched */
-+ FOTG210_HRTIMER_IO_WATCHDOG, /* Check for missing IRQs */
-+ FOTG210_HRTIMER_NUM_EVENTS /* Must come last */
-+};
-+#define FOTG210_HRTIMER_NO_EVENT 99
-+
-+struct fotg210_hcd { /* one per controller */
-+ /* timing support */
-+ enum fotg210_hrtimer_event next_hrtimer_event;
-+ unsigned enabled_hrtimer_events;
-+ ktime_t hr_timeouts[FOTG210_HRTIMER_NUM_EVENTS];
-+ struct hrtimer hrtimer;
-+
-+ int PSS_poll_count;
-+ int ASS_poll_count;
-+ int died_poll_count;
-+
-+ /* glue to PCI and HCD framework */
-+ struct fotg210_caps __iomem *caps;
-+ struct fotg210_regs __iomem *regs;
-+ struct ehci_dbg_port __iomem *debug;
-+
-+ __u32 hcs_params; /* cached register copy */
-+ spinlock_t lock;
-+ enum fotg210_rh_state rh_state;
-+
-+ /* general schedule support */
-+ bool scanning:1;
-+ bool need_rescan:1;
-+ bool intr_unlinking:1;
-+ bool async_unlinking:1;
-+ bool shutdown:1;
-+ struct fotg210_qh *qh_scan_next;
-+
-+ /* async schedule support */
-+ struct fotg210_qh *async;
-+ struct fotg210_qh *dummy; /* For AMD quirk use */
-+ struct fotg210_qh *async_unlink;
-+ struct fotg210_qh *async_unlink_last;
-+ struct fotg210_qh *async_iaa;
-+ unsigned async_unlink_cycle;
-+ unsigned async_count; /* async activity count */
-+
-+ /* periodic schedule support */
-+#define DEFAULT_I_TDPS 1024 /* some HCs can do less */
-+ unsigned periodic_size;
-+ __hc32 *periodic; /* hw periodic table */
-+ dma_addr_t periodic_dma;
-+ struct list_head intr_qh_list;
-+ unsigned i_thresh; /* uframes HC might cache */
-+
-+ union fotg210_shadow *pshadow; /* mirror hw periodic table */
-+ struct fotg210_qh *intr_unlink;
-+ struct fotg210_qh *intr_unlink_last;
-+ unsigned intr_unlink_cycle;
-+ unsigned now_frame; /* frame from HC hardware */
-+ unsigned next_frame; /* scan periodic, start here */
-+ unsigned intr_count; /* intr activity count */
-+ unsigned isoc_count; /* isoc activity count */
-+ unsigned periodic_count; /* periodic activity count */
-+ /* max periodic time per uframe */
-+ unsigned uframe_periodic_max;
-+
-+
-+ /* list of itds completed while now_frame was still active */
-+ struct list_head cached_itd_list;
-+ struct fotg210_itd *last_itd_to_free;
-+
-+ /* per root hub port */
-+ unsigned long reset_done[FOTG210_MAX_ROOT_PORTS];
-+
-+ /* bit vectors (one bit per port)
-+ * which ports were already suspended at the start of a bus suspend
-+ */
-+ unsigned long bus_suspended;
-+
-+ /* which ports are edicated to the companion controller */
-+ unsigned long companion_ports;
-+
-+ /* which ports are owned by the companion during a bus suspend */
-+ unsigned long owned_ports;
-+
-+ /* which ports have the change-suspend feature turned on */
-+ unsigned long port_c_suspend;
-+
-+ /* which ports are suspended */
-+ unsigned long suspended_ports;
-+
-+ /* which ports have started to resume */
-+ unsigned long resuming_ports;
-+
-+ /* per-HC memory pools (could be per-bus, but ...) */
-+ struct dma_pool *qh_pool; /* qh per active urb */
-+ struct dma_pool *qtd_pool; /* one or more per qh */
-+ struct dma_pool *itd_pool; /* itd per iso urb */
-+
-+ unsigned random_frame;
-+ unsigned long next_statechange;
-+ ktime_t last_periodic_enable;
-+ u32 command;
-+
-+ /* SILICON QUIRKS */
-+ unsigned need_io_watchdog:1;
-+ unsigned fs_i_thresh:1; /* Intel iso scheduling */
-+
-+ u8 sbrn; /* packed release number */
-+
-+ /* irq statistics */
-+#ifdef FOTG210_STATS
-+ struct fotg210_stats stats;
-+# define INCR(x) ((x)++)
-+#else
-+# define INCR(x) do {} while (0)
-+#endif
-+
-+ /* silicon clock */
-+ struct clk *pclk;
-+};
-+
-+/* convert between an HCD pointer and the corresponding FOTG210_HCD */
-+static inline struct fotg210_hcd *hcd_to_fotg210(struct usb_hcd *hcd)
-+{
-+ return (struct fotg210_hcd *)(hcd->hcd_priv);
-+}
-+static inline struct usb_hcd *fotg210_to_hcd(struct fotg210_hcd *fotg210)
-+{
-+ return container_of((void *) fotg210, struct usb_hcd, hcd_priv);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
-+
-+/* Section 2.2 Host Controller Capability Registers */
-+struct fotg210_caps {
-+ /* these fields are specified as 8 and 16 bit registers,
-+ * but some hosts can't perform 8 or 16 bit PCI accesses.
-+ * some hosts treat caplength and hciversion as parts of a 32-bit
-+ * register, others treat them as two separate registers, this
-+ * affects the memory map for big endian controllers.
-+ */
-+ u32 hc_capbase;
-+#define HC_LENGTH(fotg210, p) (0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
-+ (fotg210_big_endian_capbase(fotg210) ? 24 : 0)))
-+#define HC_VERSION(fotg210, p) (0xffff&((p) >> /* bits 31:16 / offset 02h */ \
-+ (fotg210_big_endian_capbase(fotg210) ? 0 : 16)))
-+ u32 hcs_params; /* HCSPARAMS - offset 0x4 */
-+#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */
-+
-+ u32 hcc_params; /* HCCPARAMS - offset 0x8 */
-+#define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */
-+#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/
-+ u8 portroute[8]; /* nibbles for routing - offset 0xC */
-+};
-+
-+
-+/* Section 2.3 Host Controller Operational Registers */
-+struct fotg210_regs {
-+
-+ /* USBCMD: offset 0x00 */
-+ u32 command;
-+
-+/* EHCI 1.1 addendum */
-+/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
-+#define CMD_PARK (1<<11) /* enable "park" on async qh */
-+#define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */
-+#define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */
-+#define CMD_ASE (1<<5) /* async schedule enable */
-+#define CMD_PSE (1<<4) /* periodic schedule enable */
-+/* 3:2 is periodic frame list size */
-+#define CMD_RESET (1<<1) /* reset HC not bus */
-+#define CMD_RUN (1<<0) /* start/stop HC */
-+
-+ /* USBSTS: offset 0x04 */
-+ u32 status;
-+#define STS_ASS (1<<15) /* Async Schedule Status */
-+#define STS_PSS (1<<14) /* Periodic Schedule Status */
-+#define STS_RECL (1<<13) /* Reclamation */
-+#define STS_HALT (1<<12) /* Not running (any reason) */
-+/* some bits reserved */
-+ /* these STS_* flags are also intr_enable bits (USBINTR) */
-+#define STS_IAA (1<<5) /* Interrupted on async advance */
-+#define STS_FATAL (1<<4) /* such as some PCI access errors */
-+#define STS_FLR (1<<3) /* frame list rolled over */
-+#define STS_PCD (1<<2) /* port change detect */
-+#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
-+#define STS_INT (1<<0) /* "normal" completion (short, ...) */
-+
-+ /* USBINTR: offset 0x08 */
-+ u32 intr_enable;
-+
-+ /* FRINDEX: offset 0x0C */
-+ u32 frame_index; /* current microframe number */
-+ /* CTRLDSSEGMENT: offset 0x10 */
-+ u32 segment; /* address bits 63:32 if needed */
-+ /* PERIODICLISTBASE: offset 0x14 */
-+ u32 frame_list; /* points to periodic list */
-+ /* ASYNCLISTADDR: offset 0x18 */
-+ u32 async_next; /* address of next async queue head */
-+
-+ u32 reserved1;
-+ /* PORTSC: offset 0x20 */
-+ u32 port_status;
-+/* 31:23 reserved */
-+#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10)) /* USB 1.1 device */
-+#define PORT_RESET (1<<8) /* reset port */
-+#define PORT_SUSPEND (1<<7) /* suspend port */
-+#define PORT_RESUME (1<<6) /* resume it */
-+#define PORT_PEC (1<<3) /* port enable change */
-+#define PORT_PE (1<<2) /* port enable */
-+#define PORT_CSC (1<<1) /* connect status change */
-+#define PORT_CONNECT (1<<0) /* device connected */
-+#define PORT_RWC_BITS (PORT_CSC | PORT_PEC)
-+ u32 reserved2[19];
-+
-+ /* OTGCSR: offet 0x70 */
-+ u32 otgcsr;
-+#define OTGCSR_HOST_SPD_TYP (3 << 22)
-+#define OTGCSR_A_BUS_DROP (1 << 5)
-+#define OTGCSR_A_BUS_REQ (1 << 4)
-+
-+ /* OTGISR: offset 0x74 */
-+ u32 otgisr;
-+#define OTGISR_OVC (1 << 10)
-+
-+ u32 reserved3[15];
-+
-+ /* GMIR: offset 0xB4 */
-+ u32 gmir;
-+#define GMIR_INT_POLARITY (1 << 3) /*Active High*/
-+#define GMIR_MHC_INT (1 << 2)
-+#define GMIR_MOTG_INT (1 << 1)
-+#define GMIR_MDEV_INT (1 << 0)
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#define QTD_NEXT(fotg210, dma) cpu_to_hc32(fotg210, (u32)dma)
-+
-+/*
-+ * EHCI Specification 0.95 Section 3.5
-+ * QTD: describe data transfer components (buffer, direction, ...)
-+ * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
-+ *
-+ * These are associated only with "QH" (Queue Head) structures,
-+ * used with control, bulk, and interrupt transfers.
-+ */
-+struct fotg210_qtd {
-+ /* first part defined by EHCI spec */
-+ __hc32 hw_next; /* see EHCI 3.5.1 */
-+ __hc32 hw_alt_next; /* see EHCI 3.5.2 */
-+ __hc32 hw_token; /* see EHCI 3.5.3 */
-+#define QTD_TOGGLE (1 << 31) /* data toggle */
-+#define QTD_LENGTH(tok) (((tok)>>16) & 0x7fff)
-+#define QTD_IOC (1 << 15) /* interrupt on complete */
-+#define QTD_CERR(tok) (((tok)>>10) & 0x3)
-+#define QTD_PID(tok) (((tok)>>8) & 0x3)
-+#define QTD_STS_ACTIVE (1 << 7) /* HC may execute this */
-+#define QTD_STS_HALT (1 << 6) /* halted on error */
-+#define QTD_STS_DBE (1 << 5) /* data buffer error (in HC) */
-+#define QTD_STS_BABBLE (1 << 4) /* device was babbling (qtd halted) */
-+#define QTD_STS_XACT (1 << 3) /* device gave illegal response */
-+#define QTD_STS_MMF (1 << 2) /* incomplete split transaction */
-+#define QTD_STS_STS (1 << 1) /* split transaction state */
-+#define QTD_STS_PING (1 << 0) /* issue PING? */
-+
-+#define ACTIVE_BIT(fotg210) cpu_to_hc32(fotg210, QTD_STS_ACTIVE)
-+#define HALT_BIT(fotg210) cpu_to_hc32(fotg210, QTD_STS_HALT)
-+#define STATUS_BIT(fotg210) cpu_to_hc32(fotg210, QTD_STS_STS)
-+
-+ __hc32 hw_buf[5]; /* see EHCI 3.5.4 */
-+ __hc32 hw_buf_hi[5]; /* Appendix B */
-+
-+ /* the rest is HCD-private */
-+ dma_addr_t qtd_dma; /* qtd address */
-+ struct list_head qtd_list; /* sw qtd list */
-+ struct urb *urb; /* qtd's urb */
-+ size_t length; /* length of buffer */
-+} __aligned(32);
-+
-+/* mask NakCnt+T in qh->hw_alt_next */
-+#define QTD_MASK(fotg210) cpu_to_hc32(fotg210, ~0x1f)
-+
-+#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1)
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* type tag from {qh,itd,fstn}->hw_next */
-+#define Q_NEXT_TYPE(fotg210, dma) ((dma) & cpu_to_hc32(fotg210, 3 << 1))
-+
-+/*
-+ * Now the following defines are not converted using the
-+ * cpu_to_le32() macro anymore, since we have to support
-+ * "dynamic" switching between be and le support, so that the driver
-+ * can be used on one system with SoC EHCI controller using big-endian
-+ * descriptors as well as a normal little-endian PCI EHCI controller.
-+ */
-+/* values for that type tag */
-+#define Q_TYPE_ITD (0 << 1)
-+#define Q_TYPE_QH (1 << 1)
-+#define Q_TYPE_SITD (2 << 1)
-+#define Q_TYPE_FSTN (3 << 1)
-+
-+/* next async queue entry, or pointer to interrupt/periodic QH */
-+#define QH_NEXT(fotg210, dma) \
-+ (cpu_to_hc32(fotg210, (((u32)dma)&~0x01f)|Q_TYPE_QH))
-+
-+/* for periodic/async schedules and qtd lists, mark end of list */
-+#define FOTG210_LIST_END(fotg210) \
-+ cpu_to_hc32(fotg210, 1) /* "null pointer" to hw */
-+
-+/*
-+ * Entries in periodic shadow table are pointers to one of four kinds
-+ * of data structure. That's dictated by the hardware; a type tag is
-+ * encoded in the low bits of the hardware's periodic schedule. Use
-+ * Q_NEXT_TYPE to get the tag.
-+ *
-+ * For entries in the async schedule, the type tag always says "qh".
-+ */
-+union fotg210_shadow {
-+ struct fotg210_qh *qh; /* Q_TYPE_QH */
-+ struct fotg210_itd *itd; /* Q_TYPE_ITD */
-+ struct fotg210_fstn *fstn; /* Q_TYPE_FSTN */
-+ __hc32 *hw_next; /* (all types) */
-+ void *ptr;
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * EHCI Specification 0.95 Section 3.6
-+ * QH: describes control/bulk/interrupt endpoints
-+ * See Fig 3-7 "Queue Head Structure Layout".
-+ *
-+ * These appear in both the async and (for interrupt) periodic schedules.
-+ */
-+
-+/* first part defined by EHCI spec */
-+struct fotg210_qh_hw {
-+ __hc32 hw_next; /* see EHCI 3.6.1 */
-+ __hc32 hw_info1; /* see EHCI 3.6.2 */
-+#define QH_CONTROL_EP (1 << 27) /* FS/LS control endpoint */
-+#define QH_HEAD (1 << 15) /* Head of async reclamation list */
-+#define QH_TOGGLE_CTL (1 << 14) /* Data toggle control */
-+#define QH_HIGH_SPEED (2 << 12) /* Endpoint speed */
-+#define QH_LOW_SPEED (1 << 12)
-+#define QH_FULL_SPEED (0 << 12)
-+#define QH_INACTIVATE (1 << 7) /* Inactivate on next transaction */
-+ __hc32 hw_info2; /* see EHCI 3.6.2 */
-+#define QH_SMASK 0x000000ff
-+#define QH_CMASK 0x0000ff00
-+#define QH_HUBADDR 0x007f0000
-+#define QH_HUBPORT 0x3f800000
-+#define QH_MULT 0xc0000000
-+ __hc32 hw_current; /* qtd list - see EHCI 3.6.4 */
-+
-+ /* qtd overlay (hardware parts of a struct fotg210_qtd) */
-+ __hc32 hw_qtd_next;
-+ __hc32 hw_alt_next;
-+ __hc32 hw_token;
-+ __hc32 hw_buf[5];
-+ __hc32 hw_buf_hi[5];
-+} __aligned(32);
-+
-+struct fotg210_qh {
-+ struct fotg210_qh_hw *hw; /* Must come first */
-+ /* the rest is HCD-private */
-+ dma_addr_t qh_dma; /* address of qh */
-+ union fotg210_shadow qh_next; /* ptr to qh; or periodic */
-+ struct list_head qtd_list; /* sw qtd list */
-+ struct list_head intr_node; /* list of intr QHs */
-+ struct fotg210_qtd *dummy;
-+ struct fotg210_qh *unlink_next; /* next on unlink list */
-+
-+ unsigned unlink_cycle;
-+
-+ u8 needs_rescan; /* Dequeue during giveback */
-+ u8 qh_state;
-+#define QH_STATE_LINKED 1 /* HC sees this */
-+#define QH_STATE_UNLINK 2 /* HC may still see this */
-+#define QH_STATE_IDLE 3 /* HC doesn't see this */
-+#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on unlink q */
-+#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */
-+
-+ u8 xacterrs; /* XactErr retry counter */
-+#define QH_XACTERR_MAX 32 /* XactErr retry limit */
-+
-+ /* periodic schedule info */
-+ u8 usecs; /* intr bandwidth */
-+ u8 gap_uf; /* uframes split/csplit gap */
-+ u8 c_usecs; /* ... split completion bw */
-+ u16 tt_usecs; /* tt downstream bandwidth */
-+ unsigned short period; /* polling interval */
-+ unsigned short start; /* where polling starts */
-+#define NO_FRAME ((unsigned short)~0) /* pick new start */
-+
-+ struct usb_device *dev; /* access to TT */
-+ unsigned is_out:1; /* bulk or intr OUT */
-+ unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* description of one iso transaction (up to 3 KB data if highspeed) */
-+struct fotg210_iso_packet {
-+ /* These will be copied to iTD when scheduling */
-+ u64 bufp; /* itd->hw_bufp{,_hi}[pg] |= */
-+ __hc32 transaction; /* itd->hw_transaction[i] |= */
-+ u8 cross; /* buf crosses pages */
-+ /* for full speed OUT splits */
-+ u32 buf1;
-+};
-+
-+/* temporary schedule data for packets from iso urbs (both speeds)
-+ * each packet is one logical usb transaction to the device (not TT),
-+ * beginning at stream->next_uframe
-+ */
-+struct fotg210_iso_sched {
-+ struct list_head td_list;
-+ unsigned span;
-+ struct fotg210_iso_packet packet[];
-+};
-+
-+/*
-+ * fotg210_iso_stream - groups all (s)itds for this endpoint.
-+ * acts like a qh would, if EHCI had them for ISO.
-+ */
-+struct fotg210_iso_stream {
-+ /* first field matches fotg210_hq, but is NULL */
-+ struct fotg210_qh_hw *hw;
-+
-+ u8 bEndpointAddress;
-+ u8 highspeed;
-+ struct list_head td_list; /* queued itds */
-+ struct list_head free_list; /* list of unused itds */
-+ struct usb_device *udev;
-+ struct usb_host_endpoint *ep;
-+
-+ /* output of (re)scheduling */
-+ int next_uframe;
-+ __hc32 splits;
-+
-+ /* the rest is derived from the endpoint descriptor,
-+ * trusting urb->interval == f(epdesc->bInterval) and
-+ * including the extra info for hw_bufp[0..2]
-+ */
-+ u8 usecs, c_usecs;
-+ u16 interval;
-+ u16 tt_usecs;
-+ u16 maxp;
-+ u16 raw_mask;
-+ unsigned bandwidth;
-+
-+ /* This is used to initialize iTD's hw_bufp fields */
-+ __hc32 buf0;
-+ __hc32 buf1;
-+ __hc32 buf2;
-+
-+ /* this is used to initialize sITD's tt info */
-+ __hc32 address;
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * EHCI Specification 0.95 Section 3.3
-+ * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
-+ *
-+ * Schedule records for high speed iso xfers
-+ */
-+struct fotg210_itd {
-+ /* first part defined by EHCI spec */
-+ __hc32 hw_next; /* see EHCI 3.3.1 */
-+ __hc32 hw_transaction[8]; /* see EHCI 3.3.2 */
-+#define FOTG210_ISOC_ACTIVE (1<<31) /* activate transfer this slot */
-+#define FOTG210_ISOC_BUF_ERR (1<<30) /* Data buffer error */
-+#define FOTG210_ISOC_BABBLE (1<<29) /* babble detected */
-+#define FOTG210_ISOC_XACTERR (1<<28) /* XactErr - transaction error */
-+#define FOTG210_ITD_LENGTH(tok) (((tok)>>16) & 0x0fff)
-+#define FOTG210_ITD_IOC (1 << 15) /* interrupt on complete */
-+
-+#define ITD_ACTIVE(fotg210) cpu_to_hc32(fotg210, FOTG210_ISOC_ACTIVE)
-+
-+ __hc32 hw_bufp[7]; /* see EHCI 3.3.3 */
-+ __hc32 hw_bufp_hi[7]; /* Appendix B */
-+
-+ /* the rest is HCD-private */
-+ dma_addr_t itd_dma; /* for this itd */
-+ union fotg210_shadow itd_next; /* ptr to periodic q entry */
-+
-+ struct urb *urb;
-+ struct fotg210_iso_stream *stream; /* endpoint's queue */
-+ struct list_head itd_list; /* list of stream's itds */
-+
-+ /* any/all hw_transactions here may be used by that urb */
-+ unsigned frame; /* where scheduled */
-+ unsigned pg;
-+ unsigned index[8]; /* in urb->iso_frame_desc */
-+} __aligned(32);
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * EHCI Specification 0.96 Section 3.7
-+ * Periodic Frame Span Traversal Node (FSTN)
-+ *
-+ * Manages split interrupt transactions (using TT) that span frame boundaries
-+ * into uframes 0/1; see 4.12.2.2. In those uframes, a "save place" FSTN
-+ * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
-+ * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
-+ */
-+struct fotg210_fstn {
-+ __hc32 hw_next; /* any periodic q entry */
-+ __hc32 hw_prev; /* qh or FOTG210_LIST_END */
-+
-+ /* the rest is HCD-private */
-+ dma_addr_t fstn_dma;
-+ union fotg210_shadow fstn_next; /* ptr to periodic q entry */
-+} __aligned(32);
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Prepare the PORTSC wakeup flags during controller suspend/resume */
-+
-+#define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
-+ fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup)
-+
-+#define fotg210_prepare_ports_for_controller_resume(fotg210) \
-+ fotg210_adjust_port_wakeup_flags(fotg210, false, false)
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * Some EHCI controllers have a Transaction Translator built into the
-+ * root hub. This is a non-standard feature. Each controller will need
-+ * to add code to the following inline functions, and call them as
-+ * needed (mostly in root hub code).
-+ */
-+
-+static inline unsigned int
-+fotg210_get_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
-+{
-+ return (readl(&fotg210->regs->otgcsr)
-+ & OTGCSR_HOST_SPD_TYP) >> 22;
-+}
-+
-+/* Returns the speed of a device attached to a port on the root hub. */
-+static inline unsigned int
-+fotg210_port_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
-+{
-+ switch (fotg210_get_speed(fotg210, portsc)) {
-+ case 0:
-+ return 0;
-+ case 1:
-+ return USB_PORT_STAT_LOW_SPEED;
-+ case 2:
-+ default:
-+ return USB_PORT_STAT_HIGH_SPEED;
-+ }
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#define fotg210_has_fsl_portno_bug(e) (0)
-+
-+/*
-+ * While most USB host controllers implement their registers in
-+ * little-endian format, a minority (celleb companion chip) implement
-+ * them in big endian format.
-+ *
-+ * This attempts to support either format at compile time without a
-+ * runtime penalty, or both formats with the additional overhead
-+ * of checking a flag bit.
-+ *
-+ */
-+
-+#define fotg210_big_endian_mmio(e) 0
-+#define fotg210_big_endian_capbase(e) 0
-+
-+static inline unsigned int fotg210_readl(const struct fotg210_hcd *fotg210,
-+ __u32 __iomem *regs)
-+{
-+ return readl(regs);
-+}
-+
-+static inline void fotg210_writel(const struct fotg210_hcd *fotg210,
-+ const unsigned int val, __u32 __iomem *regs)
-+{
-+ writel(val, regs);
-+}
-+
-+/* cpu to fotg210 */
-+static inline __hc32 cpu_to_hc32(const struct fotg210_hcd *fotg210, const u32 x)
-+{
-+ return cpu_to_le32(x);
-+}
-+
-+/* fotg210 to cpu */
-+static inline u32 hc32_to_cpu(const struct fotg210_hcd *fotg210, const __hc32 x)
-+{
-+ return le32_to_cpu(x);
-+}
-+
-+static inline u32 hc32_to_cpup(const struct fotg210_hcd *fotg210,
-+ const __hc32 *x)
-+{
-+ return le32_to_cpup(x);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static inline unsigned fotg210_read_frame_index(struct fotg210_hcd *fotg210)
-+{
-+ return fotg210_readl(fotg210, &fotg210->regs->frame_index);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#endif /* __LINUX_FOTG210_H */
---- /dev/null
-+++ b/drivers/usb/fotg210/fotg210-udc.h
-@@ -0,0 +1,249 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Faraday FOTG210 USB OTG controller
-+ *
-+ * Copyright (C) 2013 Faraday Technology Corporation
-+ * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com>
-+ */
-+
-+#include <linux/kernel.h>
-+
-+#define FOTG210_MAX_NUM_EP 5 /* ep0...ep4 */
-+#define FOTG210_MAX_FIFO_NUM 4 /* fifo0...fifo4 */
-+
-+/* Global Mask of HC/OTG/DEV interrupt Register(0xC4) */
-+#define FOTG210_GMIR 0xC4
-+#define GMIR_INT_POLARITY 0x8 /*Active High*/
-+#define GMIR_MHC_INT 0x4
-+#define GMIR_MOTG_INT 0x2
-+#define GMIR_MDEV_INT 0x1
-+
-+/* Device Main Control Register(0x100) */
-+#define FOTG210_DMCR 0x100
-+#define DMCR_HS_EN (1 << 6)
-+#define DMCR_CHIP_EN (1 << 5)
-+#define DMCR_SFRST (1 << 4)
-+#define DMCR_GOSUSP (1 << 3)
-+#define DMCR_GLINT_EN (1 << 2)
-+#define DMCR_HALF_SPEED (1 << 1)
-+#define DMCR_CAP_RMWAKUP (1 << 0)
-+
-+/* Device Address Register(0x104) */
-+#define FOTG210_DAR 0x104
-+#define DAR_AFT_CONF (1 << 7)
-+
-+/* Device Test Register(0x108) */
-+#define FOTG210_DTR 0x108
-+#define DTR_TST_CLRFF (1 << 0)
-+
-+/* PHY Test Mode Selector register(0x114) */
-+#define FOTG210_PHYTMSR 0x114
-+#define PHYTMSR_TST_PKT (1 << 4)
-+#define PHYTMSR_TST_SE0NAK (1 << 3)
-+#define PHYTMSR_TST_KSTA (1 << 2)
-+#define PHYTMSR_TST_JSTA (1 << 1)
-+#define PHYTMSR_UNPLUG (1 << 0)
-+
-+/* Cx configuration and FIFO Empty Status register(0x120) */
-+#define FOTG210_DCFESR 0x120
-+#define DCFESR_FIFO_EMPTY(fifo) (1 << 8 << (fifo))
-+#define DCFESR_CX_EMP (1 << 5)
-+#define DCFESR_CX_CLR (1 << 3)
-+#define DCFESR_CX_STL (1 << 2)
-+#define DCFESR_TST_PKDONE (1 << 1)
-+#define DCFESR_CX_DONE (1 << 0)
-+
-+/* Device IDLE Counter Register(0x124) */
-+#define FOTG210_DICR 0x124
-+
-+/* Device Mask of Interrupt Group Register (0x130) */
-+#define FOTG210_DMIGR 0x130
-+#define DMIGR_MINT_G0 (1 << 0)
-+
-+/* Device Mask of Interrupt Source Group 0(0x134) */
-+#define FOTG210_DMISGR0 0x134
-+#define DMISGR0_MCX_COMEND (1 << 3)
-+#define DMISGR0_MCX_OUT_INT (1 << 2)
-+#define DMISGR0_MCX_IN_INT (1 << 1)
-+#define DMISGR0_MCX_SETUP_INT (1 << 0)
-+
-+/* Device Mask of Interrupt Source Group 1 Register(0x138)*/
-+#define FOTG210_DMISGR1 0x138
-+#define DMISGR1_MF3_IN_INT (1 << 19)
-+#define DMISGR1_MF2_IN_INT (1 << 18)
-+#define DMISGR1_MF1_IN_INT (1 << 17)
-+#define DMISGR1_MF0_IN_INT (1 << 16)
-+#define DMISGR1_MF_IN_INT(fifo) (1 << (16 + (fifo)))
-+#define DMISGR1_MF3_SPK_INT (1 << 7)
-+#define DMISGR1_MF3_OUT_INT (1 << 6)
-+#define DMISGR1_MF2_SPK_INT (1 << 5)
-+#define DMISGR1_MF2_OUT_INT (1 << 4)
-+#define DMISGR1_MF1_SPK_INT (1 << 3)
-+#define DMISGR1_MF1_OUT_INT (1 << 2)
-+#define DMISGR1_MF0_SPK_INT (1 << 1)
-+#define DMISGR1_MF0_OUT_INT (1 << 0)
-+#define DMISGR1_MF_OUTSPK_INT(fifo) (0x3 << (fifo) * 2)
-+
-+/* Device Mask of Interrupt Source Group 2 Register (0x13C) */
-+#define FOTG210_DMISGR2 0x13C
-+#define DMISGR2_MDMA_ERROR (1 << 8)
-+#define DMISGR2_MDMA_CMPLT (1 << 7)
-+
-+/* Device Interrupt group Register (0x140) */
-+#define FOTG210_DIGR 0x140
-+#define DIGR_INT_G2 (1 << 2)
-+#define DIGR_INT_G1 (1 << 1)
-+#define DIGR_INT_G0 (1 << 0)
-+
-+/* Device Interrupt Source Group 0 Register (0x144) */
-+#define FOTG210_DISGR0 0x144
-+#define DISGR0_CX_COMABT_INT (1 << 5)
-+#define DISGR0_CX_COMFAIL_INT (1 << 4)
-+#define DISGR0_CX_COMEND_INT (1 << 3)
-+#define DISGR0_CX_OUT_INT (1 << 2)
-+#define DISGR0_CX_IN_INT (1 << 1)
-+#define DISGR0_CX_SETUP_INT (1 << 0)
-+
-+/* Device Interrupt Source Group 1 Register (0x148) */
-+#define FOTG210_DISGR1 0x148
-+#define DISGR1_OUT_INT(fifo) (1 << ((fifo) * 2))
-+#define DISGR1_SPK_INT(fifo) (1 << 1 << ((fifo) * 2))
-+#define DISGR1_IN_INT(fifo) (1 << 16 << (fifo))
-+
-+/* Device Interrupt Source Group 2 Register (0x14C) */
-+#define FOTG210_DISGR2 0x14C
-+#define DISGR2_DMA_ERROR (1 << 8)
-+#define DISGR2_DMA_CMPLT (1 << 7)
-+#define DISGR2_RX0BYTE_INT (1 << 6)
-+#define DISGR2_TX0BYTE_INT (1 << 5)
-+#define DISGR2_ISO_SEQ_ABORT_INT (1 << 4)
-+#define DISGR2_ISO_SEQ_ERR_INT (1 << 3)
-+#define DISGR2_RESM_INT (1 << 2)
-+#define DISGR2_SUSP_INT (1 << 1)
-+#define DISGR2_USBRST_INT (1 << 0)
-+
-+/* Device Receive Zero-Length Data Packet Register (0x150)*/
-+#define FOTG210_RX0BYTE 0x150
-+#define RX0BYTE_EP8 (1 << 7)
-+#define RX0BYTE_EP7 (1 << 6)
-+#define RX0BYTE_EP6 (1 << 5)
-+#define RX0BYTE_EP5 (1 << 4)
-+#define RX0BYTE_EP4 (1 << 3)
-+#define RX0BYTE_EP3 (1 << 2)
-+#define RX0BYTE_EP2 (1 << 1)
-+#define RX0BYTE_EP1 (1 << 0)
-+
-+/* Device Transfer Zero-Length Data Packet Register (0x154)*/
-+#define FOTG210_TX0BYTE 0x154
-+#define TX0BYTE_EP8 (1 << 7)
-+#define TX0BYTE_EP7 (1 << 6)
-+#define TX0BYTE_EP6 (1 << 5)
-+#define TX0BYTE_EP5 (1 << 4)
-+#define TX0BYTE_EP4 (1 << 3)
-+#define TX0BYTE_EP3 (1 << 2)
-+#define TX0BYTE_EP2 (1 << 1)
-+#define TX0BYTE_EP1 (1 << 0)
-+
-+/* Device IN Endpoint x MaxPacketSize Register(0x160+4*(x-1)) */
-+#define FOTG210_INEPMPSR(ep) (0x160 + 4 * ((ep) - 1))
-+#define INOUTEPMPSR_MPS(mps) ((mps) & 0x2FF)
-+#define INOUTEPMPSR_STL_EP (1 << 11)
-+#define INOUTEPMPSR_RESET_TSEQ (1 << 12)
-+
-+/* Device OUT Endpoint x MaxPacketSize Register(0x180+4*(x-1)) */
-+#define FOTG210_OUTEPMPSR(ep) (0x180 + 4 * ((ep) - 1))
-+
-+/* Device Endpoint 1~4 Map Register (0x1A0) */
-+#define FOTG210_EPMAP 0x1A0
-+#define EPMAP_FIFONO(ep, dir) \
-+ ((((ep) - 1) << ((ep) - 1) * 8) << ((dir) ? 0 : 4))
-+#define EPMAP_FIFONOMSK(ep, dir) \
-+ ((3 << ((ep) - 1) * 8) << ((dir) ? 0 : 4))
-+
-+/* Device FIFO Map Register (0x1A8) */
-+#define FOTG210_FIFOMAP 0x1A8
-+#define FIFOMAP_DIROUT(fifo) (0x0 << 4 << (fifo) * 8)
-+#define FIFOMAP_DIRIN(fifo) (0x1 << 4 << (fifo) * 8)
-+#define FIFOMAP_BIDIR(fifo) (0x2 << 4 << (fifo) * 8)
-+#define FIFOMAP_NA(fifo) (0x3 << 4 << (fifo) * 8)
-+#define FIFOMAP_EPNO(ep) ((ep) << ((ep) - 1) * 8)
-+#define FIFOMAP_EPNOMSK(ep) (0xF << ((ep) - 1) * 8)
-+
-+/* Device FIFO Confuguration Register (0x1AC) */
-+#define FOTG210_FIFOCF 0x1AC
-+#define FIFOCF_TYPE(type, fifo) ((type) << (fifo) * 8)
-+#define FIFOCF_BLK_SIN(fifo) (0x0 << (fifo) * 8 << 2)
-+#define FIFOCF_BLK_DUB(fifo) (0x1 << (fifo) * 8 << 2)
-+#define FIFOCF_BLK_TRI(fifo) (0x2 << (fifo) * 8 << 2)
-+#define FIFOCF_BLKSZ_512(fifo) (0x0 << (fifo) * 8 << 4)
-+#define FIFOCF_BLKSZ_1024(fifo) (0x1 << (fifo) * 8 << 4)
-+#define FIFOCF_FIFO_EN(fifo) (0x1 << (fifo) * 8 << 5)
-+
-+/* Device FIFO n Instruction and Byte Count Register (0x1B0+4*n) */
-+#define FOTG210_FIBCR(fifo) (0x1B0 + (fifo) * 4)
-+#define FIBCR_BCFX 0x7FF
-+#define FIBCR_FFRST (1 << 12)
-+
-+/* Device DMA Target FIFO Number Register (0x1C0) */
-+#define FOTG210_DMATFNR 0x1C0
-+#define DMATFNR_ACC_CXF (1 << 4)
-+#define DMATFNR_ACC_F3 (1 << 3)
-+#define DMATFNR_ACC_F2 (1 << 2)
-+#define DMATFNR_ACC_F1 (1 << 1)
-+#define DMATFNR_ACC_F0 (1 << 0)
-+#define DMATFNR_ACC_FN(fifo) (1 << (fifo))
-+#define DMATFNR_DISDMA 0
-+
-+/* Device DMA Controller Parameter setting 1 Register (0x1C8) */
-+#define FOTG210_DMACPSR1 0x1C8
-+#define DMACPSR1_DMA_LEN(len) (((len) & 0xFFFF) << 8)
-+#define DMACPSR1_DMA_ABORT (1 << 3)
-+#define DMACPSR1_DMA_TYPE(dir_in) (((dir_in) ? 1 : 0) << 1)
-+#define DMACPSR1_DMA_START (1 << 0)
-+
-+/* Device DMA Controller Parameter setting 2 Register (0x1CC) */
-+#define FOTG210_DMACPSR2 0x1CC
-+
-+/* Device DMA Controller Parameter setting 3 Register (0x1CC) */
-+#define FOTG210_CXPORT 0x1D0
-+
-+struct fotg210_request {
-+ struct usb_request req;
-+ struct list_head queue;
-+};
-+
-+struct fotg210_ep {
-+ struct usb_ep ep;
-+ struct fotg210_udc *fotg210;
-+
-+ struct list_head queue;
-+ unsigned stall:1;
-+ unsigned wedged:1;
-+ unsigned use_dma:1;
-+
-+ unsigned char epnum;
-+ unsigned char type;
-+ unsigned char dir_in;
-+ unsigned int maxp;
-+ const struct usb_endpoint_descriptor *desc;
-+};
-+
-+struct fotg210_udc {
-+ spinlock_t lock; /* protect the struct */
-+ void __iomem *reg;
-+
-+ unsigned long irq_trigger;
-+
-+ struct usb_gadget gadget;
-+ struct usb_gadget_driver *driver;
-+
-+ struct fotg210_ep *ep[FOTG210_MAX_NUM_EP];
-+
-+ struct usb_request *ep0_req; /* for internal request */
-+ __le16 ep0_data;
-+ u8 ep0_dir; /* 0/0x80 out/in */
-+
-+ u8 reenum; /* if re-enumeration */
-+};
-+
-+#define gadget_to_fotg210(g) container_of((g), struct fotg210_udc, gadget)
---- a/drivers/usb/gadget/udc/fotg210.h
-+++ /dev/null
-@@ -1,249 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0+
--/*
-- * Faraday FOTG210 USB OTG controller
-- *
-- * Copyright (C) 2013 Faraday Technology Corporation
-- * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com>
-- */
--
--#include <linux/kernel.h>
--
--#define FOTG210_MAX_NUM_EP 5 /* ep0...ep4 */
--#define FOTG210_MAX_FIFO_NUM 4 /* fifo0...fifo4 */
--
--/* Global Mask of HC/OTG/DEV interrupt Register(0xC4) */
--#define FOTG210_GMIR 0xC4
--#define GMIR_INT_POLARITY 0x8 /*Active High*/
--#define GMIR_MHC_INT 0x4
--#define GMIR_MOTG_INT 0x2
--#define GMIR_MDEV_INT 0x1
--
--/* Device Main Control Register(0x100) */
--#define FOTG210_DMCR 0x100
--#define DMCR_HS_EN (1 << 6)
--#define DMCR_CHIP_EN (1 << 5)
--#define DMCR_SFRST (1 << 4)
--#define DMCR_GOSUSP (1 << 3)
--#define DMCR_GLINT_EN (1 << 2)
--#define DMCR_HALF_SPEED (1 << 1)
--#define DMCR_CAP_RMWAKUP (1 << 0)
--
--/* Device Address Register(0x104) */
--#define FOTG210_DAR 0x104
--#define DAR_AFT_CONF (1 << 7)
--
--/* Device Test Register(0x108) */
--#define FOTG210_DTR 0x108
--#define DTR_TST_CLRFF (1 << 0)
--
--/* PHY Test Mode Selector register(0x114) */
--#define FOTG210_PHYTMSR 0x114
--#define PHYTMSR_TST_PKT (1 << 4)
--#define PHYTMSR_TST_SE0NAK (1 << 3)
--#define PHYTMSR_TST_KSTA (1 << 2)
--#define PHYTMSR_TST_JSTA (1 << 1)
--#define PHYTMSR_UNPLUG (1 << 0)
--
--/* Cx configuration and FIFO Empty Status register(0x120) */
--#define FOTG210_DCFESR 0x120
--#define DCFESR_FIFO_EMPTY(fifo) (1 << 8 << (fifo))
--#define DCFESR_CX_EMP (1 << 5)
--#define DCFESR_CX_CLR (1 << 3)
--#define DCFESR_CX_STL (1 << 2)
--#define DCFESR_TST_PKDONE (1 << 1)
--#define DCFESR_CX_DONE (1 << 0)
--
--/* Device IDLE Counter Register(0x124) */
--#define FOTG210_DICR 0x124
--
--/* Device Mask of Interrupt Group Register (0x130) */
--#define FOTG210_DMIGR 0x130
--#define DMIGR_MINT_G0 (1 << 0)
--
--/* Device Mask of Interrupt Source Group 0(0x134) */
--#define FOTG210_DMISGR0 0x134
--#define DMISGR0_MCX_COMEND (1 << 3)
--#define DMISGR0_MCX_OUT_INT (1 << 2)
--#define DMISGR0_MCX_IN_INT (1 << 1)
--#define DMISGR0_MCX_SETUP_INT (1 << 0)
--
--/* Device Mask of Interrupt Source Group 1 Register(0x138)*/
--#define FOTG210_DMISGR1 0x138
--#define DMISGR1_MF3_IN_INT (1 << 19)
--#define DMISGR1_MF2_IN_INT (1 << 18)
--#define DMISGR1_MF1_IN_INT (1 << 17)
--#define DMISGR1_MF0_IN_INT (1 << 16)
--#define DMISGR1_MF_IN_INT(fifo) (1 << (16 + (fifo)))
--#define DMISGR1_MF3_SPK_INT (1 << 7)
--#define DMISGR1_MF3_OUT_INT (1 << 6)
--#define DMISGR1_MF2_SPK_INT (1 << 5)
--#define DMISGR1_MF2_OUT_INT (1 << 4)
--#define DMISGR1_MF1_SPK_INT (1 << 3)
--#define DMISGR1_MF1_OUT_INT (1 << 2)
--#define DMISGR1_MF0_SPK_INT (1 << 1)
--#define DMISGR1_MF0_OUT_INT (1 << 0)
--#define DMISGR1_MF_OUTSPK_INT(fifo) (0x3 << (fifo) * 2)
--
--/* Device Mask of Interrupt Source Group 2 Register (0x13C) */
--#define FOTG210_DMISGR2 0x13C
--#define DMISGR2_MDMA_ERROR (1 << 8)
--#define DMISGR2_MDMA_CMPLT (1 << 7)
--
--/* Device Interrupt group Register (0x140) */
--#define FOTG210_DIGR 0x140
--#define DIGR_INT_G2 (1 << 2)
--#define DIGR_INT_G1 (1 << 1)
--#define DIGR_INT_G0 (1 << 0)
--
--/* Device Interrupt Source Group 0 Register (0x144) */
--#define FOTG210_DISGR0 0x144
--#define DISGR0_CX_COMABT_INT (1 << 5)
--#define DISGR0_CX_COMFAIL_INT (1 << 4)
--#define DISGR0_CX_COMEND_INT (1 << 3)
--#define DISGR0_CX_OUT_INT (1 << 2)
--#define DISGR0_CX_IN_INT (1 << 1)
--#define DISGR0_CX_SETUP_INT (1 << 0)
--
--/* Device Interrupt Source Group 1 Register (0x148) */
--#define FOTG210_DISGR1 0x148
--#define DISGR1_OUT_INT(fifo) (1 << ((fifo) * 2))
--#define DISGR1_SPK_INT(fifo) (1 << 1 << ((fifo) * 2))
--#define DISGR1_IN_INT(fifo) (1 << 16 << (fifo))
--
--/* Device Interrupt Source Group 2 Register (0x14C) */
--#define FOTG210_DISGR2 0x14C
--#define DISGR2_DMA_ERROR (1 << 8)
--#define DISGR2_DMA_CMPLT (1 << 7)
--#define DISGR2_RX0BYTE_INT (1 << 6)
--#define DISGR2_TX0BYTE_INT (1 << 5)
--#define DISGR2_ISO_SEQ_ABORT_INT (1 << 4)
--#define DISGR2_ISO_SEQ_ERR_INT (1 << 3)
--#define DISGR2_RESM_INT (1 << 2)
--#define DISGR2_SUSP_INT (1 << 1)
--#define DISGR2_USBRST_INT (1 << 0)
--
--/* Device Receive Zero-Length Data Packet Register (0x150)*/
--#define FOTG210_RX0BYTE 0x150
--#define RX0BYTE_EP8 (1 << 7)
--#define RX0BYTE_EP7 (1 << 6)
--#define RX0BYTE_EP6 (1 << 5)
--#define RX0BYTE_EP5 (1 << 4)
--#define RX0BYTE_EP4 (1 << 3)
--#define RX0BYTE_EP3 (1 << 2)
--#define RX0BYTE_EP2 (1 << 1)
--#define RX0BYTE_EP1 (1 << 0)
--
--/* Device Transfer Zero-Length Data Packet Register (0x154)*/
--#define FOTG210_TX0BYTE 0x154
--#define TX0BYTE_EP8 (1 << 7)
--#define TX0BYTE_EP7 (1 << 6)
--#define TX0BYTE_EP6 (1 << 5)
--#define TX0BYTE_EP5 (1 << 4)
--#define TX0BYTE_EP4 (1 << 3)
--#define TX0BYTE_EP3 (1 << 2)
--#define TX0BYTE_EP2 (1 << 1)
--#define TX0BYTE_EP1 (1 << 0)
--
--/* Device IN Endpoint x MaxPacketSize Register(0x160+4*(x-1)) */
--#define FOTG210_INEPMPSR(ep) (0x160 + 4 * ((ep) - 1))
--#define INOUTEPMPSR_MPS(mps) ((mps) & 0x2FF)
--#define INOUTEPMPSR_STL_EP (1 << 11)
--#define INOUTEPMPSR_RESET_TSEQ (1 << 12)
--
--/* Device OUT Endpoint x MaxPacketSize Register(0x180+4*(x-1)) */
--#define FOTG210_OUTEPMPSR(ep) (0x180 + 4 * ((ep) - 1))
--
--/* Device Endpoint 1~4 Map Register (0x1A0) */
--#define FOTG210_EPMAP 0x1A0
--#define EPMAP_FIFONO(ep, dir) \
-- ((((ep) - 1) << ((ep) - 1) * 8) << ((dir) ? 0 : 4))
--#define EPMAP_FIFONOMSK(ep, dir) \
-- ((3 << ((ep) - 1) * 8) << ((dir) ? 0 : 4))
--
--/* Device FIFO Map Register (0x1A8) */
--#define FOTG210_FIFOMAP 0x1A8
--#define FIFOMAP_DIROUT(fifo) (0x0 << 4 << (fifo) * 8)
--#define FIFOMAP_DIRIN(fifo) (0x1 << 4 << (fifo) * 8)
--#define FIFOMAP_BIDIR(fifo) (0x2 << 4 << (fifo) * 8)
--#define FIFOMAP_NA(fifo) (0x3 << 4 << (fifo) * 8)
--#define FIFOMAP_EPNO(ep) ((ep) << ((ep) - 1) * 8)
--#define FIFOMAP_EPNOMSK(ep) (0xF << ((ep) - 1) * 8)
--
--/* Device FIFO Confuguration Register (0x1AC) */
--#define FOTG210_FIFOCF 0x1AC
--#define FIFOCF_TYPE(type, fifo) ((type) << (fifo) * 8)
--#define FIFOCF_BLK_SIN(fifo) (0x0 << (fifo) * 8 << 2)
--#define FIFOCF_BLK_DUB(fifo) (0x1 << (fifo) * 8 << 2)
--#define FIFOCF_BLK_TRI(fifo) (0x2 << (fifo) * 8 << 2)
--#define FIFOCF_BLKSZ_512(fifo) (0x0 << (fifo) * 8 << 4)
--#define FIFOCF_BLKSZ_1024(fifo) (0x1 << (fifo) * 8 << 4)
--#define FIFOCF_FIFO_EN(fifo) (0x1 << (fifo) * 8 << 5)
--
--/* Device FIFO n Instruction and Byte Count Register (0x1B0+4*n) */
--#define FOTG210_FIBCR(fifo) (0x1B0 + (fifo) * 4)
--#define FIBCR_BCFX 0x7FF
--#define FIBCR_FFRST (1 << 12)
--
--/* Device DMA Target FIFO Number Register (0x1C0) */
--#define FOTG210_DMATFNR 0x1C0
--#define DMATFNR_ACC_CXF (1 << 4)
--#define DMATFNR_ACC_F3 (1 << 3)
--#define DMATFNR_ACC_F2 (1 << 2)
--#define DMATFNR_ACC_F1 (1 << 1)
--#define DMATFNR_ACC_F0 (1 << 0)
--#define DMATFNR_ACC_FN(fifo) (1 << (fifo))
--#define DMATFNR_DISDMA 0
--
--/* Device DMA Controller Parameter setting 1 Register (0x1C8) */
--#define FOTG210_DMACPSR1 0x1C8
--#define DMACPSR1_DMA_LEN(len) (((len) & 0xFFFF) << 8)
--#define DMACPSR1_DMA_ABORT (1 << 3)
--#define DMACPSR1_DMA_TYPE(dir_in) (((dir_in) ? 1 : 0) << 1)
--#define DMACPSR1_DMA_START (1 << 0)
--
--/* Device DMA Controller Parameter setting 2 Register (0x1CC) */
--#define FOTG210_DMACPSR2 0x1CC
--
--/* Device DMA Controller Parameter setting 3 Register (0x1CC) */
--#define FOTG210_CXPORT 0x1D0
--
--struct fotg210_request {
-- struct usb_request req;
-- struct list_head queue;
--};
--
--struct fotg210_ep {
-- struct usb_ep ep;
-- struct fotg210_udc *fotg210;
--
-- struct list_head queue;
-- unsigned stall:1;
-- unsigned wedged:1;
-- unsigned use_dma:1;
--
-- unsigned char epnum;
-- unsigned char type;
-- unsigned char dir_in;
-- unsigned int maxp;
-- const struct usb_endpoint_descriptor *desc;
--};
--
--struct fotg210_udc {
-- spinlock_t lock; /* protect the struct */
-- void __iomem *reg;
--
-- unsigned long irq_trigger;
--
-- struct usb_gadget gadget;
-- struct usb_gadget_driver *driver;
--
-- struct fotg210_ep *ep[FOTG210_MAX_NUM_EP];
--
-- struct usb_request *ep0_req; /* for internal request */
-- __le16 ep0_data;
-- u8 ep0_dir; /* 0/0x80 out/in */
--
-- u8 reenum; /* if re-enumeration */
--};
--
--#define gadget_to_fotg210(g) container_of((g), struct fotg210_udc, gadget)
---- a/drivers/usb/host/fotg210.h
-+++ /dev/null
-@@ -1,688 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0 */
--#ifndef __LINUX_FOTG210_H
--#define __LINUX_FOTG210_H
--
--#include <linux/usb/ehci-dbgp.h>
--
--/* definitions used for the EHCI driver */
--
--/*
-- * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
-- * __leXX (normally) or __beXX (given FOTG210_BIG_ENDIAN_DESC), depending on
-- * the host controller implementation.
-- *
-- * To facilitate the strongest possible byte-order checking from "sparse"
-- * and so on, we use __leXX unless that's not practical.
-- */
--#define __hc32 __le32
--#define __hc16 __le16
--
--/* statistics can be kept for tuning/monitoring */
--struct fotg210_stats {
-- /* irq usage */
-- unsigned long normal;
-- unsigned long error;
-- unsigned long iaa;
-- unsigned long lost_iaa;
--
-- /* termination of urbs from core */
-- unsigned long complete;
-- unsigned long unlink;
--};
--
--/* fotg210_hcd->lock guards shared data against other CPUs:
-- * fotg210_hcd: async, unlink, periodic (and shadow), ...
-- * usb_host_endpoint: hcpriv
-- * fotg210_qh: qh_next, qtd_list
-- * fotg210_qtd: qtd_list
-- *
-- * Also, hold this lock when talking to HC registers or
-- * when updating hw_* fields in shared qh/qtd/... structures.
-- */
--
--#define FOTG210_MAX_ROOT_PORTS 1 /* see HCS_N_PORTS */
--
--/*
-- * fotg210_rh_state values of FOTG210_RH_RUNNING or above mean that the
-- * controller may be doing DMA. Lower values mean there's no DMA.
-- */
--enum fotg210_rh_state {
-- FOTG210_RH_HALTED,
-- FOTG210_RH_SUSPENDED,
-- FOTG210_RH_RUNNING,
-- FOTG210_RH_STOPPING
--};
--
--/*
-- * Timer events, ordered by increasing delay length.
-- * Always update event_delays_ns[] and event_handlers[] (defined in
-- * ehci-timer.c) in parallel with this list.
-- */
--enum fotg210_hrtimer_event {
-- FOTG210_HRTIMER_POLL_ASS, /* Poll for async schedule off */
-- FOTG210_HRTIMER_POLL_PSS, /* Poll for periodic schedule off */
-- FOTG210_HRTIMER_POLL_DEAD, /* Wait for dead controller to stop */
-- FOTG210_HRTIMER_UNLINK_INTR, /* Wait for interrupt QH unlink */
-- FOTG210_HRTIMER_FREE_ITDS, /* Wait for unused iTDs and siTDs */
-- FOTG210_HRTIMER_ASYNC_UNLINKS, /* Unlink empty async QHs */
-- FOTG210_HRTIMER_IAA_WATCHDOG, /* Handle lost IAA interrupts */
-- FOTG210_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */
-- FOTG210_HRTIMER_DISABLE_ASYNC, /* Wait to disable async sched */
-- FOTG210_HRTIMER_IO_WATCHDOG, /* Check for missing IRQs */
-- FOTG210_HRTIMER_NUM_EVENTS /* Must come last */
--};
--#define FOTG210_HRTIMER_NO_EVENT 99
--
--struct fotg210_hcd { /* one per controller */
-- /* timing support */
-- enum fotg210_hrtimer_event next_hrtimer_event;
-- unsigned enabled_hrtimer_events;
-- ktime_t hr_timeouts[FOTG210_HRTIMER_NUM_EVENTS];
-- struct hrtimer hrtimer;
--
-- int PSS_poll_count;
-- int ASS_poll_count;
-- int died_poll_count;
--
-- /* glue to PCI and HCD framework */
-- struct fotg210_caps __iomem *caps;
-- struct fotg210_regs __iomem *regs;
-- struct ehci_dbg_port __iomem *debug;
--
-- __u32 hcs_params; /* cached register copy */
-- spinlock_t lock;
-- enum fotg210_rh_state rh_state;
--
-- /* general schedule support */
-- bool scanning:1;
-- bool need_rescan:1;
-- bool intr_unlinking:1;
-- bool async_unlinking:1;
-- bool shutdown:1;
-- struct fotg210_qh *qh_scan_next;
--
-- /* async schedule support */
-- struct fotg210_qh *async;
-- struct fotg210_qh *dummy; /* For AMD quirk use */
-- struct fotg210_qh *async_unlink;
-- struct fotg210_qh *async_unlink_last;
-- struct fotg210_qh *async_iaa;
-- unsigned async_unlink_cycle;
-- unsigned async_count; /* async activity count */
--
-- /* periodic schedule support */
--#define DEFAULT_I_TDPS 1024 /* some HCs can do less */
-- unsigned periodic_size;
-- __hc32 *periodic; /* hw periodic table */
-- dma_addr_t periodic_dma;
-- struct list_head intr_qh_list;
-- unsigned i_thresh; /* uframes HC might cache */
--
-- union fotg210_shadow *pshadow; /* mirror hw periodic table */
-- struct fotg210_qh *intr_unlink;
-- struct fotg210_qh *intr_unlink_last;
-- unsigned intr_unlink_cycle;
-- unsigned now_frame; /* frame from HC hardware */
-- unsigned next_frame; /* scan periodic, start here */
-- unsigned intr_count; /* intr activity count */
-- unsigned isoc_count; /* isoc activity count */
-- unsigned periodic_count; /* periodic activity count */
-- /* max periodic time per uframe */
-- unsigned uframe_periodic_max;
--
--
-- /* list of itds completed while now_frame was still active */
-- struct list_head cached_itd_list;
-- struct fotg210_itd *last_itd_to_free;
--
-- /* per root hub port */
-- unsigned long reset_done[FOTG210_MAX_ROOT_PORTS];
--
-- /* bit vectors (one bit per port)
-- * which ports were already suspended at the start of a bus suspend
-- */
-- unsigned long bus_suspended;
--
-- /* which ports are edicated to the companion controller */
-- unsigned long companion_ports;
--
-- /* which ports are owned by the companion during a bus suspend */
-- unsigned long owned_ports;
--
-- /* which ports have the change-suspend feature turned on */
-- unsigned long port_c_suspend;
--
-- /* which ports are suspended */
-- unsigned long suspended_ports;
--
-- /* which ports have started to resume */
-- unsigned long resuming_ports;
--
-- /* per-HC memory pools (could be per-bus, but ...) */
-- struct dma_pool *qh_pool; /* qh per active urb */
-- struct dma_pool *qtd_pool; /* one or more per qh */
-- struct dma_pool *itd_pool; /* itd per iso urb */
--
-- unsigned random_frame;
-- unsigned long next_statechange;
-- ktime_t last_periodic_enable;
-- u32 command;
--
-- /* SILICON QUIRKS */
-- unsigned need_io_watchdog:1;
-- unsigned fs_i_thresh:1; /* Intel iso scheduling */
--
-- u8 sbrn; /* packed release number */
--
-- /* irq statistics */
--#ifdef FOTG210_STATS
-- struct fotg210_stats stats;
--# define INCR(x) ((x)++)
--#else
--# define INCR(x) do {} while (0)
--#endif
--
-- /* silicon clock */
-- struct clk *pclk;
--};
--
--/* convert between an HCD pointer and the corresponding FOTG210_HCD */
--static inline struct fotg210_hcd *hcd_to_fotg210(struct usb_hcd *hcd)
--{
-- return (struct fotg210_hcd *)(hcd->hcd_priv);
--}
--static inline struct usb_hcd *fotg210_to_hcd(struct fotg210_hcd *fotg210)
--{
-- return container_of((void *) fotg210, struct usb_hcd, hcd_priv);
--}
--
--/*-------------------------------------------------------------------------*/
--
--/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
--
--/* Section 2.2 Host Controller Capability Registers */
--struct fotg210_caps {
-- /* these fields are specified as 8 and 16 bit registers,
-- * but some hosts can't perform 8 or 16 bit PCI accesses.
-- * some hosts treat caplength and hciversion as parts of a 32-bit
-- * register, others treat them as two separate registers, this
-- * affects the memory map for big endian controllers.
-- */
-- u32 hc_capbase;
--#define HC_LENGTH(fotg210, p) (0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
-- (fotg210_big_endian_capbase(fotg210) ? 24 : 0)))
--#define HC_VERSION(fotg210, p) (0xffff&((p) >> /* bits 31:16 / offset 02h */ \
-- (fotg210_big_endian_capbase(fotg210) ? 0 : 16)))
-- u32 hcs_params; /* HCSPARAMS - offset 0x4 */
--#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */
--
-- u32 hcc_params; /* HCCPARAMS - offset 0x8 */
--#define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */
--#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/
-- u8 portroute[8]; /* nibbles for routing - offset 0xC */
--};
--
--
--/* Section 2.3 Host Controller Operational Registers */
--struct fotg210_regs {
--
-- /* USBCMD: offset 0x00 */
-- u32 command;
--
--/* EHCI 1.1 addendum */
--/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
--#define CMD_PARK (1<<11) /* enable "park" on async qh */
--#define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */
--#define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */
--#define CMD_ASE (1<<5) /* async schedule enable */
--#define CMD_PSE (1<<4) /* periodic schedule enable */
--/* 3:2 is periodic frame list size */
--#define CMD_RESET (1<<1) /* reset HC not bus */
--#define CMD_RUN (1<<0) /* start/stop HC */
--
-- /* USBSTS: offset 0x04 */
-- u32 status;
--#define STS_ASS (1<<15) /* Async Schedule Status */
--#define STS_PSS (1<<14) /* Periodic Schedule Status */
--#define STS_RECL (1<<13) /* Reclamation */
--#define STS_HALT (1<<12) /* Not running (any reason) */
--/* some bits reserved */
-- /* these STS_* flags are also intr_enable bits (USBINTR) */
--#define STS_IAA (1<<5) /* Interrupted on async advance */
--#define STS_FATAL (1<<4) /* such as some PCI access errors */
--#define STS_FLR (1<<3) /* frame list rolled over */
--#define STS_PCD (1<<2) /* port change detect */
--#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
--#define STS_INT (1<<0) /* "normal" completion (short, ...) */
--
-- /* USBINTR: offset 0x08 */
-- u32 intr_enable;
--
-- /* FRINDEX: offset 0x0C */
-- u32 frame_index; /* current microframe number */
-- /* CTRLDSSEGMENT: offset 0x10 */
-- u32 segment; /* address bits 63:32 if needed */
-- /* PERIODICLISTBASE: offset 0x14 */
-- u32 frame_list; /* points to periodic list */
-- /* ASYNCLISTADDR: offset 0x18 */
-- u32 async_next; /* address of next async queue head */
--
-- u32 reserved1;
-- /* PORTSC: offset 0x20 */
-- u32 port_status;
--/* 31:23 reserved */
--#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10)) /* USB 1.1 device */
--#define PORT_RESET (1<<8) /* reset port */
--#define PORT_SUSPEND (1<<7) /* suspend port */
--#define PORT_RESUME (1<<6) /* resume it */
--#define PORT_PEC (1<<3) /* port enable change */
--#define PORT_PE (1<<2) /* port enable */
--#define PORT_CSC (1<<1) /* connect status change */
--#define PORT_CONNECT (1<<0) /* device connected */
--#define PORT_RWC_BITS (PORT_CSC | PORT_PEC)
-- u32 reserved2[19];
--
-- /* OTGCSR: offet 0x70 */
-- u32 otgcsr;
--#define OTGCSR_HOST_SPD_TYP (3 << 22)
--#define OTGCSR_A_BUS_DROP (1 << 5)
--#define OTGCSR_A_BUS_REQ (1 << 4)
--
-- /* OTGISR: offset 0x74 */
-- u32 otgisr;
--#define OTGISR_OVC (1 << 10)
--
-- u32 reserved3[15];
--
-- /* GMIR: offset 0xB4 */
-- u32 gmir;
--#define GMIR_INT_POLARITY (1 << 3) /*Active High*/
--#define GMIR_MHC_INT (1 << 2)
--#define GMIR_MOTG_INT (1 << 1)
--#define GMIR_MDEV_INT (1 << 0)
--};
--
--/*-------------------------------------------------------------------------*/
--
--#define QTD_NEXT(fotg210, dma) cpu_to_hc32(fotg210, (u32)dma)
--
--/*
-- * EHCI Specification 0.95 Section 3.5
-- * QTD: describe data transfer components (buffer, direction, ...)
-- * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
-- *
-- * These are associated only with "QH" (Queue Head) structures,
-- * used with control, bulk, and interrupt transfers.
-- */
--struct fotg210_qtd {
-- /* first part defined by EHCI spec */
-- __hc32 hw_next; /* see EHCI 3.5.1 */
-- __hc32 hw_alt_next; /* see EHCI 3.5.2 */
-- __hc32 hw_token; /* see EHCI 3.5.3 */
--#define QTD_TOGGLE (1 << 31) /* data toggle */
--#define QTD_LENGTH(tok) (((tok)>>16) & 0x7fff)
--#define QTD_IOC (1 << 15) /* interrupt on complete */
--#define QTD_CERR(tok) (((tok)>>10) & 0x3)
--#define QTD_PID(tok) (((tok)>>8) & 0x3)
--#define QTD_STS_ACTIVE (1 << 7) /* HC may execute this */
--#define QTD_STS_HALT (1 << 6) /* halted on error */
--#define QTD_STS_DBE (1 << 5) /* data buffer error (in HC) */
--#define QTD_STS_BABBLE (1 << 4) /* device was babbling (qtd halted) */
--#define QTD_STS_XACT (1 << 3) /* device gave illegal response */
--#define QTD_STS_MMF (1 << 2) /* incomplete split transaction */
--#define QTD_STS_STS (1 << 1) /* split transaction state */
--#define QTD_STS_PING (1 << 0) /* issue PING? */
--
--#define ACTIVE_BIT(fotg210) cpu_to_hc32(fotg210, QTD_STS_ACTIVE)
--#define HALT_BIT(fotg210) cpu_to_hc32(fotg210, QTD_STS_HALT)
--#define STATUS_BIT(fotg210) cpu_to_hc32(fotg210, QTD_STS_STS)
--
-- __hc32 hw_buf[5]; /* see EHCI 3.5.4 */
-- __hc32 hw_buf_hi[5]; /* Appendix B */
--
-- /* the rest is HCD-private */
-- dma_addr_t qtd_dma; /* qtd address */
-- struct list_head qtd_list; /* sw qtd list */
-- struct urb *urb; /* qtd's urb */
-- size_t length; /* length of buffer */
--} __aligned(32);
--
--/* mask NakCnt+T in qh->hw_alt_next */
--#define QTD_MASK(fotg210) cpu_to_hc32(fotg210, ~0x1f)
--
--#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1)
--
--/*-------------------------------------------------------------------------*/
--
--/* type tag from {qh,itd,fstn}->hw_next */
--#define Q_NEXT_TYPE(fotg210, dma) ((dma) & cpu_to_hc32(fotg210, 3 << 1))
--
--/*
-- * Now the following defines are not converted using the
-- * cpu_to_le32() macro anymore, since we have to support
-- * "dynamic" switching between be and le support, so that the driver
-- * can be used on one system with SoC EHCI controller using big-endian
-- * descriptors as well as a normal little-endian PCI EHCI controller.
-- */
--/* values for that type tag */
--#define Q_TYPE_ITD (0 << 1)
--#define Q_TYPE_QH (1 << 1)
--#define Q_TYPE_SITD (2 << 1)
--#define Q_TYPE_FSTN (3 << 1)
--
--/* next async queue entry, or pointer to interrupt/periodic QH */
--#define QH_NEXT(fotg210, dma) \
-- (cpu_to_hc32(fotg210, (((u32)dma)&~0x01f)|Q_TYPE_QH))
--
--/* for periodic/async schedules and qtd lists, mark end of list */
--#define FOTG210_LIST_END(fotg210) \
-- cpu_to_hc32(fotg210, 1) /* "null pointer" to hw */
--
--/*
-- * Entries in periodic shadow table are pointers to one of four kinds
-- * of data structure. That's dictated by the hardware; a type tag is
-- * encoded in the low bits of the hardware's periodic schedule. Use
-- * Q_NEXT_TYPE to get the tag.
-- *
-- * For entries in the async schedule, the type tag always says "qh".
-- */
--union fotg210_shadow {
-- struct fotg210_qh *qh; /* Q_TYPE_QH */
-- struct fotg210_itd *itd; /* Q_TYPE_ITD */
-- struct fotg210_fstn *fstn; /* Q_TYPE_FSTN */
-- __hc32 *hw_next; /* (all types) */
-- void *ptr;
--};
--
--/*-------------------------------------------------------------------------*/
--
--/*
-- * EHCI Specification 0.95 Section 3.6
-- * QH: describes control/bulk/interrupt endpoints
-- * See Fig 3-7 "Queue Head Structure Layout".
-- *
-- * These appear in both the async and (for interrupt) periodic schedules.
-- */
--
--/* first part defined by EHCI spec */
--struct fotg210_qh_hw {
-- __hc32 hw_next; /* see EHCI 3.6.1 */
-- __hc32 hw_info1; /* see EHCI 3.6.2 */
--#define QH_CONTROL_EP (1 << 27) /* FS/LS control endpoint */
--#define QH_HEAD (1 << 15) /* Head of async reclamation list */
--#define QH_TOGGLE_CTL (1 << 14) /* Data toggle control */
--#define QH_HIGH_SPEED (2 << 12) /* Endpoint speed */
--#define QH_LOW_SPEED (1 << 12)
--#define QH_FULL_SPEED (0 << 12)
--#define QH_INACTIVATE (1 << 7) /* Inactivate on next transaction */
-- __hc32 hw_info2; /* see EHCI 3.6.2 */
--#define QH_SMASK 0x000000ff
--#define QH_CMASK 0x0000ff00
--#define QH_HUBADDR 0x007f0000
--#define QH_HUBPORT 0x3f800000
--#define QH_MULT 0xc0000000
-- __hc32 hw_current; /* qtd list - see EHCI 3.6.4 */
--
-- /* qtd overlay (hardware parts of a struct fotg210_qtd) */
-- __hc32 hw_qtd_next;
-- __hc32 hw_alt_next;
-- __hc32 hw_token;
-- __hc32 hw_buf[5];
-- __hc32 hw_buf_hi[5];
--} __aligned(32);
--
--struct fotg210_qh {
-- struct fotg210_qh_hw *hw; /* Must come first */
-- /* the rest is HCD-private */
-- dma_addr_t qh_dma; /* address of qh */
-- union fotg210_shadow qh_next; /* ptr to qh; or periodic */
-- struct list_head qtd_list; /* sw qtd list */
-- struct list_head intr_node; /* list of intr QHs */
-- struct fotg210_qtd *dummy;
-- struct fotg210_qh *unlink_next; /* next on unlink list */
--
-- unsigned unlink_cycle;
--
-- u8 needs_rescan; /* Dequeue during giveback */
-- u8 qh_state;
--#define QH_STATE_LINKED 1 /* HC sees this */
--#define QH_STATE_UNLINK 2 /* HC may still see this */
--#define QH_STATE_IDLE 3 /* HC doesn't see this */
--#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on unlink q */
--#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */
--
-- u8 xacterrs; /* XactErr retry counter */
--#define QH_XACTERR_MAX 32 /* XactErr retry limit */
--
-- /* periodic schedule info */
-- u8 usecs; /* intr bandwidth */
-- u8 gap_uf; /* uframes split/csplit gap */
-- u8 c_usecs; /* ... split completion bw */
-- u16 tt_usecs; /* tt downstream bandwidth */
-- unsigned short period; /* polling interval */
-- unsigned short start; /* where polling starts */
--#define NO_FRAME ((unsigned short)~0) /* pick new start */
--
-- struct usb_device *dev; /* access to TT */
-- unsigned is_out:1; /* bulk or intr OUT */
-- unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
--};
--
--/*-------------------------------------------------------------------------*/
--
--/* description of one iso transaction (up to 3 KB data if highspeed) */
--struct fotg210_iso_packet {
-- /* These will be copied to iTD when scheduling */
-- u64 bufp; /* itd->hw_bufp{,_hi}[pg] |= */
-- __hc32 transaction; /* itd->hw_transaction[i] |= */
-- u8 cross; /* buf crosses pages */
-- /* for full speed OUT splits */
-- u32 buf1;
--};
--
--/* temporary schedule data for packets from iso urbs (both speeds)
-- * each packet is one logical usb transaction to the device (not TT),
-- * beginning at stream->next_uframe
-- */
--struct fotg210_iso_sched {
-- struct list_head td_list;
-- unsigned span;
-- struct fotg210_iso_packet packet[];
--};
--
--/*
-- * fotg210_iso_stream - groups all (s)itds for this endpoint.
-- * acts like a qh would, if EHCI had them for ISO.
-- */
--struct fotg210_iso_stream {
-- /* first field matches fotg210_hq, but is NULL */
-- struct fotg210_qh_hw *hw;
--
-- u8 bEndpointAddress;
-- u8 highspeed;
-- struct list_head td_list; /* queued itds */
-- struct list_head free_list; /* list of unused itds */
-- struct usb_device *udev;
-- struct usb_host_endpoint *ep;
--
-- /* output of (re)scheduling */
-- int next_uframe;
-- __hc32 splits;
--
-- /* the rest is derived from the endpoint descriptor,
-- * trusting urb->interval == f(epdesc->bInterval) and
-- * including the extra info for hw_bufp[0..2]
-- */
-- u8 usecs, c_usecs;
-- u16 interval;
-- u16 tt_usecs;
-- u16 maxp;
-- u16 raw_mask;
-- unsigned bandwidth;
--
-- /* This is used to initialize iTD's hw_bufp fields */
-- __hc32 buf0;
-- __hc32 buf1;
-- __hc32 buf2;
--
-- /* this is used to initialize sITD's tt info */
-- __hc32 address;
--};
--
--/*-------------------------------------------------------------------------*/
--
--/*
-- * EHCI Specification 0.95 Section 3.3
-- * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
-- *
-- * Schedule records for high speed iso xfers
-- */
--struct fotg210_itd {
-- /* first part defined by EHCI spec */
-- __hc32 hw_next; /* see EHCI 3.3.1 */
-- __hc32 hw_transaction[8]; /* see EHCI 3.3.2 */
--#define FOTG210_ISOC_ACTIVE (1<<31) /* activate transfer this slot */
--#define FOTG210_ISOC_BUF_ERR (1<<30) /* Data buffer error */
--#define FOTG210_ISOC_BABBLE (1<<29) /* babble detected */
--#define FOTG210_ISOC_XACTERR (1<<28) /* XactErr - transaction error */
--#define FOTG210_ITD_LENGTH(tok) (((tok)>>16) & 0x0fff)
--#define FOTG210_ITD_IOC (1 << 15) /* interrupt on complete */
--
--#define ITD_ACTIVE(fotg210) cpu_to_hc32(fotg210, FOTG210_ISOC_ACTIVE)
--
-- __hc32 hw_bufp[7]; /* see EHCI 3.3.3 */
-- __hc32 hw_bufp_hi[7]; /* Appendix B */
--
-- /* the rest is HCD-private */
-- dma_addr_t itd_dma; /* for this itd */
-- union fotg210_shadow itd_next; /* ptr to periodic q entry */
--
-- struct urb *urb;
-- struct fotg210_iso_stream *stream; /* endpoint's queue */
-- struct list_head itd_list; /* list of stream's itds */
--
-- /* any/all hw_transactions here may be used by that urb */
-- unsigned frame; /* where scheduled */
-- unsigned pg;
-- unsigned index[8]; /* in urb->iso_frame_desc */
--} __aligned(32);
--
--/*-------------------------------------------------------------------------*/
--
--/*
-- * EHCI Specification 0.96 Section 3.7
-- * Periodic Frame Span Traversal Node (FSTN)
-- *
-- * Manages split interrupt transactions (using TT) that span frame boundaries
-- * into uframes 0/1; see 4.12.2.2. In those uframes, a "save place" FSTN
-- * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
-- * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
-- */
--struct fotg210_fstn {
-- __hc32 hw_next; /* any periodic q entry */
-- __hc32 hw_prev; /* qh or FOTG210_LIST_END */
--
-- /* the rest is HCD-private */
-- dma_addr_t fstn_dma;
-- union fotg210_shadow fstn_next; /* ptr to periodic q entry */
--} __aligned(32);
--
--/*-------------------------------------------------------------------------*/
--
--/* Prepare the PORTSC wakeup flags during controller suspend/resume */
--
--#define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
-- fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup)
--
--#define fotg210_prepare_ports_for_controller_resume(fotg210) \
-- fotg210_adjust_port_wakeup_flags(fotg210, false, false)
--
--/*-------------------------------------------------------------------------*/
--
--/*
-- * Some EHCI controllers have a Transaction Translator built into the
-- * root hub. This is a non-standard feature. Each controller will need
-- * to add code to the following inline functions, and call them as
-- * needed (mostly in root hub code).
-- */
--
--static inline unsigned int
--fotg210_get_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
--{
-- return (readl(&fotg210->regs->otgcsr)
-- & OTGCSR_HOST_SPD_TYP) >> 22;
--}
--
--/* Returns the speed of a device attached to a port on the root hub. */
--static inline unsigned int
--fotg210_port_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
--{
-- switch (fotg210_get_speed(fotg210, portsc)) {
-- case 0:
-- return 0;
-- case 1:
-- return USB_PORT_STAT_LOW_SPEED;
-- case 2:
-- default:
-- return USB_PORT_STAT_HIGH_SPEED;
-- }
--}
--
--/*-------------------------------------------------------------------------*/
--
--#define fotg210_has_fsl_portno_bug(e) (0)
--
--/*
-- * While most USB host controllers implement their registers in
-- * little-endian format, a minority (celleb companion chip) implement
-- * them in big endian format.
-- *
-- * This attempts to support either format at compile time without a
-- * runtime penalty, or both formats with the additional overhead
-- * of checking a flag bit.
-- *
-- */
--
--#define fotg210_big_endian_mmio(e) 0
--#define fotg210_big_endian_capbase(e) 0
--
--static inline unsigned int fotg210_readl(const struct fotg210_hcd *fotg210,
-- __u32 __iomem *regs)
--{
-- return readl(regs);
--}
--
--static inline void fotg210_writel(const struct fotg210_hcd *fotg210,
-- const unsigned int val, __u32 __iomem *regs)
--{
-- writel(val, regs);
--}
--
--/* cpu to fotg210 */
--static inline __hc32 cpu_to_hc32(const struct fotg210_hcd *fotg210, const u32 x)
--{
-- return cpu_to_le32(x);
--}
--
--/* fotg210 to cpu */
--static inline u32 hc32_to_cpu(const struct fotg210_hcd *fotg210, const __hc32 x)
--{
-- return le32_to_cpu(x);
--}
--
--static inline u32 hc32_to_cpup(const struct fotg210_hcd *fotg210,
-- const __hc32 *x)
--{
-- return le32_to_cpup(x);
--}
--
--/*-------------------------------------------------------------------------*/
--
--static inline unsigned fotg210_read_frame_index(struct fotg210_hcd *fotg210)
--{
-- return fotg210_readl(fotg210, &fotg210->regs->frame_index);
--}
--
--/*-------------------------------------------------------------------------*/
--
--#endif /* __LINUX_FOTG210_H */
+++ /dev/null
-From 0dbc77a99267a5efef0603a4b49ac02ece6a3f23 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 23 Oct 2022 16:47:07 +0200
-Subject: [PATCH 03/29] usb: fotg210: Compile into one module
-
-It is since ages perfectly possible to compile both of these
-modules into the same kernel, which makes no sense since it
-is one piece of hardware.
-
-Compile one module named "fotg210.ko" for both HCD and UDC
-drivers by collecting the init calls into a fotg210-core.c
-file and start to centralize things handling one and the same
-piece of hardware.
-
-Stub out the initcalls if one or the other part of the driver
-was not selected.
-
-Tested by compiling one or the other or both of the drivers
-into the kernel and as modules.
-
-Cc: Fabian Vogt <fabian@ritter-vogt.de>
-Cc: Yuan-Hsin Chen <yhchen@faraday-tech.com>
-Cc: Felipe Balbi <balbi@kernel.org>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221023144708.3596563-2-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/Kconfig
-+++ b/drivers/usb/fotg210/Kconfig
-@@ -12,7 +12,7 @@ config USB_FOTG210
- if USB_FOTG210
-
- config USB_FOTG210_HCD
-- tristate "Faraday FOTG210 USB Host Controller support"
-+ bool "Faraday FOTG210 USB Host Controller support"
- depends on USB
- help
- Faraday FOTG210 is an OTG controller which can be configured as
-@@ -24,7 +24,7 @@ config USB_FOTG210_HCD
-
- config USB_FOTG210_UDC
- depends on USB_GADGET
-- tristate "Faraday FOTG210 USB Peripheral Controller support"
-+ bool "Faraday FOTG210 USB Peripheral Controller support"
- help
- Faraday USB2.0 OTG controller which can be configured as
- high speed or full speed USB device. This driver suppports
---- a/drivers/usb/fotg210/Makefile
-+++ b/drivers/usb/fotg210/Makefile
-@@ -1,3 +1,10 @@
- # SPDX-License-Identifier: GPL-2.0
--obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o
--obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o
-+
-+# This setup links the different object files into one single
-+# module so we don't have to EXPORT() a lot of internal symbols
-+# or create unnecessary submodules.
-+fotg210-objs-y += fotg210-core.o
-+fotg210-objs-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o
-+fotg210-objs-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o
-+fotg210-objs := $(fotg210-objs-y)
-+obj-$(CONFIG_USB_FOTG210) += fotg210.o
---- /dev/null
-+++ b/drivers/usb/fotg210/fotg210-core.c
-@@ -0,0 +1,79 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Central probing code for the FOTG210 dual role driver
-+ * We register one driver for the hardware and then we decide
-+ * whether to proceed with probing the host or the peripheral
-+ * driver.
-+ */
-+#include <linux/device.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/usb.h>
-+
-+#include "fotg210.h"
-+
-+static int fotg210_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+
-+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) {
-+ ret = fotg210_hcd_probe(pdev);
-+ if (ret)
-+ return ret;
-+ }
-+ if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
-+ ret = fotg210_udc_probe(pdev);
-+
-+ return ret;
-+}
-+
-+static int fotg210_remove(struct platform_device *pdev)
-+{
-+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
-+ fotg210_hcd_remove(pdev);
-+ if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
-+ fotg210_udc_remove(pdev);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_OF
-+static const struct of_device_id fotg210_of_match[] = {
-+ { .compatible = "faraday,fotg210" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, fotg210_of_match);
-+#endif
-+
-+static struct platform_driver fotg210_driver = {
-+ .driver = {
-+ .name = "fotg210",
-+ .of_match_table = of_match_ptr(fotg210_of_match),
-+ },
-+ .probe = fotg210_probe,
-+ .remove = fotg210_remove,
-+};
-+
-+static int __init fotg210_init(void)
-+{
-+ if (usb_disabled())
-+ return -ENODEV;
-+
-+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
-+ fotg210_hcd_init();
-+ return platform_driver_register(&fotg210_driver);
-+}
-+module_init(fotg210_init);
-+
-+static void __exit fotg210_cleanup(void)
-+{
-+ platform_driver_unregister(&fotg210_driver);
-+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
-+ fotg210_hcd_cleanup();
-+}
-+module_exit(fotg210_cleanup);
-+
-+MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("FOTG210 Dual Role Controller Driver");
---- a/drivers/usb/fotg210/fotg210-hcd.c
-+++ b/drivers/usb/fotg210/fotg210-hcd.c
-@@ -39,8 +39,8 @@
- #include <asm/irq.h>
- #include <asm/unaligned.h>
-
--#define DRIVER_AUTHOR "Yuan-Hsin Chen"
--#define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
-+#include "fotg210.h"
-+
- static const char hcd_name[] = "fotg210_hcd";
-
- #undef FOTG210_URB_TRACE
-@@ -5490,9 +5490,6 @@ static int fotg210_get_frame(struct usb_
- * functions and in order to facilitate role switching we cannot
- * give the fotg210 driver exclusive access to those.
- */
--MODULE_DESCRIPTION(DRIVER_DESC);
--MODULE_AUTHOR(DRIVER_AUTHOR);
--MODULE_LICENSE("GPL");
-
- static const struct hc_driver fotg210_fotg210_hc_driver = {
- .description = hcd_name,
-@@ -5560,7 +5557,7 @@ static void fotg210_init(struct fotg210_
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- */
--static int fotg210_hcd_probe(struct platform_device *pdev)
-+int fotg210_hcd_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd;
-@@ -5652,7 +5649,7 @@ fail_create_hcd:
- * @dev: USB Host Controller being removed
- *
- */
--static int fotg210_hcd_remove(struct platform_device *pdev)
-+int fotg210_hcd_remove(struct platform_device *pdev)
- {
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-@@ -5668,27 +5665,8 @@ static int fotg210_hcd_remove(struct pla
- return 0;
- }
-
--#ifdef CONFIG_OF
--static const struct of_device_id fotg210_of_match[] = {
-- { .compatible = "faraday,fotg210" },
-- {},
--};
--MODULE_DEVICE_TABLE(of, fotg210_of_match);
--#endif
--
--static struct platform_driver fotg210_hcd_driver = {
-- .driver = {
-- .name = "fotg210-hcd",
-- .of_match_table = of_match_ptr(fotg210_of_match),
-- },
-- .probe = fotg210_hcd_probe,
-- .remove = fotg210_hcd_remove,
--};
--
--static int __init fotg210_hcd_init(void)
-+int __init fotg210_hcd_init(void)
- {
-- int retval = 0;
--
- if (usb_disabled())
- return -ENODEV;
-
-@@ -5704,24 +5682,11 @@ static int __init fotg210_hcd_init(void)
-
- fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
-
-- retval = platform_driver_register(&fotg210_hcd_driver);
-- if (retval < 0)
-- goto clean;
-- return retval;
--
--clean:
-- debugfs_remove(fotg210_debug_root);
-- fotg210_debug_root = NULL;
--
-- clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-- return retval;
-+ return 0;
- }
--module_init(fotg210_hcd_init);
-
--static void __exit fotg210_hcd_cleanup(void)
-+void __exit fotg210_hcd_cleanup(void)
- {
-- platform_driver_unregister(&fotg210_hcd_driver);
- debugfs_remove(fotg210_debug_root);
- clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
- }
--module_exit(fotg210_hcd_cleanup);
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -16,6 +16,7 @@
- #include <linux/usb/ch9.h>
- #include <linux/usb/gadget.h>
-
-+#include "fotg210.h"
- #include "fotg210-udc.h"
-
- #define DRIVER_DESC "FOTG210 USB Device Controller Driver"
-@@ -1081,7 +1082,7 @@ static const struct usb_gadget_ops fotg2
- .udc_stop = fotg210_udc_stop,
- };
-
--static int fotg210_udc_remove(struct platform_device *pdev)
-+int fotg210_udc_remove(struct platform_device *pdev)
- {
- struct fotg210_udc *fotg210 = platform_get_drvdata(pdev);
- int i;
-@@ -1098,7 +1099,7 @@ static int fotg210_udc_remove(struct pla
- return 0;
- }
-
--static int fotg210_udc_probe(struct platform_device *pdev)
-+int fotg210_udc_probe(struct platform_device *pdev)
- {
- struct resource *res, *ires;
- struct fotg210_udc *fotg210 = NULL;
-@@ -1223,17 +1224,3 @@ err_alloc:
- err:
- return ret;
- }
--
--static struct platform_driver fotg210_driver = {
-- .driver = {
-- .name = udc_name,
-- },
-- .probe = fotg210_udc_probe,
-- .remove = fotg210_udc_remove,
--};
--
--module_platform_driver(fotg210_driver);
--
--MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>");
--MODULE_LICENSE("GPL");
--MODULE_DESCRIPTION(DRIVER_DESC);
---- /dev/null
-+++ b/drivers/usb/fotg210/fotg210.h
-@@ -0,0 +1,42 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __FOTG210_H
-+#define __FOTG210_H
-+
-+#ifdef CONFIG_USB_FOTG210_HCD
-+int fotg210_hcd_probe(struct platform_device *pdev);
-+int fotg210_hcd_remove(struct platform_device *pdev);
-+int fotg210_hcd_init(void);
-+void fotg210_hcd_cleanup(void);
-+#else
-+static inline int fotg210_hcd_probe(struct platform_device *pdev)
-+{
-+ return 0;
-+}
-+static inline int fotg210_hcd_remove(struct platform_device *pdev)
-+{
-+ return 0;
-+}
-+static inline int fotg210_hcd_init(void)
-+{
-+ return 0;
-+}
-+static inline void fotg210_hcd_cleanup(void)
-+{
-+}
-+#endif
-+
-+#ifdef CONFIG_USB_FOTG210_UDC
-+int fotg210_udc_probe(struct platform_device *pdev);
-+int fotg210_udc_remove(struct platform_device *pdev);
-+#else
-+static inline int fotg210_udc_probe(struct platform_device *pdev)
-+{
-+ return 0;
-+}
-+static inline int fotg210_udc_remove(struct platform_device *pdev)
-+{
-+ return 0;
-+}
-+#endif
-+
-+#endif /* __FOTG210_H */
+++ /dev/null
-From 7c0b661926097e935f2711857596fc2277b2304a Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 23 Oct 2022 16:47:08 +0200
-Subject: [PATCH 04/29] usb: fotg210: Select subdriver by mode
-
-Check which mode the hardware is in, and selecte the peripheral
-driver if the hardware is in explicit peripheral mode, otherwise
-select host mode.
-
-This should solve the immediate problem that both subdrivers
-can get probed.
-
-Cc: Fabian Vogt <fabian@ritter-vogt.de>
-Cc: Yuan-Hsin Chen <yhchen@faraday-tech.com>
-Cc: Felipe Balbi <balbi@kernel.org>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221023144708.3596563-3-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-core.c
-+++ b/drivers/usb/fotg210/fotg210-core.c
-@@ -10,30 +10,37 @@
- #include <linux/of.h>
- #include <linux/platform_device.h>
- #include <linux/usb.h>
-+#include <linux/usb/otg.h>
-
- #include "fotg210.h"
-
- static int fotg210_probe(struct platform_device *pdev)
- {
-+ struct device *dev = &pdev->dev;
-+ enum usb_dr_mode mode;
- int ret;
-
-- if (IS_ENABLED(CONFIG_USB_FOTG210_HCD)) {
-- ret = fotg210_hcd_probe(pdev);
-- if (ret)
-- return ret;
-- }
-- if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
-+ mode = usb_get_dr_mode(dev);
-+
-+ if (mode == USB_DR_MODE_PERIPHERAL)
- ret = fotg210_udc_probe(pdev);
-+ else
-+ ret = fotg210_hcd_probe(pdev);
-
- return ret;
- }
-
- static int fotg210_remove(struct platform_device *pdev)
- {
-- if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
-- fotg210_hcd_remove(pdev);
-- if (IS_ENABLED(CONFIG_USB_FOTG210_UDC))
-+ struct device *dev = &pdev->dev;
-+ enum usb_dr_mode mode;
-+
-+ mode = usb_get_dr_mode(dev);
-+
-+ if (mode == USB_DR_MODE_PERIPHERAL)
- fotg210_udc_remove(pdev);
-+ else
-+ fotg210_hcd_remove(pdev);
-
- return 0;
- }
+++ /dev/null
-From f7f6c8aca91093e2f886ec97910b1a7d9a69bf9b Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 9 Nov 2022 21:05:54 +0100
-Subject: [PATCH 05/29] usb: fotg2: add Gemini-specific handling
-
-The Cortina Systems Gemini has bolted on a PHY inside the
-silicon that can be handled by six bits in a MISC register in
-the system controller.
-
-If we are running on Gemini, look up a syscon regmap through
-a phandle and enable VBUS and optionally the Mini-B connector.
-
-If the device is flagged as "wakeup-source" using the standard
-DT bindings, we also enable this in the global controller for
-respective port.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221109200554.1957185-1-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/Kconfig
-+++ b/drivers/usb/fotg210/Kconfig
-@@ -5,6 +5,7 @@ config USB_FOTG210
- depends on USB || USB_GADGET
- depends on HAS_DMA && HAS_IOMEM
- default ARCH_GEMINI
-+ select MFD_SYSCON
- help
- Faraday FOTG210 is a dual-mode USB controller that can act
- in both host controller and peripheral controller mode.
---- a/drivers/usb/fotg210/fotg210-core.c
-+++ b/drivers/usb/fotg210/fotg210-core.c
-@@ -5,15 +5,86 @@
- * whether to proceed with probing the host or the peripheral
- * driver.
- */
-+#include <linux/bitops.h>
- #include <linux/device.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/module.h>
- #include <linux/of.h>
- #include <linux/platform_device.h>
-+#include <linux/regmap.h>
- #include <linux/usb.h>
- #include <linux/usb/otg.h>
-
- #include "fotg210.h"
-
-+/*
-+ * Gemini-specific initialization function, only executed on the
-+ * Gemini SoC using the global misc control register.
-+ *
-+ * The gemini USB blocks are connected to either Mini-A (host mode) or
-+ * Mini-B (peripheral mode) plugs. There is no role switch support on the
-+ * Gemini SoC, just either-or.
-+ */
-+#define GEMINI_GLOBAL_MISC_CTRL 0x30
-+#define GEMINI_MISC_USB0_WAKEUP BIT(14)
-+#define GEMINI_MISC_USB1_WAKEUP BIT(15)
-+#define GEMINI_MISC_USB0_VBUS_ON BIT(22)
-+#define GEMINI_MISC_USB1_VBUS_ON BIT(23)
-+#define GEMINI_MISC_USB0_MINI_B BIT(29)
-+#define GEMINI_MISC_USB1_MINI_B BIT(30)
-+
-+static int fotg210_gemini_init(struct device *dev, struct resource *res,
-+ enum usb_dr_mode mode)
-+{
-+ struct device_node *np = dev->of_node;
-+ struct regmap *map;
-+ bool wakeup;
-+ u32 mask, val;
-+ int ret;
-+
-+ map = syscon_regmap_lookup_by_phandle(np, "syscon");
-+ if (IS_ERR(map)) {
-+ dev_err(dev, "no syscon\n");
-+ return PTR_ERR(map);
-+ }
-+ wakeup = of_property_read_bool(np, "wakeup-source");
-+
-+ /*
-+ * Figure out if this is USB0 or USB1 by simply checking the
-+ * physical base address.
-+ */
-+ mask = 0;
-+ if (res->start == 0x69000000) {
-+ mask = GEMINI_MISC_USB1_VBUS_ON | GEMINI_MISC_USB1_MINI_B |
-+ GEMINI_MISC_USB1_WAKEUP;
-+ if (mode == USB_DR_MODE_HOST)
-+ val = GEMINI_MISC_USB1_VBUS_ON;
-+ else
-+ val = GEMINI_MISC_USB1_MINI_B;
-+ if (wakeup)
-+ val |= GEMINI_MISC_USB1_WAKEUP;
-+ } else {
-+ mask = GEMINI_MISC_USB0_VBUS_ON | GEMINI_MISC_USB0_MINI_B |
-+ GEMINI_MISC_USB0_WAKEUP;
-+ if (mode == USB_DR_MODE_HOST)
-+ val = GEMINI_MISC_USB0_VBUS_ON;
-+ else
-+ val = GEMINI_MISC_USB0_MINI_B;
-+ if (wakeup)
-+ val |= GEMINI_MISC_USB0_WAKEUP;
-+ }
-+
-+ ret = regmap_update_bits(map, GEMINI_GLOBAL_MISC_CTRL, mask, val);
-+ if (ret) {
-+ dev_err(dev, "failed to initialize Gemini PHY\n");
-+ return ret;
-+ }
-+
-+ dev_info(dev, "initialized Gemini PHY in %s mode\n",
-+ (mode == USB_DR_MODE_HOST) ? "host" : "gadget");
-+ return 0;
-+}
-+
- static int fotg210_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -22,6 +93,15 @@ static int fotg210_probe(struct platform
-
- mode = usb_get_dr_mode(dev);
-
-+ if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) {
-+ struct resource *res;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ ret = fotg210_gemini_init(dev, res, mode);
-+ if (ret)
-+ return ret;
-+ }
-+
- if (mode == USB_DR_MODE_PERIPHERAL)
- ret = fotg210_udc_probe(pdev);
- else
+++ /dev/null
-From 6e002d41889bc52213a26ff91338d340505e0336 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Fri, 11 Nov 2022 15:48:21 +0100
-Subject: [PATCH 06/29] usb: fotg210: Fix Kconfig for USB host modules
-
-The kernel robot reports a link failure when activating the
-FOTG210 host subdriver with =y on a system where the USB host
-core is a module (CONFIG_USB=m).
-
-This is a bit of special case, so mimic the Kconfig incantations
-from DWC3: let the subdrivers for host or peripheral depend
-on the host or gadget support being =y or the same as the
-FOTG210 core itself.
-
-This should ensure that either:
-
-- The host (CONFIG_USB) or gadget (CONFIG_GADGET) is compiled
- in and then the FOTG210 can be either module or compiled
- in.
-
-- The host or gadget is modular, and then the FOTG210 module
- must be a module too, or we cannot resolve the symbols
- at link time.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Link: https://lore.kernel.org/linux-usb/202211112132.0BUPGKCd-lkp@intel.com/
-Cc: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221111144821.113665-1-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/Kconfig
-+++ b/drivers/usb/fotg210/Kconfig
-@@ -14,7 +14,7 @@ if USB_FOTG210
-
- config USB_FOTG210_HCD
- bool "Faraday FOTG210 USB Host Controller support"
-- depends on USB
-+ depends on USB=y || USB=USB_FOTG210
- help
- Faraday FOTG210 is an OTG controller which can be configured as
- an USB2.0 host. It is designed to meet USB2.0 EHCI specification
-@@ -24,7 +24,7 @@ config USB_FOTG210_HCD
- module will be called fotg210-hcd.
-
- config USB_FOTG210_UDC
-- depends on USB_GADGET
-+ depends on USB_GADGET=y || USB_GADGET=USB_FOTG210
- bool "Faraday FOTG210 USB Peripheral Controller support"
- help
- Faraday USB2.0 OTG controller which can be configured as
+++ /dev/null
-From 466b10510add46afd21ca19505b29d35ad853370 Mon Sep 17 00:00:00 2001
-From: Geert Uytterhoeven <geert+renesas@glider.be>
-Date: Mon, 21 Nov 2022 16:22:19 +0100
-Subject: [PATCH 07/29] usb: USB_FOTG210 should depend on ARCH_GEMINI
-
-The Faraday Technology FOTG210 USB2 Dual Role Controller is only present
-on Cortina Systems Gemini SoCs. Hence add a dependency on ARCH_GEMINI,
-to prevent asking the user about its drivers when configuring a kernel
-without Cortina Systems Gemini SoC support.
-
-Fixes: 1dd33a9f1b95ab59 ("usb: fotg210: Collect pieces of dual mode controller")
-Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/a989b3b798ecaf3b45f35160e30e605636d66a77.1669044086.git.geert+renesas@glider.be
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/Kconfig
-+++ b/drivers/usb/fotg210/Kconfig
-@@ -4,6 +4,7 @@ config USB_FOTG210
- tristate "Faraday FOTG210 USB2 Dual Role controller"
- depends on USB || USB_GADGET
- depends on HAS_DMA && HAS_IOMEM
-+ depends on ARCH_GEMINI || COMPILE_TEST
- default ARCH_GEMINI
- select MFD_SYSCON
- help
+++ /dev/null
-From 27cd321a365fecac857e41ad1681062994142e4a Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 14 Nov 2022 12:51:58 +0100
-Subject: [PATCH 08/29] fotg210-udc: Use dev pointer in probe and dev_messages
-
-Add a local struct device *dev pointer and use dev_err()
-etc to report status.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221114115201.302887-1-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -1104,6 +1104,7 @@ int fotg210_udc_probe(struct platform_de
- struct resource *res, *ires;
- struct fotg210_udc *fotg210 = NULL;
- struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP];
-+ struct device *dev = &pdev->dev;
- int ret = 0;
- int i;
-
-@@ -1135,7 +1136,7 @@ int fotg210_udc_probe(struct platform_de
-
- fotg210->reg = ioremap(res->start, resource_size(res));
- if (fotg210->reg == NULL) {
-- pr_err("ioremap error.\n");
-+ dev_err(dev, "ioremap error\n");
- goto err_alloc;
- }
-
-@@ -1146,8 +1147,8 @@ int fotg210_udc_probe(struct platform_de
- fotg210->gadget.ops = &fotg210_gadget_ops;
-
- fotg210->gadget.max_speed = USB_SPEED_HIGH;
-- fotg210->gadget.dev.parent = &pdev->dev;
-- fotg210->gadget.dev.dma_mask = pdev->dev.dma_mask;
-+ fotg210->gadget.dev.parent = dev;
-+ fotg210->gadget.dev.dma_mask = dev->dma_mask;
- fotg210->gadget.name = udc_name;
-
- INIT_LIST_HEAD(&fotg210->gadget.ep_list);
-@@ -1195,15 +1196,15 @@ int fotg210_udc_probe(struct platform_de
- ret = request_irq(ires->start, fotg210_irq, IRQF_SHARED,
- udc_name, fotg210);
- if (ret < 0) {
-- pr_err("request_irq error (%d)\n", ret);
-+ dev_err(dev, "request_irq error (%d)\n", ret);
- goto err_req;
- }
-
-- ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget);
-+ ret = usb_add_gadget_udc(dev, &fotg210->gadget);
- if (ret)
- goto err_add_udc;
-
-- dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
-+ dev_info(dev, "version %s\n", DRIVER_VERSION);
-
- return 0;
-
+++ /dev/null
-From 03e4b585ac947e2d422bedf03179bbfec3aca3cf Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 14 Nov 2022 12:51:59 +0100
-Subject: [PATCH 09/29] fotg210-udc: Support optional external PHY
-
-This adds support for an optional external PHY to the FOTG210
-UDC driver.
-
-Tested with the GPIO VBUS PHY driver on the Gemini SoC.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221114115201.302887-2-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -15,6 +15,8 @@
- #include <linux/platform_device.h>
- #include <linux/usb/ch9.h>
- #include <linux/usb/gadget.h>
-+#include <linux/usb/otg.h>
-+#include <linux/usb/phy.h>
-
- #include "fotg210.h"
- #include "fotg210-udc.h"
-@@ -1022,10 +1024,18 @@ static int fotg210_udc_start(struct usb_
- {
- struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
- u32 value;
-+ int ret;
-
- /* hook up the driver */
- fotg210->driver = driver;
-
-+ if (!IS_ERR_OR_NULL(fotg210->phy)) {
-+ ret = otg_set_peripheral(fotg210->phy->otg,
-+ &fotg210->gadget);
-+ if (ret)
-+ dev_err(fotg210->dev, "can't bind to phy\n");
-+ }
-+
- /* enable device global interrupt */
- value = ioread32(fotg210->reg + FOTG210_DMCR);
- value |= DMCR_GLINT_EN;
-@@ -1067,6 +1077,9 @@ static int fotg210_udc_stop(struct usb_g
- struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
- unsigned long flags;
-
-+ if (!IS_ERR_OR_NULL(fotg210->phy))
-+ return otg_set_peripheral(fotg210->phy->otg, NULL);
-+
- spin_lock_irqsave(&fotg210->lock, flags);
-
- fotg210_init(fotg210);
-@@ -1082,12 +1095,50 @@ static const struct usb_gadget_ops fotg2
- .udc_stop = fotg210_udc_stop,
- };
-
-+/**
-+ * fotg210_phy_event - Called by phy upon VBus event
-+ * @nb: notifier block
-+ * @action: phy action, is vbus connect or disconnect
-+ * @data: the usb_gadget structure in fotg210
-+ *
-+ * Called by the USB Phy when a cable connect or disconnect is sensed.
-+ *
-+ * Returns NOTIFY_OK or NOTIFY_DONE
-+ */
-+static int fotg210_phy_event(struct notifier_block *nb, unsigned long action,
-+ void *data)
-+{
-+ struct usb_gadget *gadget = data;
-+
-+ if (!gadget)
-+ return NOTIFY_DONE;
-+
-+ switch (action) {
-+ case USB_EVENT_VBUS:
-+ usb_gadget_vbus_connect(gadget);
-+ return NOTIFY_OK;
-+ case USB_EVENT_NONE:
-+ usb_gadget_vbus_disconnect(gadget);
-+ return NOTIFY_OK;
-+ default:
-+ return NOTIFY_DONE;
-+ }
-+}
-+
-+static struct notifier_block fotg210_phy_notifier = {
-+ .notifier_call = fotg210_phy_event,
-+};
-+
- int fotg210_udc_remove(struct platform_device *pdev)
- {
- struct fotg210_udc *fotg210 = platform_get_drvdata(pdev);
- int i;
-
- usb_del_gadget_udc(&fotg210->gadget);
-+ if (!IS_ERR_OR_NULL(fotg210->phy)) {
-+ usb_unregister_notifier(fotg210->phy, &fotg210_phy_notifier);
-+ usb_put_phy(fotg210->phy);
-+ }
- iounmap(fotg210->reg);
- free_irq(platform_get_irq(pdev, 0), fotg210);
-
-@@ -1127,6 +1178,22 @@ int fotg210_udc_probe(struct platform_de
- if (fotg210 == NULL)
- goto err;
-
-+ fotg210->dev = dev;
-+
-+ fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0);
-+ if (IS_ERR(fotg210->phy)) {
-+ ret = PTR_ERR(fotg210->phy);
-+ if (ret == -EPROBE_DEFER)
-+ goto err;
-+ dev_info(dev, "no PHY found\n");
-+ fotg210->phy = NULL;
-+ } else {
-+ ret = usb_phy_init(fotg210->phy);
-+ if (ret)
-+ goto err;
-+ dev_info(dev, "found and initialized PHY\n");
-+ }
-+
- for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
- _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
- if (_ep[i] == NULL)
-@@ -1200,6 +1267,9 @@ int fotg210_udc_probe(struct platform_de
- goto err_req;
- }
-
-+ if (!IS_ERR_OR_NULL(fotg210->phy))
-+ usb_register_notifier(fotg210->phy, &fotg210_phy_notifier);
-+
- ret = usb_add_gadget_udc(dev, &fotg210->gadget);
- if (ret)
- goto err_add_udc;
-@@ -1209,6 +1279,8 @@ int fotg210_udc_probe(struct platform_de
- return 0;
-
- err_add_udc:
-+ if (!IS_ERR_OR_NULL(fotg210->phy))
-+ usb_unregister_notifier(fotg210->phy, &fotg210_phy_notifier);
- free_irq(ires->start, fotg210);
-
- err_req:
---- a/drivers/usb/fotg210/fotg210-udc.h
-+++ b/drivers/usb/fotg210/fotg210-udc.h
-@@ -234,6 +234,8 @@ struct fotg210_udc {
-
- unsigned long irq_trigger;
-
-+ struct device *dev;
-+ struct usb_phy *phy;
- struct usb_gadget gadget;
- struct usb_gadget_driver *driver;
-
+++ /dev/null
-From 772ea3ec2b9363b45ef9a4768ea205f758c3debc Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 14 Nov 2022 12:52:00 +0100
-Subject: [PATCH 10/29] fotg210-udc: Handle PCLK
-
-This adds optional handling of the peripheral clock PCLK.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221114115201.302887-3-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -15,6 +15,7 @@
- #include <linux/platform_device.h>
- #include <linux/usb/ch9.h>
- #include <linux/usb/gadget.h>
-+#include <linux/clk.h>
- #include <linux/usb/otg.h>
- #include <linux/usb/phy.h>
-
-@@ -1145,6 +1146,10 @@ int fotg210_udc_remove(struct platform_d
- fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
- for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
- kfree(fotg210->ep[i]);
-+
-+ if (!IS_ERR(fotg210->pclk))
-+ clk_disable_unprepare(fotg210->pclk);
-+
- kfree(fotg210);
-
- return 0;
-@@ -1180,17 +1185,34 @@ int fotg210_udc_probe(struct platform_de
-
- fotg210->dev = dev;
-
-+ /* It's OK not to supply this clock */
-+ fotg210->pclk = devm_clk_get(dev, "PCLK");
-+ if (!IS_ERR(fotg210->pclk)) {
-+ ret = clk_prepare_enable(fotg210->pclk);
-+ if (ret) {
-+ dev_err(dev, "failed to enable PCLK\n");
-+ return ret;
-+ }
-+ } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
-+ /*
-+ * Percolate deferrals, for anything else,
-+ * just live without the clocking.
-+ */
-+ ret = -EPROBE_DEFER;
-+ goto err;
-+ }
-+
- fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0);
- if (IS_ERR(fotg210->phy)) {
- ret = PTR_ERR(fotg210->phy);
- if (ret == -EPROBE_DEFER)
-- goto err;
-+ goto err_pclk;
- dev_info(dev, "no PHY found\n");
- fotg210->phy = NULL;
- } else {
- ret = usb_phy_init(fotg210->phy);
- if (ret)
-- goto err;
-+ goto err_pclk;
- dev_info(dev, "found and initialized PHY\n");
- }
-
-@@ -1292,6 +1314,10 @@ err_map:
- err_alloc:
- for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
- kfree(fotg210->ep[i]);
-+err_pclk:
-+ if (!IS_ERR(fotg210->pclk))
-+ clk_disable_unprepare(fotg210->pclk);
-+
- kfree(fotg210);
-
- err:
---- a/drivers/usb/fotg210/fotg210-udc.h
-+++ b/drivers/usb/fotg210/fotg210-udc.h
-@@ -231,6 +231,7 @@ struct fotg210_ep {
- struct fotg210_udc {
- spinlock_t lock; /* protect the struct */
- void __iomem *reg;
-+ struct clk *pclk;
-
- unsigned long irq_trigger;
-
+++ /dev/null
-From eda686d41e298a9d16708d2ec8d12d8e682dd7ca Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 14 Nov 2022 12:52:01 +0100
-Subject: [PATCH 11/29] fotg210-udc: Get IRQ using platform_get_irq()
-
-The platform_get_irq() is necessary to use to get dynamic
-IRQ resolution when instantiating the device from the
-device tree. IRQs are not passed as resources in that
-case.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221114115201.302887-4-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -1157,10 +1157,11 @@ int fotg210_udc_remove(struct platform_d
-
- int fotg210_udc_probe(struct platform_device *pdev)
- {
-- struct resource *res, *ires;
-+ struct resource *res;
- struct fotg210_udc *fotg210 = NULL;
- struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP];
- struct device *dev = &pdev->dev;
-+ int irq;
- int ret = 0;
- int i;
-
-@@ -1170,9 +1171,9 @@ int fotg210_udc_probe(struct platform_de
- return -ENODEV;
- }
-
-- ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-- if (!ires) {
-- pr_err("platform_get_resource IORESOURCE_IRQ error.\n");
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0) {
-+ pr_err("could not get irq\n");
- return -ENODEV;
- }
-
-@@ -1202,7 +1203,7 @@ int fotg210_udc_probe(struct platform_de
- goto err;
- }
-
-- fotg210->phy = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0);
-+ fotg210->phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
- if (IS_ERR(fotg210->phy)) {
- ret = PTR_ERR(fotg210->phy);
- if (ret == -EPROBE_DEFER)
-@@ -1282,7 +1283,7 @@ int fotg210_udc_probe(struct platform_de
-
- fotg210_disable_unplug(fotg210);
-
-- ret = request_irq(ires->start, fotg210_irq, IRQF_SHARED,
-+ ret = request_irq(irq, fotg210_irq, IRQF_SHARED,
- udc_name, fotg210);
- if (ret < 0) {
- dev_err(dev, "request_irq error (%d)\n", ret);
-@@ -1303,7 +1304,7 @@ int fotg210_udc_probe(struct platform_de
- err_add_udc:
- if (!IS_ERR_OR_NULL(fotg210->phy))
- usb_unregister_notifier(fotg210->phy, &fotg210_phy_notifier);
-- free_irq(ires->start, fotg210);
-+ free_irq(irq, fotg210);
-
- err_req:
- fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
+++ /dev/null
-From 7889a2f0256c55e0184dffd0001d0782f9e4cb83 Mon Sep 17 00:00:00 2001
-From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
-Date: Mon, 14 Nov 2022 21:38:04 +0100
-Subject: [PATCH 12/29] usb: fotg210-udc: Remove a useless assignment
-
-There is no need to use an intermediate array for these memory allocations,
-so, axe it.
-
-While at it, turn a '== NULL' into a shorter '!' when testing memory
-allocation failure.
-
-Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/deab9696fc4000499470e7ccbca7c36fca17bd4e.1668458274.git.christophe.jaillet@wanadoo.fr
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -1159,7 +1159,6 @@ int fotg210_udc_probe(struct platform_de
- {
- struct resource *res;
- struct fotg210_udc *fotg210 = NULL;
-- struct fotg210_ep *_ep[FOTG210_MAX_NUM_EP];
- struct device *dev = &pdev->dev;
- int irq;
- int ret = 0;
-@@ -1218,10 +1217,9 @@ int fotg210_udc_probe(struct platform_de
- }
-
- for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
-- _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
-- if (_ep[i] == NULL)
-+ fotg210->ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
-+ if (!fotg210->ep[i])
- goto err_alloc;
-- fotg210->ep[i] = _ep[i];
- }
-
- fotg210->reg = ioremap(res->start, resource_size(res));
+++ /dev/null
-From 7b95ade85ac18eec63e81ac58a482b3e88361ffd Mon Sep 17 00:00:00 2001
-From: Yi Yang <yiyang13@huawei.com>
-Date: Fri, 2 Dec 2022 09:21:26 +0800
-Subject: [PATCH 13/29] usb: fotg210-udc: fix potential memory leak in
- fotg210_udc_probe()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-In fotg210_udc_probe(), if devm_clk_get() or clk_prepare_enable()
-fails, 'fotg210' will not be freed, which will lead to a memory leak.
-Fix it by moving kfree() to a proper location.
-
-In addition,we can use "return -ENOMEM" instead of "goto err"
-to simplify the code.
-
-Fixes: 718a38d092ec ("fotg210-udc: Handle PCLK")
-Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: Yi Yang <yiyang13@huawei.com>
-Link: https://lore.kernel.org/r/20221202012126.246953-1-yiyang13@huawei.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -1176,12 +1176,10 @@ int fotg210_udc_probe(struct platform_de
- return -ENODEV;
- }
-
-- ret = -ENOMEM;
--
- /* initialize udc */
- fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL);
- if (fotg210 == NULL)
-- goto err;
-+ return -ENOMEM;
-
- fotg210->dev = dev;
-
-@@ -1191,7 +1189,7 @@ int fotg210_udc_probe(struct platform_de
- ret = clk_prepare_enable(fotg210->pclk);
- if (ret) {
- dev_err(dev, "failed to enable PCLK\n");
-- return ret;
-+ goto err;
- }
- } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
- /*
-@@ -1317,8 +1315,7 @@ err_pclk:
- if (!IS_ERR(fotg210->pclk))
- clk_disable_unprepare(fotg210->pclk);
-
-- kfree(fotg210);
--
- err:
-+ kfree(fotg210);
- return ret;
- }
+++ /dev/null
-From d8eed400495029ba551704ff0fae1dad87332291 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Thu, 15 Dec 2022 17:57:20 +0100
-Subject: [PATCH 14/29] usb: fotg210: fix OTG-only build
-
-The fotg210 module combines the HCD and OTG drivers, which then
-fails to build when only the USB gadget support is enabled
-in the kernel but host support is not:
-
-aarch64-linux-ld: drivers/usb/fotg210/fotg210-core.o: in function `fotg210_init':
-fotg210-core.c:(.init.text+0xc): undefined reference to `usb_disabled'
-
-Move the check for usb_disabled() after the check for the HCD module,
-and let the OTG driver still be probed in this configuration.
-
-A nicer approach might be to have the common portion built as a
-library module, with the two platform other files registering
-their own platform_driver instances separately.
-
-Fixes: ddacd6ef44ca ("usb: fotg210: Fix Kconfig for USB host modules")
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Link: https://lore.kernel.org/r/20221215165728.2062984-1-arnd@kernel.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-core.c
-+++ b/drivers/usb/fotg210/fotg210-core.c
-@@ -144,10 +144,7 @@ static struct platform_driver fotg210_dr
-
- static int __init fotg210_init(void)
- {
-- if (usb_disabled())
-- return -ENODEV;
--
-- if (IS_ENABLED(CONFIG_USB_FOTG210_HCD))
-+ if (IS_ENABLED(CONFIG_USB_FOTG210_HCD) && !usb_disabled())
- fotg210_hcd_init();
- return platform_driver_register(&fotg210_driver);
- }
+++ /dev/null
-From eaaa85d907fe27852dd960b2bc5d7bcf11bc3ebd Mon Sep 17 00:00:00 2001
-From: Yang Yingliang <yangyingliang@huawei.com>
-Date: Fri, 30 Dec 2022 14:54:27 +0800
-Subject: [PATCH 15/29] usb: fotg210-udc: fix error return code in
- fotg210_udc_probe()
-
-After commit 5f217ccd520f ("fotg210-udc: Support optional external PHY"),
-the error code is re-assigned to 0 in fotg210_udc_probe(), if allocate or
-map memory fails after the assignment, it can't return an error code. Set
-the error code to -ENOMEM to fix this problem.
-
-Fixes: 5f217ccd520f ("fotg210-udc: Support optional external PHY")
-Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221230065427.944586-1-yangyingliang@huawei.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -1214,6 +1214,8 @@ int fotg210_udc_probe(struct platform_de
- dev_info(dev, "found and initialized PHY\n");
- }
-
-+ ret = -ENOMEM;
-+
- for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
- fotg210->ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
- if (!fotg210->ep[i])
+++ /dev/null
-From 407577548b2fcd41cc72ee05df1f05a430ed30a0 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 18 Jan 2023 08:09:16 +0100
-Subject: [PATCH 16/29] usb: fotg210: List different variants
-
-There are at least two variants of the FOTG: FOTG200 and
-FOTG210. Handle them in this driver and let's add
-more quirks as we go along.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-2-100388af9810@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-core.c
-+++ b/drivers/usb/fotg210/fotg210-core.c
-@@ -127,7 +127,9 @@ static int fotg210_remove(struct platfor
-
- #ifdef CONFIG_OF
- static const struct of_device_id fotg210_of_match[] = {
-+ { .compatible = "faraday,fotg200" },
- { .compatible = "faraday,fotg210" },
-+ /* TODO: can we also handle FUSB220? */
- {},
- };
- MODULE_DEVICE_TABLE(of, fotg210_of_match);
+++ /dev/null
-From fa735ad1afeb5791d5562617b9bbed74574d3e81 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 18 Jan 2023 08:09:17 +0100
-Subject: [PATCH 17/29] usb: fotg210: Acquire memory resource in core
-
-The subdrivers are obtaining and mapping the memory resource
-separately. Create a common state container for the shared
-resources and start populating this by acquiring the IO
-memory resource and remap it and pass this to the subdrivers
-for host and peripheral.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-3-100388af9810@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-core.c
-+++ b/drivers/usb/fotg210/fotg210-core.c
-@@ -33,9 +33,10 @@
- #define GEMINI_MISC_USB0_MINI_B BIT(29)
- #define GEMINI_MISC_USB1_MINI_B BIT(30)
-
--static int fotg210_gemini_init(struct device *dev, struct resource *res,
-+static int fotg210_gemini_init(struct fotg210 *fotg, struct resource *res,
- enum usb_dr_mode mode)
- {
-+ struct device *dev = fotg->dev;
- struct device_node *np = dev->of_node;
- struct regmap *map;
- bool wakeup;
-@@ -47,6 +48,7 @@ static int fotg210_gemini_init(struct de
- dev_err(dev, "no syscon\n");
- return PTR_ERR(map);
- }
-+ fotg->map = map;
- wakeup = of_property_read_bool(np, "wakeup-source");
-
- /*
-@@ -55,6 +57,7 @@ static int fotg210_gemini_init(struct de
- */
- mask = 0;
- if (res->start == 0x69000000) {
-+ fotg->port = GEMINI_PORT_1;
- mask = GEMINI_MISC_USB1_VBUS_ON | GEMINI_MISC_USB1_MINI_B |
- GEMINI_MISC_USB1_WAKEUP;
- if (mode == USB_DR_MODE_HOST)
-@@ -64,6 +67,7 @@ static int fotg210_gemini_init(struct de
- if (wakeup)
- val |= GEMINI_MISC_USB1_WAKEUP;
- } else {
-+ fotg->port = GEMINI_PORT_0;
- mask = GEMINI_MISC_USB0_VBUS_ON | GEMINI_MISC_USB0_MINI_B |
- GEMINI_MISC_USB0_WAKEUP;
- if (mode == USB_DR_MODE_HOST)
-@@ -89,23 +93,34 @@ static int fotg210_probe(struct platform
- {
- struct device *dev = &pdev->dev;
- enum usb_dr_mode mode;
-+ struct fotg210 *fotg;
- int ret;
-
-+ fotg = devm_kzalloc(dev, sizeof(*fotg), GFP_KERNEL);
-+ if (!fotg)
-+ return -ENOMEM;
-+ fotg->dev = dev;
-+
-+ fotg->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!fotg->res)
-+ return -ENODEV;
-+
-+ fotg->base = devm_ioremap_resource(dev, fotg->res);
-+ if (!fotg->base)
-+ return -ENOMEM;
-+
- mode = usb_get_dr_mode(dev);
-
- if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) {
-- struct resource *res;
--
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- ret = fotg210_gemini_init(dev, res, mode);
-+ ret = fotg210_gemini_init(fotg, fotg->res, mode);
- if (ret)
- return ret;
- }
-
- if (mode == USB_DR_MODE_PERIPHERAL)
-- ret = fotg210_udc_probe(pdev);
-+ ret = fotg210_udc_probe(pdev, fotg);
- else
-- ret = fotg210_hcd_probe(pdev);
-+ ret = fotg210_hcd_probe(pdev, fotg);
-
- return ret;
- }
---- a/drivers/usb/fotg210/fotg210-hcd.c
-+++ b/drivers/usb/fotg210/fotg210-hcd.c
-@@ -5557,11 +5557,10 @@ static void fotg210_init(struct fotg210_
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- */
--int fotg210_hcd_probe(struct platform_device *pdev)
-+int fotg210_hcd_probe(struct platform_device *pdev, struct fotg210 *fotg)
- {
- struct device *dev = &pdev->dev;
- struct usb_hcd *hcd;
-- struct resource *res;
- int irq;
- int retval;
- struct fotg210_hcd *fotg210;
-@@ -5585,18 +5584,14 @@ int fotg210_hcd_probe(struct platform_de
-
- hcd->has_tt = 1;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- hcd->regs = devm_ioremap_resource(&pdev->dev, res);
-- if (IS_ERR(hcd->regs)) {
-- retval = PTR_ERR(hcd->regs);
-- goto failed_put_hcd;
-- }
-+ hcd->regs = fotg->base;
-
-- hcd->rsrc_start = res->start;
-- hcd->rsrc_len = resource_size(res);
-+ hcd->rsrc_start = fotg->res->start;
-+ hcd->rsrc_len = resource_size(fotg->res);
-
- fotg210 = hcd_to_fotg210(hcd);
-
-+ fotg210->fotg = fotg;
- fotg210->caps = hcd->regs;
-
- /* It's OK not to supply this clock */
---- a/drivers/usb/fotg210/fotg210-hcd.h
-+++ b/drivers/usb/fotg210/fotg210-hcd.h
-@@ -182,6 +182,7 @@ struct fotg210_hcd { /* one per contro
- # define INCR(x) do {} while (0)
- #endif
-
-+ struct fotg210 *fotg; /* Overarching FOTG210 device */
- /* silicon clock */
- struct clk *pclk;
- };
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -1155,21 +1155,14 @@ int fotg210_udc_remove(struct platform_d
- return 0;
- }
-
--int fotg210_udc_probe(struct platform_device *pdev)
-+int fotg210_udc_probe(struct platform_device *pdev, struct fotg210 *fotg)
- {
-- struct resource *res;
- struct fotg210_udc *fotg210 = NULL;
- struct device *dev = &pdev->dev;
- int irq;
- int ret = 0;
- int i;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- if (!res) {
-- pr_err("platform_get_resource error.\n");
-- return -ENODEV;
-- }
--
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- pr_err("could not get irq\n");
-@@ -1182,6 +1175,7 @@ int fotg210_udc_probe(struct platform_de
- return -ENOMEM;
-
- fotg210->dev = dev;
-+ fotg210->fotg = fotg;
-
- /* It's OK not to supply this clock */
- fotg210->pclk = devm_clk_get(dev, "PCLK");
-@@ -1222,11 +1216,7 @@ int fotg210_udc_probe(struct platform_de
- goto err_alloc;
- }
-
-- fotg210->reg = ioremap(res->start, resource_size(res));
-- if (fotg210->reg == NULL) {
-- dev_err(dev, "ioremap error\n");
-- goto err_alloc;
-- }
-+ fotg210->reg = fotg->base;
-
- spin_lock_init(&fotg210->lock);
-
---- a/drivers/usb/fotg210/fotg210-udc.h
-+++ b/drivers/usb/fotg210/fotg210-udc.h
-@@ -236,6 +236,7 @@ struct fotg210_udc {
- unsigned long irq_trigger;
-
- struct device *dev;
-+ struct fotg210 *fotg;
- struct usb_phy *phy;
- struct usb_gadget gadget;
- struct usb_gadget_driver *driver;
---- a/drivers/usb/fotg210/fotg210.h
-+++ b/drivers/usb/fotg210/fotg210.h
-@@ -2,13 +2,28 @@
- #ifndef __FOTG210_H
- #define __FOTG210_H
-
-+enum gemini_port {
-+ GEMINI_PORT_NONE = 0,
-+ GEMINI_PORT_0,
-+ GEMINI_PORT_1,
-+};
-+
-+struct fotg210 {
-+ struct device *dev;
-+ struct resource *res;
-+ void __iomem *base;
-+ struct regmap *map;
-+ enum gemini_port port;
-+};
-+
- #ifdef CONFIG_USB_FOTG210_HCD
--int fotg210_hcd_probe(struct platform_device *pdev);
-+int fotg210_hcd_probe(struct platform_device *pdev, struct fotg210 *fotg);
- int fotg210_hcd_remove(struct platform_device *pdev);
- int fotg210_hcd_init(void);
- void fotg210_hcd_cleanup(void);
- #else
--static inline int fotg210_hcd_probe(struct platform_device *pdev)
-+static inline int fotg210_hcd_probe(struct platform_device *pdev,
-+ struct fotg210 *fotg)
- {
- return 0;
- }
-@@ -26,10 +41,11 @@ static inline void fotg210_hcd_cleanup(v
- #endif
-
- #ifdef CONFIG_USB_FOTG210_UDC
--int fotg210_udc_probe(struct platform_device *pdev);
-+int fotg210_udc_probe(struct platform_device *pdev, struct fotg210 *fotg);
- int fotg210_udc_remove(struct platform_device *pdev);
- #else
--static inline int fotg210_udc_probe(struct platform_device *pdev)
-+static inline int fotg210_udc_probe(struct platform_device *pdev,
-+ struct fotg210 *fotg)
- {
- return 0;
- }
+++ /dev/null
-From fb8e1e8dbc47e7aff7624b47adaa0a84d2983802 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 18 Jan 2023 08:09:18 +0100
-Subject: [PATCH 18/29] usb: fotg210: Move clock handling to core
-
-Grab the optional silicon block clock, prepare and enable it in
-the core before proceeding to prepare the host or peripheral
-driver. This saves duplicate code and also uses the simple
-devm_clk_get_optional_enabled() to do everything we really
-want to do.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-4-100388af9810@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-core.c
-+++ b/drivers/usb/fotg210/fotg210-core.c
-@@ -6,6 +6,7 @@
- * driver.
- */
- #include <linux/bitops.h>
-+#include <linux/clk.h>
- #include <linux/device.h>
- #include <linux/mfd/syscon.h>
- #include <linux/module.h>
-@@ -109,6 +110,10 @@ static int fotg210_probe(struct platform
- if (!fotg->base)
- return -ENOMEM;
-
-+ fotg->pclk = devm_clk_get_optional_enabled(dev, "PCLK");
-+ if (IS_ERR(fotg->pclk))
-+ return PTR_ERR(fotg->pclk);
-+
- mode = usb_get_dr_mode(dev);
-
- if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) {
---- a/drivers/usb/fotg210/fotg210-hcd.c
-+++ b/drivers/usb/fotg210/fotg210-hcd.c
-@@ -33,7 +33,6 @@
- #include <linux/platform_device.h>
- #include <linux/io.h>
- #include <linux/iopoll.h>
--#include <linux/clk.h>
-
- #include <asm/byteorder.h>
- #include <asm/irq.h>
-@@ -5594,44 +5593,22 @@ int fotg210_hcd_probe(struct platform_de
- fotg210->fotg = fotg;
- fotg210->caps = hcd->regs;
-
-- /* It's OK not to supply this clock */
-- fotg210->pclk = clk_get(dev, "PCLK");
-- if (!IS_ERR(fotg210->pclk)) {
-- retval = clk_prepare_enable(fotg210->pclk);
-- if (retval) {
-- dev_err(dev, "failed to enable PCLK\n");
-- goto failed_put_hcd;
-- }
-- } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
-- /*
-- * Percolate deferrals, for anything else,
-- * just live without the clocking.
-- */
-- retval = PTR_ERR(fotg210->pclk);
-- goto failed_dis_clk;
-- }
--
- retval = fotg210_setup(hcd);
- if (retval)
-- goto failed_dis_clk;
-+ goto failed_put_hcd;
-
- fotg210_init(fotg210);
-
- retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
- if (retval) {
- dev_err(dev, "failed to add hcd with err %d\n", retval);
-- goto failed_dis_clk;
-+ goto failed_put_hcd;
- }
- device_wakeup_enable(hcd->self.controller);
- platform_set_drvdata(pdev, hcd);
-
- return retval;
-
--failed_dis_clk:
-- if (!IS_ERR(fotg210->pclk)) {
-- clk_disable_unprepare(fotg210->pclk);
-- clk_put(fotg210->pclk);
-- }
- failed_put_hcd:
- usb_put_hcd(hcd);
- fail_create_hcd:
-@@ -5647,12 +5624,6 @@ fail_create_hcd:
- int fotg210_hcd_remove(struct platform_device *pdev)
- {
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-- struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
--
-- if (!IS_ERR(fotg210->pclk)) {
-- clk_disable_unprepare(fotg210->pclk);
-- clk_put(fotg210->pclk);
-- }
-
- usb_remove_hcd(hcd);
- usb_put_hcd(hcd);
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -15,7 +15,6 @@
- #include <linux/platform_device.h>
- #include <linux/usb/ch9.h>
- #include <linux/usb/gadget.h>
--#include <linux/clk.h>
- #include <linux/usb/otg.h>
- #include <linux/usb/phy.h>
-
-@@ -1147,9 +1146,6 @@ int fotg210_udc_remove(struct platform_d
- for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
- kfree(fotg210->ep[i]);
-
-- if (!IS_ERR(fotg210->pclk))
-- clk_disable_unprepare(fotg210->pclk);
--
- kfree(fotg210);
-
- return 0;
-@@ -1177,34 +1173,17 @@ int fotg210_udc_probe(struct platform_de
- fotg210->dev = dev;
- fotg210->fotg = fotg;
-
-- /* It's OK not to supply this clock */
-- fotg210->pclk = devm_clk_get(dev, "PCLK");
-- if (!IS_ERR(fotg210->pclk)) {
-- ret = clk_prepare_enable(fotg210->pclk);
-- if (ret) {
-- dev_err(dev, "failed to enable PCLK\n");
-- goto err;
-- }
-- } else if (PTR_ERR(fotg210->pclk) == -EPROBE_DEFER) {
-- /*
-- * Percolate deferrals, for anything else,
-- * just live without the clocking.
-- */
-- ret = -EPROBE_DEFER;
-- goto err;
-- }
--
- fotg210->phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
- if (IS_ERR(fotg210->phy)) {
- ret = PTR_ERR(fotg210->phy);
- if (ret == -EPROBE_DEFER)
-- goto err_pclk;
-+ goto err_free;
- dev_info(dev, "no PHY found\n");
- fotg210->phy = NULL;
- } else {
- ret = usb_phy_init(fotg210->phy);
- if (ret)
-- goto err_pclk;
-+ goto err_free;
- dev_info(dev, "found and initialized PHY\n");
- }
-
-@@ -1303,11 +1282,8 @@ err_map:
- err_alloc:
- for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
- kfree(fotg210->ep[i]);
--err_pclk:
-- if (!IS_ERR(fotg210->pclk))
-- clk_disable_unprepare(fotg210->pclk);
-
--err:
-+err_free:
- kfree(fotg210);
- return ret;
- }
---- a/drivers/usb/fotg210/fotg210-udc.h
-+++ b/drivers/usb/fotg210/fotg210-udc.h
-@@ -231,7 +231,6 @@ struct fotg210_ep {
- struct fotg210_udc {
- spinlock_t lock; /* protect the struct */
- void __iomem *reg;
-- struct clk *pclk;
-
- unsigned long irq_trigger;
-
---- a/drivers/usb/fotg210/fotg210.h
-+++ b/drivers/usb/fotg210/fotg210.h
-@@ -12,6 +12,7 @@ struct fotg210 {
- struct device *dev;
- struct resource *res;
- void __iomem *base;
-+ struct clk *pclk;
- struct regmap *map;
- enum gemini_port port;
- };
+++ /dev/null
-From b1b07abb598211de3ce7f52abdf8dcb24384341e Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 18 Jan 2023 08:09:19 +0100
-Subject: [PATCH 19/29] usb: fotg210: Check role register in core
-
-Read the role register and check that we are in host/peripheral
-mode and issue warnings if we're not in the right role when
-probing respective driver.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-5-100388af9810@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-core.c
-+++ b/drivers/usb/fotg210/fotg210-core.c
-@@ -18,6 +18,11 @@
-
- #include "fotg210.h"
-
-+/* Role Register 0x80 */
-+#define FOTG210_RR 0x80
-+#define FOTG210_RR_ID BIT(21) /* 1 = B-device, 0 = A-device */
-+#define FOTG210_RR_CROLE BIT(20) /* 1 = device, 0 = host */
-+
- /*
- * Gemini-specific initialization function, only executed on the
- * Gemini SoC using the global misc control register.
-@@ -95,6 +100,7 @@ static int fotg210_probe(struct platform
- struct device *dev = &pdev->dev;
- enum usb_dr_mode mode;
- struct fotg210 *fotg;
-+ u32 val;
- int ret;
-
- fotg = devm_kzalloc(dev, sizeof(*fotg), GFP_KERNEL);
-@@ -122,10 +128,16 @@ static int fotg210_probe(struct platform
- return ret;
- }
-
-- if (mode == USB_DR_MODE_PERIPHERAL)
-+ val = readl(fotg->base + FOTG210_RR);
-+ if (mode == USB_DR_MODE_PERIPHERAL) {
-+ if (!(val & FOTG210_RR_CROLE))
-+ dev_err(dev, "block not in device role\n");
- ret = fotg210_udc_probe(pdev, fotg);
-- else
-+ } else {
-+ if (val & FOTG210_RR_CROLE)
-+ dev_err(dev, "block not in host role\n");
- ret = fotg210_hcd_probe(pdev, fotg);
-+ }
-
- return ret;
- }
+++ /dev/null
-From d7c2b0b6da75b86cf5ddbcd51a74d74e19bbf178 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 18 Jan 2023 08:09:20 +0100
-Subject: [PATCH 20/29] usb: fotg210-udc: Assign of_node and speed on start
-
-Follow the example set by other drivers to assign of_node
-and speed to the driver when binding, also print bound
-info akin to other UDC drivers.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-6-100388af9810@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -1028,6 +1028,10 @@ static int fotg210_udc_start(struct usb_
-
- /* hook up the driver */
- fotg210->driver = driver;
-+ fotg210->gadget.dev.of_node = fotg210->dev->of_node;
-+ fotg210->gadget.speed = USB_SPEED_UNKNOWN;
-+
-+ dev_info(fotg210->dev, "bound driver %s\n", driver->driver.name);
-
- if (!IS_ERR_OR_NULL(fotg210->phy)) {
- ret = otg_set_peripheral(fotg210->phy->otg,
-@@ -1084,6 +1088,7 @@ static int fotg210_udc_stop(struct usb_g
-
- fotg210_init(fotg210);
- fotg210->driver = NULL;
-+ fotg210->gadget.speed = USB_SPEED_UNKNOWN;
-
- spin_unlock_irqrestore(&fotg210->lock, flags);
-
+++ /dev/null
-From 2fbbfb2c556944945639b17b13fcb1e05272b646 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 18 Jan 2023 08:09:21 +0100
-Subject: [PATCH 21/29] usb: fotg210-udc: Implement VBUS session
-
-Implement VBUS session handling for FOTG210. This is
-mainly used by the UDC driver which needs to call down to
-the FOTG210 core and enable/disable VBUS, as this needs to be
-handled outside of the HCD and UDC drivers, by platform
-specific glue code.
-
-The Gemini has a special bit in a system register to turn
-VBUS on and off so we implement this in the FOTG210 core.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230103-gemini-fotg210-usb-v2-7-100388af9810@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-core.c
-+++ b/drivers/usb/fotg210/fotg210-core.c
-@@ -95,6 +95,35 @@ static int fotg210_gemini_init(struct fo
- return 0;
- }
-
-+/**
-+ * fotg210_vbus() - Called by gadget driver to enable/disable VBUS
-+ * @enable: true to enable VBUS, false to disable VBUS
-+ */
-+void fotg210_vbus(struct fotg210 *fotg, bool enable)
-+{
-+ u32 mask;
-+ u32 val;
-+ int ret;
-+
-+ switch (fotg->port) {
-+ case GEMINI_PORT_0:
-+ mask = GEMINI_MISC_USB0_VBUS_ON;
-+ val = enable ? GEMINI_MISC_USB0_VBUS_ON : 0;
-+ break;
-+ case GEMINI_PORT_1:
-+ mask = GEMINI_MISC_USB1_VBUS_ON;
-+ val = enable ? GEMINI_MISC_USB1_VBUS_ON : 0;
-+ break;
-+ default:
-+ return;
-+ }
-+ ret = regmap_update_bits(fotg->map, GEMINI_GLOBAL_MISC_CTRL, mask, val);
-+ if (ret)
-+ dev_err(fotg->dev, "failed to %s VBUS\n",
-+ enable ? "enable" : "disable");
-+ dev_info(fotg->dev, "%s: %s VBUS\n", __func__, enable ? "enable" : "disable");
-+}
-+
- static int fotg210_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -1095,9 +1095,26 @@ static int fotg210_udc_stop(struct usb_g
- return 0;
- }
-
-+/**
-+ * fotg210_vbus_session - Called by external transceiver to enable/disable udc
-+ * @_gadget: usb gadget
-+ * @is_active: 0 if should disable UDC VBUS, 1 if should enable
-+ *
-+ * Returns 0
-+ */
-+static int fotg210_vbus_session(struct usb_gadget *g, int is_active)
-+{
-+ struct fotg210_udc *fotg210 = gadget_to_fotg210(g);
-+
-+ /* Call down to core integration layer to drive or disable VBUS */
-+ fotg210_vbus(fotg210->fotg, is_active);
-+ return 0;
-+}
-+
- static const struct usb_gadget_ops fotg210_gadget_ops = {
- .udc_start = fotg210_udc_start,
- .udc_stop = fotg210_udc_stop,
-+ .vbus_session = fotg210_vbus_session,
- };
-
- /**
---- a/drivers/usb/fotg210/fotg210.h
-+++ b/drivers/usb/fotg210/fotg210.h
-@@ -17,6 +17,8 @@ struct fotg210 {
- enum gemini_port port;
- };
-
-+void fotg210_vbus(struct fotg210 *fotg, bool enable);
-+
- #ifdef CONFIG_USB_FOTG210_HCD
- int fotg210_hcd_probe(struct platform_device *pdev, struct fotg210 *fotg);
- int fotg210_hcd_remove(struct platform_device *pdev);
+++ /dev/null
-From f011d1eab23f4c063c5441c0d5a22898adf9145c Mon Sep 17 00:00:00 2001
-From: Fabian Vogt <fabian@ritter-vogt.de>
-Date: Mon, 23 Jan 2023 08:35:07 +0100
-Subject: [PATCH 22/29] fotg210-udc: Introduce and use a fotg210_ack_int
- function
-
-This is in preparation of support for devices where interrupts are acked
-differently.
-
-Signed-off-by: Fabian Vogt <fabian@ritter-vogt.de>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230123073508.2350402-3-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -28,6 +28,14 @@ static const char udc_name[] = "fotg210_
- static const char * const fotg210_ep_name[] = {
- "ep0", "ep1", "ep2", "ep3", "ep4"};
-
-+static void fotg210_ack_int(struct fotg210_udc *fotg210, u32 offset, u32 mask)
-+{
-+ u32 value = ioread32(fotg210->reg + offset);
-+
-+ value &= ~mask;
-+ iowrite32(value, fotg210->reg + offset);
-+}
-+
- static void fotg210_disable_fifo_int(struct fotg210_ep *ep)
- {
- u32 value = ioread32(ep->fotg210->reg + FOTG210_DMISGR1);
-@@ -303,8 +311,7 @@ static void fotg210_wait_dma_done(struct
- goto dma_reset;
- } while (!(value & DISGR2_DMA_CMPLT));
-
-- value &= ~DISGR2_DMA_CMPLT;
-- iowrite32(value, ep->fotg210->reg + FOTG210_DISGR2);
-+ fotg210_ack_int(ep->fotg210, FOTG210_DISGR2, DISGR2_DMA_CMPLT);
- return;
-
- dma_reset:
-@@ -844,14 +851,6 @@ static void fotg210_ep0in(struct fotg210
- }
- }
-
--static void fotg210_clear_comabt_int(struct fotg210_udc *fotg210)
--{
-- u32 value = ioread32(fotg210->reg + FOTG210_DISGR0);
--
-- value &= ~DISGR0_CX_COMABT_INT;
-- iowrite32(value, fotg210->reg + FOTG210_DISGR0);
--}
--
- static void fotg210_in_fifo_handler(struct fotg210_ep *ep)
- {
- struct fotg210_request *req = list_entry(ep->queue.next,
-@@ -893,60 +892,43 @@ static irqreturn_t fotg210_irq(int irq,
- void __iomem *reg = fotg210->reg + FOTG210_DISGR2;
- u32 int_grp2 = ioread32(reg);
- u32 int_msk2 = ioread32(fotg210->reg + FOTG210_DMISGR2);
-- u32 value;
-
- int_grp2 &= ~int_msk2;
-
- if (int_grp2 & DISGR2_USBRST_INT) {
- usb_gadget_udc_reset(&fotg210->gadget,
- fotg210->driver);
-- value = ioread32(reg);
-- value &= ~DISGR2_USBRST_INT;
-- iowrite32(value, reg);
-+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_USBRST_INT);
- pr_info("fotg210 udc reset\n");
- }
- if (int_grp2 & DISGR2_SUSP_INT) {
-- value = ioread32(reg);
-- value &= ~DISGR2_SUSP_INT;
-- iowrite32(value, reg);
-+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_SUSP_INT);
- pr_info("fotg210 udc suspend\n");
- }
- if (int_grp2 & DISGR2_RESM_INT) {
-- value = ioread32(reg);
-- value &= ~DISGR2_RESM_INT;
-- iowrite32(value, reg);
-+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_RESM_INT);
- pr_info("fotg210 udc resume\n");
- }
- if (int_grp2 & DISGR2_ISO_SEQ_ERR_INT) {
-- value = ioread32(reg);
-- value &= ~DISGR2_ISO_SEQ_ERR_INT;
-- iowrite32(value, reg);
-+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_ISO_SEQ_ERR_INT);
- pr_info("fotg210 iso sequence error\n");
- }
- if (int_grp2 & DISGR2_ISO_SEQ_ABORT_INT) {
-- value = ioread32(reg);
-- value &= ~DISGR2_ISO_SEQ_ABORT_INT;
-- iowrite32(value, reg);
-+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_ISO_SEQ_ABORT_INT);
- pr_info("fotg210 iso sequence abort\n");
- }
- if (int_grp2 & DISGR2_TX0BYTE_INT) {
- fotg210_clear_tx0byte(fotg210);
-- value = ioread32(reg);
-- value &= ~DISGR2_TX0BYTE_INT;
-- iowrite32(value, reg);
-+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_TX0BYTE_INT);
- pr_info("fotg210 transferred 0 byte\n");
- }
- if (int_grp2 & DISGR2_RX0BYTE_INT) {
- fotg210_clear_rx0byte(fotg210);
-- value = ioread32(reg);
-- value &= ~DISGR2_RX0BYTE_INT;
-- iowrite32(value, reg);
-+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_RX0BYTE_INT);
- pr_info("fotg210 received 0 byte\n");
- }
- if (int_grp2 & DISGR2_DMA_ERROR) {
-- value = ioread32(reg);
-- value &= ~DISGR2_DMA_ERROR;
-- iowrite32(value, reg);
-+ fotg210_ack_int(fotg210, FOTG210_DISGR2, DISGR2_DMA_ERROR);
- }
- }
-
-@@ -960,7 +942,7 @@ static irqreturn_t fotg210_irq(int irq,
-
- /* the highest priority in this source register */
- if (int_grp0 & DISGR0_CX_COMABT_INT) {
-- fotg210_clear_comabt_int(fotg210);
-+ fotg210_ack_int(fotg210, FOTG210_DISGR0, DISGR0_CX_COMABT_INT);
- pr_info("fotg210 CX command abort\n");
- }
-
+++ /dev/null
-From 367747c7813cecf19b46ef7134691f903ab76dc9 Mon Sep 17 00:00:00 2001
-From: Fabian Vogt <fabian@ritter-vogt.de>
-Date: Mon, 23 Jan 2023 08:35:08 +0100
-Subject: [PATCH 23/29] fotg210-udc: Improve device initialization
-
-Reset the device explicitly to get into a known state and also set the chip
-enable bit. Additionally, mask interrupts which aren't handled.
-
-Signed-off-by: Fabian Vogt <fabian@ritter-vogt.de>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230123073508.2350402-4-linus.walleij@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-udc.c
-+++ b/drivers/usb/fotg210/fotg210-udc.c
-@@ -7,6 +7,7 @@
- * Author : Yuan-Hsin Chen <yhchen@faraday-tech.com>
- */
-
-+#include <linux/delay.h>
- #include <linux/dma-mapping.h>
- #include <linux/err.h>
- #include <linux/interrupt.h>
-@@ -1022,6 +1023,11 @@ static int fotg210_udc_start(struct usb_
- dev_err(fotg210->dev, "can't bind to phy\n");
- }
-
-+ /* chip enable */
-+ value = ioread32(fotg210->reg + FOTG210_DMCR);
-+ value |= DMCR_CHIP_EN;
-+ iowrite32(value, fotg210->reg + FOTG210_DMCR);
-+
- /* enable device global interrupt */
- value = ioread32(fotg210->reg + FOTG210_DMCR);
- value |= DMCR_GLINT_EN;
-@@ -1038,6 +1044,15 @@ static void fotg210_init(struct fotg210_
- iowrite32(GMIR_MHC_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
- fotg210->reg + FOTG210_GMIR);
-
-+ /* mask interrupts for groups other than 0-2 */
-+ iowrite32(~(DMIGR_MINT_G0 | DMIGR_MINT_G1 | DMIGR_MINT_G2),
-+ fotg210->reg + FOTG210_DMIGR);
-+
-+ /* udc software reset */
-+ iowrite32(DMCR_SFRST, fotg210->reg + FOTG210_DMCR);
-+ /* Better wait a bit, but without a datasheet, no idea how long. */
-+ usleep_range(100, 200);
-+
- /* disable device global interrupt */
- value = ioread32(fotg210->reg + FOTG210_DMCR);
- value &= ~DMCR_GLINT_EN;
---- a/drivers/usb/fotg210/fotg210-udc.h
-+++ b/drivers/usb/fotg210/fotg210-udc.h
-@@ -58,6 +58,8 @@
-
- /* Device Mask of Interrupt Group Register (0x130) */
- #define FOTG210_DMIGR 0x130
-+#define DMIGR_MINT_G2 (1 << 2)
-+#define DMIGR_MINT_G1 (1 << 1)
- #define DMIGR_MINT_G0 (1 << 0)
-
- /* Device Mask of Interrupt Source Group 0(0x134) */
+++ /dev/null
-From 482830a70408a5d30af264b3d6706f818c78b2b2 Mon Sep 17 00:00:00 2001
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Date: Fri, 20 Jan 2023 17:44:33 +0200
-Subject: [PATCH 24/29] usb: fotg210-hcd: use sysfs_emit() to instead of
- scnprintf()
-
-Follow the advice of the Documentation/filesystems/sysfs.rst and show()
-should only use sysfs_emit() or sysfs_emit_at() when formatting the
-value to be returned to user space.
-
-Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Link: https://lore.kernel.org/r/20230120154437.22025-1-andriy.shevchenko@linux.intel.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
---- a/drivers/usb/fotg210/fotg210-hcd.c
-+++ b/drivers/usb/fotg210/fotg210-hcd.c
-@@ -4686,14 +4686,11 @@ static ssize_t uframe_periodic_max_show(
- struct device_attribute *attr, char *buf)
- {
- struct fotg210_hcd *fotg210;
-- int n;
-
- fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
-- n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
-- return n;
-+ return sysfs_emit(buf, "%d\n", fotg210->uframe_periodic_max);
- }
-
--
- static ssize_t uframe_periodic_max_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
+++ /dev/null
-From 6b84aa39a063eec883d410a9893cec70fce56163 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 4 Dec 2022 20:02:28 +0100
-Subject: [PATCH 25/29] ARM: dts: gemini: Push down flash address/size cells
-
-The platforms not defining any OF partions complain like
-this:
-
-../arch/arm/boot/dts/gemini.dtsi:19.25-28.5: Warning
- (avoid_unnecessary_addr_size): /soc/flash@30000000: unnecessary
- #address-cells/#size-cells without "ranges" or child "reg" property
-
-Get rid of this by only defining the address-cells and
-size-cells where it is actually used by OF partitions.
-
-Link: https://lore.kernel.org/r/20221204190230.3345590-1-linus.walleij@linaro.org
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
---- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts
-+++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
-@@ -164,6 +164,8 @@
- compatible = "cortina,gemini-flash", "jedec-flash";
- status = "okay";
- reg = <0x30000000 0x00080000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-
- /*
- * This "RedBoot" is the Storlink derivative.
---- a/arch/arm/boot/dts/gemini-wbd111.dts
-+++ b/arch/arm/boot/dts/gemini-wbd111.dts
-@@ -86,6 +86,8 @@
- status = "okay";
- /* 8MB of flash */
- reg = <0x30000000 0x00800000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-
- partition@0 {
- label = "RedBoot";
---- a/arch/arm/boot/dts/gemini-wbd222.dts
-+++ b/arch/arm/boot/dts/gemini-wbd222.dts
-@@ -90,6 +90,8 @@
- status = "okay";
- /* 8MB of flash */
- reg = <0x30000000 0x00800000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-
- partition@0 {
- label = "RedBoot";
---- a/arch/arm/boot/dts/gemini.dtsi
-+++ b/arch/arm/boot/dts/gemini.dtsi
-@@ -22,8 +22,6 @@
- pinctrl-names = "default";
- pinctrl-0 = <&pflash_default_pins>;
- bank-width = <2>;
-- #address-cells = <1>;
-- #size-cells = <1>;
- status = "disabled";
- };
-
+++ /dev/null
-From 0e733f5af628210f372585e431504a7024e7b571 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 4 Dec 2022 20:02:29 +0100
-Subject: [PATCH 26/29] ARM: dts: gemini: wbd111: Use RedBoot partion parser
-
-This is clearly a RedBoot partitioned device with 0x20000
-sized erase blocks.
-
-Link: https://lore.kernel.org/r/20221204190230.3345590-2-linus.walleij@linaro.org
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
---- a/arch/arm/boot/dts/gemini-wbd111.dts
-+++ b/arch/arm/boot/dts/gemini-wbd111.dts
-@@ -86,36 +86,11 @@
- status = "okay";
- /* 8MB of flash */
- reg = <0x30000000 0x00800000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
-
-- partition@0 {
-- label = "RedBoot";
-- reg = <0x00000000 0x00020000>;
-- read-only;
-- };
-- partition@20000 {
-- label = "kernel";
-- reg = <0x00020000 0x00100000>;
-- };
-- partition@120000 {
-- label = "rootfs";
-- reg = <0x00120000 0x006a0000>;
-- };
-- partition@7c0000 {
-- label = "VCTL";
-- reg = <0x007c0000 0x00010000>;
-- read-only;
-- };
-- partition@7d0000 {
-- label = "cfg";
-- reg = <0x007d0000 0x00010000>;
-- read-only;
-- };
-- partition@7e0000 {
-- label = "FIS";
-- reg = <0x007e0000 0x00010000>;
-- read-only;
-+ partitions {
-+ compatible = "redboot-fis";
-+ /* Eraseblock at 0x7e0000 */
-+ fis-index-block = <0x3f>;
- };
- };
-
+++ /dev/null
-From 8558e2e1110a5daa4ac9e1c5b5c15e1651a8fb94 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Sun, 4 Dec 2022 20:02:30 +0100
-Subject: [PATCH 27/29] ARM: dts: gemini: wbd222: Use RedBoot partion parser
-
-This is clearly a RedBoot partitioned device with 0x20000
-sized erase blocks.
-
-Link: https://lore.kernel.org/r/20221204190230.3345590-3-linus.walleij@linaro.org
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
---- a/arch/arm/boot/dts/gemini-wbd222.dts
-+++ b/arch/arm/boot/dts/gemini-wbd222.dts
-@@ -90,36 +90,11 @@
- status = "okay";
- /* 8MB of flash */
- reg = <0x30000000 0x00800000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
-
-- partition@0 {
-- label = "RedBoot";
-- reg = <0x00000000 0x00020000>;
-- read-only;
-- };
-- partition@20000 {
-- label = "kernel";
-- reg = <0x00020000 0x00100000>;
-- };
-- partition@120000 {
-- label = "rootfs";
-- reg = <0x00120000 0x006a0000>;
-- };
-- partition@7c0000 {
-- label = "VCTL";
-- reg = <0x007c0000 0x00010000>;
-- read-only;
-- };
-- partition@7d0000 {
-- label = "cfg";
-- reg = <0x007d0000 0x00010000>;
-- read-only;
-- };
-- partition@7e0000 {
-- label = "FIS";
-- reg = <0x007e0000 0x00010000>;
-- read-only;
-+ partitions {
-+ compatible = "redboot-fis";
-+ /* Eraseblock at 0x7e0000 */
-+ fis-index-block = <0x3f>;
- };
- };
-
+++ /dev/null
-From d5c01ce4a1016507c69682894cf6b66301abca3d Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 23 Jan 2023 08:39:15 +0100
-Subject: [PATCH 28/29] ARM: dts: gemini: Fix USB block version
-
-The FOTG version in the Gemini is the FOTG200, fix this
-up.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230123073916.2350839-1-linus.walleij@linaro.org
----
---- a/arch/arm/boot/dts/gemini.dtsi
-+++ b/arch/arm/boot/dts/gemini.dtsi
-@@ -439,7 +439,7 @@
- };
-
- usb0: usb@68000000 {
-- compatible = "cortina,gemini-usb", "faraday,fotg210";
-+ compatible = "cortina,gemini-usb", "faraday,fotg200";
- reg = <0x68000000 0x1000>;
- interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&syscon GEMINI_RESET_USB0>;
-@@ -460,7 +460,7 @@
- };
-
- usb1: usb@69000000 {
-- compatible = "cortina,gemini-usb", "faraday,fotg210";
-+ compatible = "cortina,gemini-usb", "faraday,fotg200";
- reg = <0x69000000 0x1000>;
- interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&syscon GEMINI_RESET_USB1>;
+++ /dev/null
-From 296184694ae7a4e388603c95499e98d30b21cc09 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 23 Jan 2023 08:39:16 +0100
-Subject: [PATCH 29/29] ARM: dts: gemini: Enable DNS313 FOTG210 as periph
-
-Add the GPIO-based VBUS phy, and enable the FOTG210
-USB1 block for use as peripheral.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230123073916.2350839-2-linus.walleij@linaro.org
----
---- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts
-+++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
-@@ -80,6 +80,15 @@
- #cooling-cells = <2>;
- };
-
-+ /*
-+ * This is the type B USB connector on the device,
-+ * a GPIO-controlled USB VBUS detect
-+ */
-+ usb1_phy: phy {
-+ compatible = "gpio-usb-b-connector", "usb-b-connector";
-+ #phy-cells = <0>;
-+ vbus-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
-+ };
-
- /* Global Mixed-Mode Technology G751 mounted on GPIO I2C */
- i2c {
-@@ -302,5 +311,13 @@
- ide@63000000 {
- status = "okay";
- };
-+
-+ usb@69000000 {
-+ status = "okay";
-+ dr_mode = "peripheral";
-+ usb-phy = <&usb1_phy>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&usb_default_pins>;
-+ };
- };
- };
---- a/arch/arm/boot/dts/gemini.dtsi
-+++ b/arch/arm/boot/dts/gemini.dtsi
-@@ -455,6 +455,8 @@
- */
- pinctrl-names = "default";
- pinctrl-0 = <&usb_default_pins>;
-+ /* Default to host mode */
-+ dr_mode = "host";
- syscon = <&syscon>;
- status = "disabled";
- };
+++ /dev/null
-From 36ee838bf83c01cff7cb47c7b07be278d2950ac0 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 11 Mar 2019 15:44:29 +0100
-Subject: [PATCH 2/2] ARM: dts: Augment DIR-685 partition table for OpenWrt
-
-Rename the firmware partition so that the firmware MTD
-splitter will do its job, drop the rootfs arguments as
-the MTD splitter will set this up automatically.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
---- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts
-+++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts
-@@ -20,7 +20,7 @@
- };
-
- chosen {
-- bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait consoleblank=300";
-+ bootargs = "console=ttyS0,19200n8 consoleblank=300";
- stdout-path = "uart0:19200n8";
- };
-
-@@ -317,9 +317,9 @@
- * this is called "upgrade" on the vendor system.
- */
- partition@40000 {
-- label = "upgrade";
-+ compatible = "wrg";
-+ label = "firmware";
- reg = <0x00040000 0x01f40000>;
-- read-only;
- };
- /* RGDB, Residental Gateway Database? */
- partition@1f80000 {
--- /dev/null
+From f8001196455311eb128fcafd98cb2050a70218df Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Sat, 6 Jan 2024 01:12:22 +0100
+Subject: [PATCH 4/4] net: ethernet: cortina: Drop TSO support
+
+The recent change to allow large frames without hardware checksumming
+slotted in software checksumming in the driver if hardware could not
+do it.
+
+This will however upset TSO (TCP Segment Offloading). Typical
+error dumps includes this:
+
+skb len=2961 headroom=222 headlen=66 tailroom=0
+(...)
+WARNING: CPU: 0 PID: 956 at net/core/dev.c:3259 skb_warn_bad_offload+0x7c/0x108
+gemini-ethernet-port: caps=(0x0000010000154813, 0x00002007ffdd7889)
+
+And the packets do not go through.
+
+The TSO implementation is bogus: a TSO enabled driver must propagate
+the skb_shinfo(skb)->gso_size value to the TSO engine on the NIC.
+
+Drop the size check and TSO offloading features for now: this
+needs to be fixed up properly.
+
+After this ethernet works fine on Gemini devices with a direct connected
+PHY such as D-Link DNS-313.
+
+Also tested to still be working with a DSA switch using the Gemini
+ethernet as conduit interface.
+
+Link: https://lore.kernel.org/netdev/CANn89iJLfxng1sYL5Zk0mknXpyYQPCp83m3KgD2KJ2_hKCpEUg@mail.gmail.com/
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Fixes: d4d0c5b4d279 ("net: ethernet: cortina: Handle large frames")
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/cortina/gemini.c | 15 ++-------------
+ 1 file changed, 2 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/ethernet/cortina/gemini.c
++++ b/drivers/net/ethernet/cortina/gemini.c
+@@ -79,8 +79,7 @@ MODULE_PARM_DESC(debug, "Debug level (0=
+ #define GMAC0_IRQ4_8 (GMAC0_MIB_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT)
+
+ #define GMAC_OFFLOAD_FEATURES (NETIF_F_SG | NETIF_F_IP_CSUM | \
+- NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | \
+- NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)
++ NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM)
+
+ /**
+ * struct gmac_queue_page - page buffer per-page info
+@@ -1143,23 +1142,13 @@ static int gmac_map_tx_bufs(struct net_d
+ struct gmac_txdesc *txd;
+ skb_frag_t *skb_frag;
+ dma_addr_t mapping;
+- unsigned short mtu;
+ void *buffer;
+ int ret;
+
+- mtu = ETH_HLEN;
+- mtu += netdev->mtu;
+- if (skb->protocol == htons(ETH_P_8021Q))
+- mtu += VLAN_HLEN;
+-
++ /* TODO: implement proper TSO using MTU in word3 */
+ word1 = skb->len;
+ word3 = SOF_BIT;
+
+- if (word1 > mtu) {
+- word1 |= TSS_MTU_ENABLE_BIT;
+- word3 |= mtu;
+- }
+-
+ if (skb->len >= ETH_FRAME_LEN) {
+ /* Hardware offloaded checksumming isn't working on frames
+ * bigger than 1514 bytes. A hypothesis about this is that the
--- /dev/null
+From 091cde88b5ff2a2ca5739ce41f9cf5640a95222f Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Sun, 11 Feb 2024 22:24:25 +0100
+Subject: [PATCH] ARM: dts: gemini: Map reset keys to KEY_RESTART
+
+This maps the misc "reset", "setup" and "facory reset" keys to the
+only key a standard userspace is likely to understand: KEY_RESTART.
+On OpenWrt this will simply restart the system under controlled
+forms.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20240211-gemini-dts-v1-3-6c09adeb4c2e@linaro.org
+---
+ arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts | 4 ++--
+ arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts | 4 ++--
+ arch/arm/boot/dts/gemini/gemini-sl93512r.dts | 2 +-
+ arch/arm/boot/dts/gemini/gemini-sq201.dts | 2 +-
+ arch/arm/boot/dts/gemini/gemini-wbd111.dts | 4 ++--
+ arch/arm/boot/dts/gemini/gemini-wbd222.dts | 4 ++--
+ 6 files changed, 10 insertions(+), 10 deletions(-)
+
+--- a/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
++++ b/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
+@@ -27,10 +27,10 @@
+ gpio_keys {
+ compatible = "gpio-keys";
+
+- button-esc {
++ button-reset {
+ debounce-interval = <100>;
+ wakeup-source;
+- linux,code = <KEY_ESC>;
++ linux,code = <KEY_RESTART>;
+ label = "reset";
+ /* Collides with LPC_LAD[0], UART DCD, SSP 97RST */
+ gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+--- a/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts
++++ b/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts
+@@ -33,10 +33,10 @@
+ gpio_keys {
+ compatible = "gpio-keys";
+
+- button-esc {
++ button-reset {
+ debounce-interval = <100>;
+ wakeup-source;
+- linux,code = <KEY_ESC>;
++ linux,code = <KEY_RESTART>;
+ label = "reset";
+ gpios = <&gpio1 31 GPIO_ACTIVE_LOW>;
+ };
+--- a/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
++++ b/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
+@@ -43,7 +43,7 @@
+ button-setup {
+ debounce-interval = <50>;
+ wakeup-source;
+- linux,code = <KEY_SETUP>;
++ linux,code = <KEY_RESTART>;
+ label = "factory reset";
+ /* Conflict with NAND flash */
+ gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+--- a/arch/arm/boot/dts/gemini/gemini-sq201.dts
++++ b/arch/arm/boot/dts/gemini/gemini-sq201.dts
+@@ -30,7 +30,7 @@
+ button-setup {
+ debounce-interval = <100>;
+ wakeup-source;
+- linux,code = <KEY_SETUP>;
++ linux,code = <KEY_RESTART>;
+ label = "factory reset";
+ /* Conflict with NAND flash */
+ gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+--- a/arch/arm/boot/dts/gemini/gemini-wbd111.dts
++++ b/arch/arm/boot/dts/gemini/gemini-wbd111.dts
+@@ -28,10 +28,10 @@
+ gpio_keys {
+ compatible = "gpio-keys";
+
+- button-setup {
++ button-reset {
+ debounce-interval = <100>;
+ wakeup-source;
+- linux,code = <KEY_SETUP>;
++ linux,code = <KEY_RESTART>;
+ label = "reset";
+ /* Conflict with ICE */
+ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+--- a/arch/arm/boot/dts/gemini/gemini-wbd222.dts
++++ b/arch/arm/boot/dts/gemini/gemini-wbd222.dts
+@@ -27,10 +27,10 @@
+ gpio_keys {
+ compatible = "gpio-keys";
+
+- button-setup {
++ button-reset {
+ debounce-interval = <100>;
+ wakeup-source;
+- linux,code = <KEY_SETUP>;
++ linux,code = <KEY_RESTART>;
+ label = "reset";
+ /* Conflict with ICE */
+ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
--- /dev/null
+From c1aa34cd568bc7b86b82353034070c32b6ebe6db Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Mon, 11 Mar 2019 15:44:29 +0100
+Subject: [PATCH] ARM: dts: Augment DIR-685 partition table for OpenWrt
+
+Rename the firmware partition so that the firmware MTD
+splitter will do its job, drop the rootfs arguments as
+the MTD splitter will set this up automatically.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
++++ b/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
+@@ -20,7 +20,7 @@
+ };
+
+ chosen {
+- bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait consoleblank=300";
++ bootargs = "console=ttyS0,19200n8 consoleblank=300";
+ stdout-path = "uart0:19200n8";
+ };
+
+@@ -317,9 +317,9 @@
+ * this is called "upgrade" on the vendor system.
+ */
+ partition@40000 {
+- label = "upgrade";
++ compatible = "wrg";
++ label = "firmware";
+ reg = <0x00040000 0x01f40000>;
+- read-only;
+ };
+ /* RGDB, Residental Gateway Database? */
+ partition@1f80000 {
--- a/arch/Kconfig
+++ b/arch/Kconfig
-@@ -1299,6 +1299,14 @@ config ARCH_HAS_ELFCORE_COMPAT
+@@ -1307,6 +1307,14 @@ config ARCH_HAS_ELFCORE_COMPAT
config ARCH_HAS_PARANOID_L1D_FLUSH
bool
source "scripts/gcc-plugins/Kconfig"
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
-@@ -85,6 +85,7 @@ config X86
+@@ -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
--- a/kernel/bounds.c
+++ b/kernel/bounds.c
@@ -22,6 +22,11 @@ int main(void)
- DEFINE(NR_CPUS_BITS, bits_per(CONFIG_NR_CPUS));
+ DEFINE(NR_CPUS_BITS, order_base_2(CONFIG_NR_CPUS));
#endif
DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
+#ifdef CONFIG_LRU_GEN
list_del(&dst->list);
kfree(dst);
}
-@@ -805,7 +809,7 @@ static int dsa_switch_setup_tag_protocol
+@@ -827,7 +831,7 @@ static int dsa_switch_setup_tag_protocol
int port, err;
if (tag_ops->proto == dst->default_proto)
for (port = 0; port < ds->num_ports; port++) {
if (!dsa_is_cpu_port(ds, port))
-@@ -821,6 +825,17 @@ static int dsa_switch_setup_tag_protocol
+@@ -843,6 +847,17 @@ static int dsa_switch_setup_tag_protocol
}
}
return 0;
}
-@@ -1132,6 +1147,46 @@ static void dsa_tree_teardown(struct dsa
+@@ -1154,6 +1169,46 @@ static void dsa_tree_teardown(struct dsa
dst->setup = false;
}
/* 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).
-@@ -1164,12 +1219,15 @@ int dsa_tree_change_tag_proto(struct dsa
+@@ -1186,12 +1241,15 @@ int dsa_tree_change_tag_proto(struct dsa
goto out_unlock;
}
rtnl_unlock();
-@@ -1257,6 +1315,7 @@ static int dsa_port_parse_cpu(struct dsa
+@@ -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;
/* Find out which protocol the switch would prefer. */
default_proto = dsa_get_tag_protocol(dp, master);
-@@ -1311,6 +1370,12 @@ static int dsa_port_parse_cpu(struct dsa
+@@ -1333,6 +1392,12 @@ static int dsa_port_parse_cpu(struct dsa
*/
dsa_tag_driver_put(tag_ops);
} else {
list_del(&dst->list);
kfree(dst);
}
-@@ -826,17 +822,29 @@ static int dsa_switch_setup_tag_protocol
+@@ -848,17 +844,29 @@ static int dsa_switch_setup_tag_protocol
}
connect:
}
static int dsa_switch_setup(struct dsa_switch *ds)
-@@ -1156,13 +1164,6 @@ static int dsa_tree_bind_tag_proto(struc
+@@ -1178,13 +1186,6 @@ static int dsa_tree_bind_tag_proto(struc
dst->tag_ops = tag_ops;
/* Notify the switches from this tree about the connection
* to the new tagger
*/
-@@ -1172,16 +1173,14 @@ static int dsa_tree_bind_tag_proto(struc
+@@ -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 */
dst->tag_ops = old_tag_ops;
return err;
-@@ -1315,7 +1314,6 @@ static int dsa_port_parse_cpu(struct dsa
+@@ -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;
/* Find out which protocol the switch would prefer. */
default_proto = dsa_get_tag_protocol(dp, master);
-@@ -1370,12 +1368,6 @@ static int dsa_port_parse_cpu(struct dsa
+@@ -1392,12 +1390,6 @@ static int dsa_port_parse_cpu(struct dsa
*/
dsa_tag_driver_put(tag_ops);
} else {
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 7 Feb 2022 10:27:22 +0100
-Subject: [PATCH] arm64: dts: mediatek: mt7622: add support for coherent
- DMA
-
-It improves performance by eliminating the need for a cache flush on rx and tx
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -357,7 +357,7 @@
- };
-
- cci_control2: slave-if@5000 {
-- compatible = "arm,cci-400-ctrl-if";
-+ compatible = "arm,cci-400-ctrl-if", "syscon";
- interface-type = "ace";
- reg = <0x5000 0x1000>;
- };
-@@ -938,6 +938,8 @@
- power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
- mediatek,ethsys = <ðsys>;
- mediatek,sgmiisys = <&sgmiisys>;
-+ mediatek,cci-control = <&cci_control2>;
-+ dma-coherent;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 5 Feb 2022 18:36:36 +0100
-Subject: [PATCH] arm64: dts: mediatek: mt7622: introduce nodes for
- Wireless Ethernet Dispatch
-
-Introduce wed0 and wed1 nodes in order to enable offloading forwarding
-between ethernet and wireless devices on the mt7622 chipset.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -894,6 +894,11 @@
- };
- };
-
-+ hifsys: syscon@1af00000 {
-+ compatible = "mediatek,mt7622-hifsys", "syscon";
-+ reg = <0 0x1af00000 0 0x70>;
-+ };
-+
- ethsys: syscon@1b000000 {
- compatible = "mediatek,mt7622-ethsys",
- "syscon";
-@@ -912,6 +917,26 @@
- #dma-cells = <1>;
- };
-
-+ pcie_mirror: pcie-mirror@10000400 {
-+ compatible = "mediatek,mt7622-pcie-mirror",
-+ "syscon";
-+ reg = <0 0x10000400 0 0x10>;
-+ };
-+
-+ wed0: wed@1020a000 {
-+ compatible = "mediatek,mt7622-wed",
-+ "syscon";
-+ reg = <0 0x1020a000 0 0x1000>;
-+ interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_LOW>;
-+ };
-+
-+ wed1: wed@1020b000 {
-+ compatible = "mediatek,mt7622-wed",
-+ "syscon";
-+ reg = <0 0x1020b000 0 0x1000>;
-+ interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_LOW>;
-+ };
-+
- eth: ethernet@1b100000 {
- compatible = "mediatek,mt7622-eth",
- "mediatek,mt2701-eth",
-@@ -939,6 +964,9 @@
- mediatek,ethsys = <ðsys>;
- mediatek,sgmiisys = <&sgmiisys>;
- mediatek,cci-control = <&cci_control2>;
-+ mediatek,wed = <&wed0>, <&wed1>;
-+ mediatek,pcie-mirror = <&pcie_mirror>;
-+ mediatek,hifsys = <&hifsys>;
- dma-coherent;
- #address-cells = <1>;
- #size-cells = <0>;
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -963,7 +963,7 @@
+@@ -957,7 +957,7 @@
power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
mediatek,ethsys = <ðsys>;
mediatek,sgmiisys = <&sgmiisys>;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -1243,27 +1243,31 @@ static int
+@@ -1425,27 +1425,31 @@ static int
mt7530_port_bridge_join(struct dsa_switch *ds, int port,
struct net_device *bridge)
{
}
/* Add the all other ports to this port matrix. */
-@@ -1368,24 +1372,28 @@ static void
+@@ -1550,24 +1554,28 @@ static void
mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
struct net_device *bridge)
{
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2499,6 +2499,32 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -2687,6 +2687,32 @@ mt7531_setup(struct dsa_switch *ds)
return 0;
}
static bool
mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
const struct phylink_link_state *state)
-@@ -2535,6 +2561,37 @@ static bool mt7531_is_rgmii_port(struct
+@@ -2723,6 +2749,37 @@ static bool mt7531_is_rgmii_port(struct
return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
}
static bool
mt7531_phy_mode_supported(struct dsa_switch *ds, int port,
const struct phylink_link_state *state)
-@@ -3011,6 +3068,18 @@ mt7531_cpu_port_config(struct dsa_switch
+@@ -3199,6 +3256,18 @@ mt7531_cpu_port_config(struct dsa_switch
return 0;
}
static void
mt7530_mac_port_validate(struct dsa_switch *ds, int port,
unsigned long *supported)
-@@ -3246,6 +3315,7 @@ static const struct dsa_switch_ops mt753
+@@ -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_validate = mt753x_phylink_validate,
.phylink_mac_link_state = mt753x_phylink_mac_link_state,
.phylink_mac_config = mt753x_phylink_mac_config,
-@@ -3263,6 +3333,7 @@ static const struct mt753x_info mt753x_t
+@@ -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,
.phy_mode_supported = mt7530_phy_mode_supported,
.mac_port_validate = mt7530_mac_port_validate,
.mac_port_get_state = mt7530_phylink_mac_link_state,
-@@ -3274,6 +3345,7 @@ static const struct mt753x_info mt753x_t
+@@ -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,
.phy_mode_supported = mt7530_phy_mode_supported,
.mac_port_validate = mt7530_mac_port_validate,
.mac_port_get_state = mt7530_phylink_mac_link_state,
-@@ -3286,6 +3358,7 @@ static const struct mt753x_info mt753x_t
+@@ -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,
.phy_mode_supported = mt7531_phy_mode_supported,
.mac_port_validate = mt7531_mac_port_validate,
.mac_port_get_state = mt7531_phylink_mac_link_state,
-@@ -3348,6 +3421,7 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -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_state || !priv->info->mac_port_config)
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -796,6 +796,8 @@ struct mt753x_info {
+@@ -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);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2525,37 +2525,6 @@ static void mt7530_mac_port_get_caps(str
+@@ -2713,37 +2713,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);
-@@ -2592,44 +2561,6 @@ static void mt7531_mac_port_get_caps(str
+@@ -2780,44 +2749,6 @@ static void mt7531_mac_port_get_caps(str
}
}
static int
mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
{
-@@ -2884,9 +2815,6 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -3072,9 +3003,6 @@ mt753x_phylink_mac_config(struct dsa_swi
struct mt7530_priv *priv = ds->priv;
u32 mcr_cur, mcr_new;
switch (port) {
case 0 ... 4: /* Internal phy */
if (state->interface != PHY_INTERFACE_MODE_GMII)
-@@ -3102,12 +3030,6 @@ mt753x_phylink_validate(struct dsa_switc
+@@ -3290,12 +3218,6 @@ mt753x_phylink_validate(struct dsa_switc
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
struct mt7530_priv *priv = ds->priv;
phylink_set_port_modes(mask);
if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
-@@ -3334,7 +3256,6 @@ static const struct mt753x_info mt753x_t
+@@ -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,
.mac_port_validate = mt7530_mac_port_validate,
.mac_port_get_state = mt7530_phylink_mac_link_state,
.mac_port_config = mt7530_mac_config,
-@@ -3346,7 +3267,6 @@ static const struct mt753x_info mt753x_t
+@@ -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,
.mac_port_validate = mt7530_mac_port_validate,
.mac_port_get_state = mt7530_phylink_mac_link_state,
.mac_port_config = mt7530_mac_config,
-@@ -3359,7 +3279,6 @@ static const struct mt753x_info mt753x_t
+@@ -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,
.mac_port_validate = mt7531_mac_port_validate,
.mac_port_get_state = mt7531_phylink_mac_link_state,
.mac_port_config = mt7531_mac_config,
-@@ -3422,7 +3341,6 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -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 ||
return -EINVAL;
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -798,8 +798,6 @@ struct mt753x_info {
+@@ -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);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3054,11 +3054,6 @@ mt753x_phylink_validate(struct dsa_switc
+@@ -3242,11 +3242,6 @@ mt753x_phylink_validate(struct dsa_switc
linkmode_and(supported, supported, mask);
linkmode_and(state->advertising, state->advertising, mask);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2632,12 +2632,13 @@ static int mt7531_rgmii_setup(struct mt7
+@@ -2820,12 +2820,13 @@ static int mt7531_rgmii_setup(struct mt7
}
static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port,
phylink_set(supported, 2500baseX_Full);
phylink_set(supported, 2500baseT_Full);
}
-@@ -3010,16 +3011,18 @@ static void mt753x_phylink_get_caps(stru
+@@ -3198,16 +3199,18 @@ static void mt753x_phylink_get_caps(stru
static void
mt7530_mac_port_validate(struct dsa_switch *ds, int port,
}
static void
-@@ -3042,12 +3045,13 @@ mt753x_phylink_validate(struct dsa_switc
+@@ -3230,12 +3233,13 @@ mt753x_phylink_validate(struct dsa_switc
}
/* This switch only supports 1G full-duplex. */
phylink_set(mask, Asym_Pause);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -799,6 +799,7 @@ struct mt753x_info {
+@@ -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,
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2631,19 +2631,6 @@ static int mt7531_rgmii_setup(struct mt7
+@@ -2819,19 +2819,6 @@ 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,
-@@ -3010,51 +2997,21 @@ static void mt753x_phylink_get_caps(stru
+@@ -3198,51 +3185,21 @@ static void mt753x_phylink_get_caps(stru
}
static void
linkmode_and(supported, supported, mask);
linkmode_and(state->advertising, state->advertising, mask);
-@@ -3255,7 +3212,6 @@ static const struct mt753x_info mt753x_t
+@@ -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_get_state = mt7530_phylink_mac_link_state,
.mac_port_config = mt7530_mac_config,
},
-@@ -3266,7 +3222,6 @@ static const struct mt753x_info mt753x_t
+@@ -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_get_state = mt7530_phylink_mac_link_state,
.mac_port_config = mt7530_mac_config,
},
-@@ -3278,7 +3233,6 @@ static const struct mt753x_info mt753x_t
+@@ -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_get_state = mt7531_phylink_mac_link_state,
.mac_port_config = mt7531_mac_config,
.mac_pcs_an_restart = mt7531_sgmii_restart_an,
-@@ -3340,7 +3294,6 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -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 ||
/* 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"),
-@@ -2631,12 +2636,11 @@ static int mt7531_rgmii_setup(struct mt7
+@@ -2819,12 +2824,11 @@ static int mt7531_rgmii_setup(struct mt7
return 0;
}
unsigned int val;
/* For adjusting speed and duplex of SGMII force mode. */
-@@ -2662,6 +2666,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw
+@@ -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.
*/
if ((speed == SPEED_10 || speed == SPEED_100) &&
duplex != DUPLEX_FULL)
-@@ -2737,9 +2744,10 @@ static int mt7531_sgmii_setup_mode_an(st
+@@ -2925,9 +2932,10 @@ static int mt7531_sgmii_setup_mode_an(st
return 0;
}
u32 val;
/* Only restart AN when AN is enabled */
-@@ -2796,6 +2804,24 @@ mt753x_mac_config(struct dsa_switch *ds,
+@@ -2984,6 +2992,24 @@ mt753x_mac_config(struct dsa_switch *ds,
return priv->info->mac_port_config(ds, port, mode, state->interface);
}
static void
mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
const struct phylink_link_state *state)
-@@ -2857,17 +2883,6 @@ unsupported:
+@@ -3045,17 +3071,6 @@ unsupported:
mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
}
static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
unsigned int mode,
phy_interface_t interface)
-@@ -2877,16 +2892,13 @@ static void mt753x_phylink_mac_link_down
+@@ -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_phylink_mac_link_up(struct dsa_switch *ds, int port,
-@@ -2899,8 +2911,6 @@ static void mt753x_phylink_mac_link_up(s
+@@ -3087,8 +3099,6 @@ static void mt753x_phylink_mac_link_up(s
struct mt7530_priv *priv = ds->priv;
u32 mcr;
mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
/* MT753x MAC works in 1G full duplex mode for all up-clocked
-@@ -2978,6 +2988,8 @@ mt7531_cpu_port_config(struct dsa_switch
+@@ -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_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
speed, DUPLEX_FULL, true, true);
-@@ -3017,16 +3029,13 @@ mt753x_phylink_validate(struct dsa_switc
+@@ -3205,16 +3217,13 @@ mt753x_phylink_validate(struct dsa_switc
linkmode_and(state->advertising, state->advertising, mask);
}
pmsr = mt7530_read(priv, MT7530_PMSR_P(port));
state->link = (pmsr & PMSR_LINK);
-@@ -3053,8 +3062,6 @@ mt7530_phylink_mac_link_state(struct dsa
+@@ -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;
}
static int
-@@ -3096,32 +3103,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
+@@ -3284,32 +3291,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
return 0;
}
if (ret)
return ret;
-@@ -3134,6 +3158,13 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3322,6 +3346,13 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
return ret;
}
-@@ -3195,9 +3226,8 @@ static const struct dsa_switch_ops mt753
+@@ -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_down = mt753x_phylink_mac_link_down,
.phylink_mac_link_up = mt753x_phylink_mac_link_up,
.get_mac_eee = mt753x_get_mac_eee,
-@@ -3207,36 +3237,34 @@ static const struct dsa_switch_ops mt753
+@@ -3396,36 +3426,34 @@ static const struct dsa_switch_ops mt753
static const struct mt753x_info mt753x_table[] = {
[ID_MT7621] = {
.id = ID_MT7621,
},
};
-@@ -3294,7 +3322,7 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -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->id = priv->info->id;
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -768,6 +768,12 @@ static const char *p5_intf_modes(unsigne
+@@ -779,6 +779,12 @@ static const char *p5_intf_modes(unsigne
struct mt7530_priv;
/* 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
-@@ -779,18 +785,14 @@ struct mt7530_priv;
+@@ -790,18 +796,14 @@ struct mt7530_priv;
* port
* @mac_port_validate: Holding the way to set addition validate type for a
* certan MAC port
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);
-@@ -801,15 +803,9 @@ struct mt753x_info {
+@@ -812,15 +814,9 @@ struct mt753x_info {
void (*mac_port_validate)(struct dsa_switch *ds, int port,
phy_interface_t interface,
unsigned long *supported);
};
/* struct mt7530_priv - This is the main data structure for holding the state
-@@ -851,6 +847,7 @@ struct mt7530_priv {
+@@ -862,6 +858,7 @@ struct mt7530_priv {
u8 mirror_tx;
struct mt7530_port ports[MT7530_NUM_PORTS];
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3008,25 +3008,16 @@ static void mt753x_phylink_get_caps(stru
+@@ -3196,25 +3196,16 @@ static void mt753x_phylink_get_caps(stru
priv->info->mac_port_get_caps(ds, port, config);
}
}
static void mt7530_pcs_get_state(struct phylink_pcs *pcs,
-@@ -3128,12 +3119,14 @@ static void mt7530_pcs_an_restart(struct
+@@ -3316,12 +3307,14 @@ static void mt7530_pcs_an_restart(struct
}
static const struct phylink_pcs_ops mt7530_pcs_ops = {
.pcs_get_state = mt7531_pcs_get_state,
.pcs_config = mt753x_pcs_config,
.pcs_an_restart = mt7531_pcs_an_restart,
-@@ -3225,7 +3218,6 @@ static const struct dsa_switch_ops mt753
+@@ -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,
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3005,6 +3005,12 @@ static void mt753x_phylink_get_caps(stru
+@@ -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;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3143,9 +3143,16 @@ static int
+@@ -3331,9 +3331,16 @@ static int
mt753x_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
if (ret)
return ret;
-@@ -3157,13 +3164,6 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3345,13 +3352,6 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -1589,11 +1589,11 @@ static void
+@@ -1771,11 +1771,11 @@ static void
mt7530_hw_vlan_add(struct mt7530_priv *priv,
struct mt7530_hw_vlan_entry *entry)
{
/* Validate the entry with independent learning, create egress tag per
* VLAN and joining the port as one of the port members.
-@@ -1604,22 +1604,20 @@ mt7530_hw_vlan_add(struct mt7530_priv *p
+@@ -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.
}
static void
-@@ -1638,11 +1636,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *p
+@@ -1820,11 +1818,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *p
return;
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -1093,6 +1093,7 @@ static int
+@@ -1275,6 +1275,7 @@ static int
mt7530_port_enable(struct dsa_switch *ds, int port,
struct phy_device *phy)
{
struct mt7530_priv *priv = ds->priv;
mutex_lock(&priv->reg_mutex);
-@@ -1101,7 +1102,11 @@ mt7530_port_enable(struct dsa_switch *ds
+@@ -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].enable = true;
mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
priv->ports[port].pm);
-@@ -1249,7 +1254,8 @@ mt7530_port_bridge_join(struct dsa_switc
+@@ -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;
struct mt7530_priv *priv = ds->priv;
mutex_lock(&priv->reg_mutex);
-@@ -1326,9 +1332,12 @@ mt7530_port_set_vlan_unaware(struct dsa_
+@@ -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) {
| PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
}
}
-@@ -1378,6 +1387,7 @@ mt7530_port_bridge_leave(struct dsa_swit
+@@ -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 mt7530_priv *priv = ds->priv;
mutex_lock(&priv->reg_mutex);
-@@ -1406,8 +1416,8 @@ mt7530_port_bridge_leave(struct dsa_swit
+@@ -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,
/* 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
-@@ -1570,6 +1580,9 @@ static int
+@@ -1752,6 +1762,9 @@ static int
mt7530_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
struct netlink_ext_ack *extack)
{
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
-@@ -1577,7 +1590,7 @@ mt7530_port_vlan_filtering(struct dsa_sw
+@@ -1759,7 +1772,7 @@ mt7530_port_vlan_filtering(struct dsa_sw
* for becoming a VLAN-aware port.
*/
mt7530_port_set_vlan_aware(ds, port);
+++ /dev/null
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Thu, 11 Apr 2024 13:28:59 +0200
-Subject: [PATCH] netfilter: flowtable: validate pppoe header
-
-Ensure there is sufficient room to access the protocol field of the
-PPPoe header. Validate it once before the flowtable lookup, then use a
-helper function to access protocol field.
-
-Reported-by: syzbot+b6f07e1c07ef40199081@syzkaller.appspotmail.com
-Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
-
---- a/include/net/netfilter/nf_flow_table.h
-+++ b/include/net/netfilter/nf_flow_table.h
-@@ -318,7 +318,7 @@ int nf_flow_rule_route_ipv6(struct net *
- int nf_flow_table_offload_init(void);
- void nf_flow_table_offload_exit(void);
-
--static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
-+static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb)
- {
- __be16 proto;
-
-@@ -334,4 +334,14 @@ static inline __be16 nf_flow_pppoe_proto
- return 0;
- }
-
-+static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto)
-+{
-+ if (!pskb_may_pull(skb, PPPOE_SES_HLEN))
-+ return false;
-+
-+ *inner_proto = __nf_flow_pppoe_proto(skb);
-+
-+ return true;
-+}
-+
- #endif /* _NF_FLOW_TABLE_H */
---- a/net/netfilter/nf_flow_table_inet.c
-+++ b/net/netfilter/nf_flow_table_inet.c
-@@ -21,7 +21,8 @@ nf_flow_offload_inet_hook(void *priv, st
- proto = veth->h_vlan_encapsulated_proto;
- break;
- case htons(ETH_P_PPP_SES):
-- proto = nf_flow_pppoe_proto(skb);
-+ if (!nf_flow_pppoe_proto(skb, &proto))
-+ return NF_ACCEPT;
- break;
- default:
- proto = skb->protocol;
---- a/net/netfilter/nf_flow_table_ip.c
-+++ b/net/netfilter/nf_flow_table_ip.c
-@@ -246,10 +246,11 @@ static unsigned int nf_flow_xmit_xfrm(st
- return NF_STOLEN;
- }
-
--static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
-+static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto,
- u32 *offset)
- {
- struct vlan_ethhdr *veth;
-+ __be16 inner_proto;
-
- switch (skb->protocol) {
- case htons(ETH_P_8021Q):
-@@ -260,7 +261,8 @@ static bool nf_flow_skb_encap_protocol(c
- }
- break;
- case htons(ETH_P_PPP_SES):
-- if (nf_flow_pppoe_proto(skb) == proto) {
-+ if (nf_flow_pppoe_proto(skb, &inner_proto) &&
-+ inner_proto == proto) {
- *offset += PPPOE_SES_HLEN;
- return true;
- }
-@@ -289,7 +291,7 @@ static void nf_flow_encap_pop(struct sk_
- skb_reset_network_header(skb);
- break;
- case htons(ETH_P_PPP_SES):
-- skb->protocol = nf_flow_pppoe_proto(skb);
-+ skb->protocol = __nf_flow_pppoe_proto(skb);
- skb_pull(skb, PPPOE_SES_HLEN);
- skb_reset_network_header(skb);
- break;
+++ /dev/null
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Thu, 11 Apr 2024 13:29:00 +0200
-Subject: [PATCH] netfilter: flowtable: incorrect pppoe tuple
-
-pppoe traffic reaching ingress path does not match the flowtable entry
-because the pppoe header is expected to be at the network header offset.
-This bug causes a mismatch in the flow table lookup, so pppoe packets
-enter the classical forwarding path.
-
-Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
-
---- a/net/netfilter/nf_flow_table_ip.c
-+++ b/net/netfilter/nf_flow_table_ip.c
-@@ -156,7 +156,7 @@ static void nf_flow_tuple_encap(struct s
- tuple->encap[i].proto = skb->protocol;
- break;
- case htons(ETH_P_PPP_SES):
-- phdr = (struct pppoe_hdr *)skb_mac_header(skb);
-+ phdr = (struct pppoe_hdr *)skb_network_header(skb);
- tuple->encap[i].id = ntohs(phdr->sid);
- tuple->encap[i].proto = skb->protocol;
- break;
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
-@@ -1034,6 +1034,8 @@ static int dsa_tree_setup_master(struct
+@@ -1056,6 +1056,8 @@ static int dsa_tree_setup_master(struct
struct dsa_port *dp;
int err;
list_for_each_entry(dp, &dst->ports, list) {
if (dsa_port_is_cpu(dp)) {
err = dsa_master_setup(dp->master, dp);
-@@ -1042,6 +1044,8 @@ static int dsa_tree_setup_master(struct
+@@ -1064,6 +1066,8 @@ static int dsa_tree_setup_master(struct
}
}
return 0;
}
-@@ -1049,9 +1053,13 @@ static void dsa_tree_teardown_master(str
+@@ -1071,9 +1075,13 @@ static void dsa_tree_teardown_master(str
{
struct dsa_port *dp;
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
-@@ -999,23 +999,28 @@ static void dsa_tree_teardown_switches(s
+@@ -1021,23 +1021,28 @@ static void dsa_tree_teardown_switches(s
dsa_switch_teardown(dp->ds);
}
}
}
-@@ -1024,7 +1029,21 @@ static int dsa_tree_setup_switches(struc
+@@ -1046,7 +1051,21 @@ static int dsa_tree_setup_switches(struc
teardown:
dsa_tree_teardown_ports(dst);
return err;
}
-@@ -1111,10 +1130,14 @@ static int dsa_tree_setup(struct dsa_swi
+@@ -1133,10 +1152,14 @@ static int dsa_tree_setup(struct dsa_swi
if (err)
goto teardown_cpu_ports;
err = dsa_tree_setup_lags(dst);
if (err)
goto teardown_master;
-@@ -1127,8 +1150,9 @@ static int dsa_tree_setup(struct dsa_swi
+@@ -1149,8 +1172,9 @@ static int dsa_tree_setup(struct dsa_swi
teardown_master:
dsa_tree_teardown_master(dst);
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
-@@ -545,6 +545,7 @@ static void dsa_port_teardown(struct dsa
+@@ -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;
if (!dp->setup)
return;
-@@ -566,9 +567,11 @@ static void dsa_port_teardown(struct dsa
+@@ -588,9 +589,11 @@ static void dsa_port_teardown(struct dsa
dsa_port_link_unregister_of(dp);
break;
case DSA_PORT_TYPE_USER:
}
break;
}
-@@ -1130,17 +1133,17 @@ static int dsa_tree_setup(struct dsa_swi
+@@ -1152,17 +1155,17 @@ static int dsa_tree_setup(struct dsa_swi
if (err)
goto teardown_cpu_ports;
dst->setup = true;
-@@ -1148,10 +1151,10 @@ static int dsa_tree_setup(struct dsa_swi
+@@ -1170,10 +1173,10 @@ static int dsa_tree_setup(struct dsa_swi
return 0;
teardown_switches:
dsa_tree_teardown_switches(dst);
teardown_cpu_ports:
-@@ -1169,10 +1172,10 @@ static void dsa_tree_teardown(struct dsa
+@@ -1191,10 +1194,10 @@ static void dsa_tree_teardown(struct dsa
dsa_tree_teardown_lags(dst);
static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p)
{
return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED;
-@@ -949,6 +959,13 @@ struct dsa_switch_ops {
+@@ -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);
#define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
-@@ -1275,6 +1275,52 @@ out_unlock:
+@@ -1297,6 +1297,52 @@ out_unlock:
return err;
}
#include "dsa_priv.h"
-@@ -1060,9 +1061,18 @@ static int dsa_tree_setup_master(struct
+@@ -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)) {
}
}
-@@ -1077,9 +1087,19 @@ static void dsa_tree_teardown_master(str
+@@ -1099,9 +1109,19 @@ static void dsa_tree_teardown_master(str
rtnl_lock();
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2791,9 +2791,6 @@ mt7531_mac_config(struct dsa_switch *ds,
+@@ -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:
return mt7531_sgmii_setup_mode_force(priv, port, interface);
default:
return -EINVAL;
-@@ -2869,13 +2866,6 @@ unsupported:
+@@ -3057,13 +3054,6 @@ unsupported:
return;
}
mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
mcr_new = mcr_cur;
mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
-@@ -3012,6 +3002,9 @@ static void mt753x_phylink_get_caps(stru
+@@ -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;
/* 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.
-@@ -3077,6 +3070,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
+@@ -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);
if (state->interface == PHY_INTERFACE_MODE_SGMII &&
(status & MT7531_SGMII_AN_ENABLE)) {
val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
-@@ -3107,16 +3101,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
+@@ -3295,16 +3289,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
return 0;
}
}
static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -3157,6 +3179,8 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -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;
ret = priv->info->sw_setup(ds);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -400,6 +400,7 @@ enum mt7530_vlan_port_acc_frm {
+@@ -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)
#include <linux/phylink.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
-@@ -2643,128 +2644,11 @@ static int mt7531_rgmii_setup(struct mt7
+@@ -2831,128 +2832,11 @@ static int mt7531_rgmii_setup(struct mt7
return 0;
}
static int
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
-@@ -2787,11 +2671,11 @@ mt7531_mac_config(struct dsa_switch *ds,
+@@ -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:
default:
return -EINVAL;
}
-@@ -2816,11 +2700,11 @@ mt753x_phylink_mac_select_pcs(struct dsa
+@@ -3004,11 +2888,11 @@ mt753x_phylink_mac_select_pcs(struct dsa
switch (interface) {
case PHY_INTERFACE_MODE_TRGMII:
default:
return NULL;
}
-@@ -3061,86 +2945,6 @@ static void mt7530_pcs_get_state(struct
+@@ -3249,86 +3133,6 @@ static void mt7530_pcs_get_state(struct
state->pause |= MLO_PAUSE_TX;
}
static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
phy_interface_t interface,
const unsigned long *advertising,
-@@ -3160,18 +2964,57 @@ static const struct phylink_pcs_ops mt75
+@@ -3348,18 +3152,57 @@ static const struct phylink_pcs_ops mt75
.pcs_an_restart = mt7530_pcs_an_restart,
};
int i, ret;
/* Initialise the PCS devices */
-@@ -3179,8 +3022,6 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -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;
}
ret = priv->info->sw_setup(ds);
-@@ -3195,6 +3036,16 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3383,6 +3224,16 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
return ret;
}
-@@ -3286,7 +3137,7 @@ static const struct mt753x_info mt753x_t
+@@ -3475,7 +3326,7 @@ static const struct mt753x_info mt753x_t
},
[ID_MT7531] = {
.id = ID_MT7531,
.sw_setup = mt7531_setup,
.phy_read = mt7531_ind_phy_read,
.phy_write = mt7531_ind_phy_write,
-@@ -3394,7 +3245,7 @@ static void
+@@ -3583,7 +3434,7 @@ static void
mt7530_remove(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
if (!priv)
return;
-@@ -3413,6 +3264,10 @@ mt7530_remove(struct mdio_device *mdiode
+@@ -3602,6 +3453,10 @@ mt7530_remove(struct mdio_device *mdiode
mt7530_free_irq(priv);
dsa_unregister_switch(priv->ds);
dev_set_drvdata(&mdiodev->dev, NULL);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -391,47 +391,8 @@ enum mt7530_vlan_port_acc_frm {
+@@ -401,47 +401,8 @@ enum mt7530_vlan_port_acc_frm {
CCR_TX_OCT_CNT_BAD)
/* MT7531 SGMII register group */
/* Register for system reset */
#define MT7530_SYS_CTRL 0x7000
-@@ -730,13 +691,13 @@ struct mt7530_fdb {
+@@ -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.
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2996,26 +2996,56 @@ static const struct regmap_bus mt7531_re
+@@ -3184,26 +3184,56 @@ static const struct regmap_bus mt7531_re
.reg_update_bits = mt7530_regmap_update_bits,
};
int i, ret;
/* Initialise the PCS devices */
-@@ -3037,15 +3067,11 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3225,15 +3255,11 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2969,7 +2969,7 @@ static int mt7530_regmap_read(void *cont
+@@ -3157,7 +3157,7 @@ static int mt7530_regmap_read(void *cont
{
struct mt7530_priv *priv = context;
return 0;
};
-@@ -2977,23 +2977,25 @@ static int mt7530_regmap_write(void *con
+@@ -3165,23 +3165,25 @@ static int mt7530_regmap_write(void *con
{
struct mt7530_priv *priv = context;
};
static int
-@@ -3019,6 +3021,9 @@ mt7531_create_sgmii(struct mt7530_priv *
+@@ -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;
}
static void
-@@ -2965,22 +2986,6 @@ static const struct phylink_pcs_ops mt75
+@@ -3153,22 +3174,6 @@ static const struct phylink_pcs_ops mt75
.pcs_an_restart = mt7530_pcs_an_restart,
};
static void
mt7530_mdio_regmap_lock(void *mdio_lock)
{
-@@ -2993,7 +2998,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc
+@@ -3181,7 +3186,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc
mutex_unlock(mdio_lock);
}
.reg_write = mt7530_regmap_write,
.reg_read = mt7530_regmap_read,
};
-@@ -3026,7 +3031,7 @@ mt7531_create_sgmii(struct mt7530_priv *
+@@ -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_pcs_config[i]);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
-@@ -3191,6 +3196,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match)
+@@ -3380,6 +3385,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match)
static int
mt7530_probe(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv;
struct device_node *dn;
-@@ -3270,6 +3276,21 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3459,6 +3465,21 @@ mt7530_probe(struct mdio_device *mdiodev
mutex_init(&priv->reg_mutex);
dev_set_drvdata(&mdiodev->dev, priv);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -774,6 +774,7 @@ struct mt753x_info {
+@@ -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
* @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
-@@ -794,6 +795,7 @@ struct mt7530_priv {
+@@ -805,6 +806,7 @@ struct mt7530_priv {
struct device *dev;
struct dsa_switch *ds;
struct mii_bus *bus;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3077,12 +3077,6 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3265,12 +3265,6 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
return ret;
}
-@@ -3199,6 +3193,7 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3388,6 +3382,7 @@ mt7530_probe(struct mdio_device *mdiodev
static struct regmap_config *regmap_config;
struct mt7530_priv *priv;
struct device_node *dn;
dn = mdiodev->dev.of_node;
-@@ -3291,6 +3286,12 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3480,6 +3475,12 @@ mt7530_probe(struct mdio_device *mdiodev
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
}
static void
-@@ -646,14 +650,13 @@ static int
+@@ -660,14 +664,13 @@ static int
mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
int regnum)
{
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -686,7 +689,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr
+@@ -700,7 +703,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
return ret;
}
-@@ -695,14 +698,13 @@ static int
+@@ -709,14 +712,13 @@ static int
mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
int regnum, u32 data)
{
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -734,7 +736,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p
+@@ -748,7 +750,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p
}
out:
return ret;
}
-@@ -742,14 +744,13 @@ out:
+@@ -756,14 +758,13 @@ out:
static int
mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
{
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -772,7 +773,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr
+@@ -786,7 +787,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
return ret;
}
-@@ -781,14 +782,13 @@ static int
+@@ -795,14 +796,13 @@ static int
mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
u16 data)
{
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -810,7 +810,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p
+@@ -824,7 +824,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p
}
out:
return ret;
}
-@@ -1162,7 +1162,6 @@ static int
+@@ -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;
int length;
u32 val;
-@@ -1173,7 +1172,7 @@ mt7530_port_change_mtu(struct dsa_switch
+@@ -1355,7 +1354,7 @@ mt7530_port_change_mtu(struct dsa_switch
if (!dsa_is_cpu_port(ds, port))
return 0;
val = mt7530_mii_read(priv, MT7530_GMACCR);
val &= ~MAX_RX_PKT_LEN_MASK;
-@@ -1194,7 +1193,7 @@ mt7530_port_change_mtu(struct dsa_switch
+@@ -1376,7 +1375,7 @@ mt7530_port_change_mtu(struct dsa_switch
mt7530_mii_write(priv, MT7530_GMACCR, val);
return 0;
}
-@@ -1990,10 +1989,10 @@ mt7530_irq_thread_fn(int irq, void *dev_
+@@ -2172,10 +2171,10 @@ mt7530_irq_thread_fn(int irq, void *dev_
u32 val;
int p;
for (p = 0; p < MT7530_NUM_PHYS; p++) {
if (BIT(p) & val) {
-@@ -2029,7 +2028,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
+@@ -2211,7 +2210,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
{
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
}
static void
-@@ -2038,7 +2037,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da
+@@ -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);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -951,6 +951,24 @@ mt7530_set_ageing_time(struct dsa_switch
+@@ -965,6 +965,24 @@ mt7530_set_ageing_time(struct dsa_switch
return 0;
}
struct mt7530_priv *priv = ds->priv;
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -709,24 +709,6 @@ enum p5_interface_select {
+@@ -720,24 +720,6 @@ enum p5_interface_select {
P5_INTF_SEL_GMAC5_SGMII,
};
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3205,44 +3205,21 @@ static const struct of_device_id mt7530_
+@@ -3394,44 +3394,21 @@ static const struct of_device_id mt7530_
MODULE_DEVICE_TABLE(of, mt7530_of_match);
static int
if (!priv->info)
return -EINVAL;
-@@ -3256,23 +3233,53 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3445,23 +3422,53 @@ mt7530_probe(struct mdio_device *mdiodev
return -EINVAL;
priv->id = priv->info->id;
priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(priv->reset)) {
-@@ -3281,12 +3288,15 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3470,12 +3477,15 @@ mt7530_probe(struct mdio_device *mdiodev
}
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3323,6 +3323,17 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3512,6 +3512,17 @@ mt7530_probe(struct mdio_device *mdiodev
}
static void
mt7530_remove(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-@@ -3341,16 +3352,11 @@ mt7530_remove(struct mdio_device *mdiode
+@@ -3530,16 +3541,11 @@ mt7530_remove(struct mdio_device *mdiode
dev_err(priv->dev, "Failed to disable io pwr: %d\n",
ret);
static u32
mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
{
-@@ -3003,72 +2954,6 @@ static const struct phylink_pcs_ops mt75
+@@ -3191,72 +3142,6 @@ static const struct phylink_pcs_ops mt75
.pcs_an_restart = mt7530_pcs_an_restart,
};
static int
mt753x_setup(struct dsa_switch *ds)
{
-@@ -3127,7 +3012,7 @@ static int mt753x_set_mac_eee(struct dsa
+@@ -3315,7 +3200,7 @@ static int mt753x_set_mac_eee(struct dsa
return 0;
}
+const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
- .get_strings = mt7530_get_strings,
-@@ -3161,8 +3046,9 @@ static const struct dsa_switch_ops mt753
+ .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,
};
[ID_MT7621] = {
.id = ID_MT7621,
.pcs_ops = &mt7530_pcs_ops,
-@@ -3195,16 +3081,9 @@ static const struct mt753x_info mt753x_t
+@@ -3384,16 +3270,9 @@ static const struct mt753x_info mt753x_t
.mac_port_config = mt7531_mac_config,
},
};
mt7530_probe_common(struct mt7530_priv *priv)
{
struct device *dev = priv->dev;
-@@ -3241,88 +3120,9 @@ mt7530_probe_common(struct mt7530_priv *
+@@ -3430,88 +3309,9 @@ mt7530_probe_common(struct mt7530_priv *
return 0;
}
mt7530_remove_common(struct mt7530_priv *priv)
{
if (priv->irq)
-@@ -3333,57 +3133,6 @@ mt7530_remove_common(struct mt7530_priv
+@@ -3522,57 +3322,6 @@ mt7530_remove_common(struct mt7530_priv
mutex_destroy(&priv->reg_mutex);
}
MODULE_LICENSE("GPL");
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -834,4 +834,10 @@ static inline void INIT_MT7530_DUMMY_POL
+@@ -845,4 +845,10 @@ static inline void INIT_MT7530_DUMMY_POL
p->reg = reg;
}
+MODULE_LICENSE("GPL");
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2037,6 +2037,47 @@ static const struct irq_domain_ops mt753
+@@ -2219,6 +2219,47 @@ static const struct irq_domain_ops mt753
};
static void
mt7530_setup_mdio_irq(struct mt7530_priv *priv)
{
struct dsa_switch *ds = priv->ds;
-@@ -2070,8 +2111,15 @@ mt7530_setup_irq(struct mt7530_priv *pri
+@@ -2252,8 +2293,15 @@ mt7530_setup_irq(struct mt7530_priv *pri
return priv->irq ? : -EINVAL;
}
if (!priv->irq_domain) {
dev_err(dev, "failed to create IRQ domain\n");
return -ENOMEM;
-@@ -2566,6 +2614,25 @@ static void mt7531_mac_port_get_caps(str
+@@ -2754,6 +2802,25 @@ static void mt7531_mac_port_get_caps(str
}
}
static int
mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
{
-@@ -2642,6 +2709,17 @@ static bool mt753x_is_mac_port(u32 port)
+@@ -2830,6 +2897,17 @@ static bool mt753x_is_mac_port(u32 port)
}
static int
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
{
-@@ -2711,7 +2789,8 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2899,7 +2977,8 @@ mt753x_phylink_mac_config(struct dsa_swi
switch (port) {
case 0 ... 4: /* Internal phy */
goto unsupported;
break;
case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-@@ -2789,7 +2868,8 @@ static void mt753x_phylink_mac_link_up(s
+@@ -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.
*/
(phy_interface_mode_is_8023z(interface))) {
speed = SPEED_1000;
duplex = DUPLEX_FULL;
-@@ -2869,6 +2949,21 @@ mt7531_cpu_port_config(struct dsa_switch
+@@ -3057,6 +3137,21 @@ 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)
{
-@@ -3014,6 +3109,27 @@ static int mt753x_set_mac_eee(struct dsa
+@@ -3202,6 +3297,27 @@ static int mt753x_set_mac_eee(struct dsa
return 0;
}
const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
-@@ -3082,6 +3198,17 @@ const struct mt753x_info mt753x_table[]
+@@ -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,
},
};
#define NUM_TRGMII_CTRL 5
-@@ -54,11 +55,11 @@ enum mt753x_id {
- #define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
+@@ -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_MIRROR_MASK : MIRROR_MASK)
/* Registers for BPDU and PAE frame control*/
-@@ -322,9 +323,8 @@ enum mt7530_vlan_port_acc_frm {
+@@ -332,9 +333,8 @@ enum mt7530_vlan_port_acc_frm {
MT7531_FORCE_DPX | \
MT7531_FORCE_RX_FC | \
MT7531_FORCE_TX_FC)
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3076,6 +3076,12 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3264,6 +3264,12 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -768,10 +768,10 @@ struct mt753x_info {
+@@ -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
*/
struct mt7530_priv {
struct device *dev;
-@@ -790,7 +790,6 @@ struct mt7530_priv {
+@@ -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*/
-@@ -798,6 +797,7 @@ struct mt7530_priv {
+@@ -809,6 +808,7 @@ struct mt7530_priv {
int irq;
struct irq_domain *irq_domain;
u32 irq_enable;
ax88179_reset(dev);
-@@ -1507,17 +1508,19 @@ ax88179_tx_fixup(struct usbnet *dev, str
+@@ -1502,17 +1503,19 @@ ax88179_tx_fixup(struct usbnet *dev, str
{
u32 tx_hdr1, tx_hdr2;
int frame_size = dev->maxpacket;
if ((skb_header_cloned(skb) || headroom < 0) &&
pskb_expand_head(skb, headroom < 0 ? 8 : 0, 0, GFP_ATOMIC)) {
dev_kfree_skb_any(skb);
-@@ -1528,6 +1531,8 @@ ax88179_tx_fixup(struct usbnet *dev, str
+@@ -1523,6 +1526,8 @@ ax88179_tx_fixup(struct usbnet *dev, str
put_unaligned_le32(tx_hdr1, ptr);
put_unaligned_le32(tx_hdr2, ptr + 4);
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
-@@ -2287,6 +2287,23 @@ struct btmtk_section_map {
+@@ -2289,6 +2289,23 @@ struct btmtk_section_map {
};
} __packed;
static void btusb_mtk_wmt_recv(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
-@@ -3941,6 +3958,7 @@ static int btusb_probe(struct usb_interf
+@@ -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;
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
-@@ -2292,7 +2292,7 @@ static int btusb_set_bdaddr_mtk(struct h
+@@ -2294,7 +2294,7 @@ static int btusb_set_bdaddr_mtk(struct h
struct sk_buff *skb;
long ret;
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
-@@ -476,6 +476,9 @@ static const struct usb_device_id blackl
+@@ -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 },
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
-@@ -467,6 +467,9 @@ static const struct usb_device_id blackl
+@@ -469,6 +469,9 @@ static const struct usb_device_id blackl
BTUSB_VALID_LE_STATES },
/* Additional MediaTek MT7921 Bluetooth devices */
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
-@@ -485,6 +485,9 @@ static const struct usb_device_id blackl
+@@ -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 },
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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--;
--- /dev/null
+From: Richard Gobert <richardbgobert@gmail.com>
+Date: Tue, 30 Apr 2024 16:35:55 +0200
+Subject: [PATCH] net: gro: add flush check in udp_gro_receive_segment
+
+GRO-GSO path is supposed to be transparent and as such L3 flush checks are
+relevant to all UDP flows merging in GRO. This patch uses the same logic
+and code from tcp_gro_receive, terminating merge if flush is non zero.
+
+Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.")
+Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -463,6 +463,7 @@ static struct sk_buff *udp_gro_receive_s
+ struct sk_buff *p;
+ unsigned int ulen;
+ int ret = 0;
++ int flush;
+
+ /* requires non zero csum, for symmetry with GSO */
+ if (!uh->check) {
+@@ -496,13 +497,22 @@ static struct sk_buff *udp_gro_receive_s
+ return p;
+ }
+
++ flush = NAPI_GRO_CB(p)->flush;
++
++ if (NAPI_GRO_CB(p)->flush_id != 1 ||
++ NAPI_GRO_CB(p)->count != 1 ||
++ !NAPI_GRO_CB(p)->is_atomic)
++ flush |= NAPI_GRO_CB(p)->flush_id;
++ else
++ NAPI_GRO_CB(p)->is_atomic = false;
++
+ /* Terminate the flow on len mismatch or if it grow "too much".
+ * Under small packet flood GRO count could elsewhere grow a lot
+ * leading to excessive truesize values.
+ * On len mismatch merge the first packet shorter than gso_size,
+ * otherwise complete the GRO packet.
+ */
+- if (ulen > ntohs(uh2->len)) {
++ if (ulen > ntohs(uh2->len) || flush) {
+ pp = p;
+ } else {
+ if (NAPI_GRO_CB(skb)->is_flist) {
+++ /dev/null
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Thu, 11 Apr 2024 13:28:59 +0200
-Subject: [PATCH] netfilter: flowtable: validate pppoe header
-
-Ensure there is sufficient room to access the protocol field of the
-PPPoe header. Validate it once before the flowtable lookup, then use a
-helper function to access protocol field.
-
-Reported-by: syzbot+b6f07e1c07ef40199081@syzkaller.appspotmail.com
-Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
-
---- a/include/net/netfilter/nf_flow_table.h
-+++ b/include/net/netfilter/nf_flow_table.h
-@@ -335,7 +335,7 @@ int nf_flow_rule_route_ipv6(struct net *
- int nf_flow_table_offload_init(void);
- void nf_flow_table_offload_exit(void);
-
--static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
-+static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb)
- {
- __be16 proto;
-
-@@ -351,6 +351,16 @@ static inline __be16 nf_flow_pppoe_proto
- return 0;
- }
-
-+static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto)
-+{
-+ if (!pskb_may_pull(skb, PPPOE_SES_HLEN))
-+ return false;
-+
-+ *inner_proto = __nf_flow_pppoe_proto(skb);
-+
-+ return true;
-+}
-+
- #define NF_FLOW_TABLE_STAT_INC(net, count) __this_cpu_inc((net)->ft.stat->count)
- #define NF_FLOW_TABLE_STAT_DEC(net, count) __this_cpu_dec((net)->ft.stat->count)
- #define NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count) \
---- a/net/netfilter/nf_flow_table_inet.c
-+++ b/net/netfilter/nf_flow_table_inet.c
-@@ -21,7 +21,8 @@ nf_flow_offload_inet_hook(void *priv, st
- proto = veth->h_vlan_encapsulated_proto;
- break;
- case htons(ETH_P_PPP_SES):
-- proto = nf_flow_pppoe_proto(skb);
-+ if (!nf_flow_pppoe_proto(skb, &proto))
-+ return NF_ACCEPT;
- break;
- default:
- proto = skb->protocol;
---- a/net/netfilter/nf_flow_table_ip.c
-+++ b/net/netfilter/nf_flow_table_ip.c
-@@ -267,10 +267,11 @@ static unsigned int nf_flow_xmit_xfrm(st
- return NF_STOLEN;
- }
-
--static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto,
-+static bool nf_flow_skb_encap_protocol(struct sk_buff *skb, __be16 proto,
- u32 *offset)
- {
- struct vlan_ethhdr *veth;
-+ __be16 inner_proto;
-
- switch (skb->protocol) {
- case htons(ETH_P_8021Q):
-@@ -281,7 +282,8 @@ static bool nf_flow_skb_encap_protocol(c
- }
- break;
- case htons(ETH_P_PPP_SES):
-- if (nf_flow_pppoe_proto(skb) == proto) {
-+ if (nf_flow_pppoe_proto(skb, &inner_proto) &&
-+ inner_proto == proto) {
- *offset += PPPOE_SES_HLEN;
- return true;
- }
-@@ -310,7 +312,7 @@ static void nf_flow_encap_pop(struct sk_
- skb_reset_network_header(skb);
- break;
- case htons(ETH_P_PPP_SES):
-- skb->protocol = nf_flow_pppoe_proto(skb);
-+ skb->protocol = __nf_flow_pppoe_proto(skb);
- skb_pull(skb, PPPOE_SES_HLEN);
- skb_reset_network_header(skb);
- break;
+++ /dev/null
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Thu, 11 Apr 2024 13:29:00 +0200
-Subject: [PATCH] netfilter: flowtable: incorrect pppoe tuple
-
-pppoe traffic reaching ingress path does not match the flowtable entry
-because the pppoe header is expected to be at the network header offset.
-This bug causes a mismatch in the flow table lookup, so pppoe packets
-enter the classical forwarding path.
-
-Fixes: 72efd585f714 ("netfilter: flowtable: add pppoe support")
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
-
---- a/net/netfilter/nf_flow_table_ip.c
-+++ b/net/netfilter/nf_flow_table_ip.c
-@@ -156,7 +156,7 @@ static void nf_flow_tuple_encap(struct s
- tuple->encap[i].proto = skb->protocol;
- break;
- case htons(ETH_P_PPP_SES):
-- phdr = (struct pppoe_hdr *)skb_mac_header(skb);
-+ phdr = (struct pppoe_hdr *)skb_network_header(skb);
- tuple->encap[i].id = ntohs(phdr->sid);
- tuple->encap[i].proto = skb->protocol;
- break;
}
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
-@@ -1736,6 +1736,15 @@ static int dsa_switch_probe(struct dsa_s
+@@ -1758,6 +1758,15 @@ static int dsa_switch_probe(struct dsa_s
if (!ds->num_ports)
return -EINVAL;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3010,9 +3010,6 @@ static void mt753x_phylink_get_caps(stru
+@@ -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;
#include <linux/phylink.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
-@@ -2651,128 +2652,11 @@ static int mt7531_rgmii_setup(struct mt7
+@@ -2839,128 +2840,11 @@ static int mt7531_rgmii_setup(struct mt7
return 0;
}
static int
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
-@@ -2795,11 +2679,11 @@ mt7531_mac_config(struct dsa_switch *ds,
+@@ -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:
default:
return -EINVAL;
}
-@@ -2824,11 +2708,11 @@ mt753x_phylink_mac_select_pcs(struct dsa
+@@ -3012,11 +2896,11 @@ mt753x_phylink_mac_select_pcs(struct dsa
switch (interface) {
case PHY_INTERFACE_MODE_TRGMII:
default:
return NULL;
}
-@@ -3066,86 +2950,6 @@ static void mt7530_pcs_get_state(struct
+@@ -3254,86 +3138,6 @@ static void mt7530_pcs_get_state(struct
state->pause |= MLO_PAUSE_TX;
}
static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
phy_interface_t interface,
const unsigned long *advertising,
-@@ -3165,18 +2969,57 @@ static const struct phylink_pcs_ops mt75
+@@ -3353,18 +3157,57 @@ static const struct phylink_pcs_ops mt75
.pcs_an_restart = mt7530_pcs_an_restart,
};
int i, ret;
/* Initialise the PCS devices */
-@@ -3184,8 +3027,6 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -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;
}
ret = priv->info->sw_setup(ds);
-@@ -3200,6 +3041,16 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3388,6 +3229,16 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
return ret;
}
-@@ -3291,7 +3142,7 @@ static const struct mt753x_info mt753x_t
+@@ -3480,7 +3331,7 @@ static const struct mt753x_info mt753x_t
},
[ID_MT7531] = {
.id = ID_MT7531,
.sw_setup = mt7531_setup,
.phy_read = mt7531_ind_phy_read,
.phy_write = mt7531_ind_phy_write,
-@@ -3399,7 +3250,7 @@ static void
+@@ -3588,7 +3439,7 @@ static void
mt7530_remove(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
if (!priv)
return;
-@@ -3418,6 +3269,10 @@ mt7530_remove(struct mdio_device *mdiode
+@@ -3607,6 +3458,10 @@ mt7530_remove(struct mdio_device *mdiode
mt7530_free_irq(priv);
dsa_unregister_switch(priv->ds);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -391,47 +391,8 @@ enum mt7530_vlan_port_acc_frm {
+@@ -401,47 +401,8 @@ enum mt7530_vlan_port_acc_frm {
CCR_TX_OCT_CNT_BAD)
/* MT7531 SGMII register group */
/* Register for system reset */
#define MT7530_SYS_CTRL 0x7000
-@@ -730,13 +691,13 @@ struct mt7530_fdb {
+@@ -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.
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3001,26 +3001,56 @@ static const struct regmap_bus mt7531_re
+@@ -3189,26 +3189,56 @@ static const struct regmap_bus mt7531_re
.reg_update_bits = mt7530_regmap_update_bits,
};
int i, ret;
/* Initialise the PCS devices */
-@@ -3042,15 +3072,11 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3230,15 +3260,11 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2974,7 +2974,7 @@ static int mt7530_regmap_read(void *cont
+@@ -3162,7 +3162,7 @@ static int mt7530_regmap_read(void *cont
{
struct mt7530_priv *priv = context;
return 0;
};
-@@ -2982,23 +2982,25 @@ static int mt7530_regmap_write(void *con
+@@ -3170,23 +3170,25 @@ static int mt7530_regmap_write(void *con
{
struct mt7530_priv *priv = context;
};
static int
-@@ -3024,6 +3026,9 @@ mt7531_create_sgmii(struct mt7530_priv *
+@@ -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;
}
static void
-@@ -2970,22 +2991,6 @@ static const struct phylink_pcs_ops mt75
+@@ -3158,22 +3179,6 @@ static const struct phylink_pcs_ops mt75
.pcs_an_restart = mt7530_pcs_an_restart,
};
static void
mt7530_mdio_regmap_lock(void *mdio_lock)
{
-@@ -2998,7 +3003,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc
+@@ -3186,7 +3191,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc
mutex_unlock(mdio_lock);
}
.reg_write = mt7530_regmap_write,
.reg_read = mt7530_regmap_read,
};
-@@ -3031,7 +3036,7 @@ mt7531_create_sgmii(struct mt7530_priv *
+@@ -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_pcs_config[i]);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
-@@ -3196,6 +3201,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match)
+@@ -3385,6 +3390,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match)
static int
mt7530_probe(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv;
struct device_node *dn;
-@@ -3275,6 +3281,21 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3464,6 +3470,21 @@ mt7530_probe(struct mdio_device *mdiodev
mutex_init(&priv->reg_mutex);
dev_set_drvdata(&mdiodev->dev, priv);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -774,6 +774,7 @@ struct mt753x_info {
+@@ -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
* @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
-@@ -794,6 +795,7 @@ struct mt7530_priv {
+@@ -805,6 +806,7 @@ struct mt7530_priv {
struct device *dev;
struct dsa_switch *ds;
struct mii_bus *bus;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3082,12 +3082,6 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3270,12 +3270,6 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
return ret;
}
-@@ -3204,6 +3198,7 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3393,6 +3387,7 @@ mt7530_probe(struct mdio_device *mdiodev
static struct regmap_config *regmap_config;
struct mt7530_priv *priv;
struct device_node *dn;
dn = mdiodev->dev.of_node;
-@@ -3296,6 +3291,12 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3485,6 +3480,12 @@ mt7530_probe(struct mdio_device *mdiodev
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
}
static void
-@@ -645,14 +649,13 @@ static int
+@@ -659,14 +663,13 @@ static int
mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
int regnum)
{
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -685,7 +688,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr
+@@ -699,7 +702,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
return ret;
}
-@@ -694,14 +697,13 @@ static int
+@@ -708,14 +711,13 @@ static int
mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
int regnum, u32 data)
{
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -733,7 +735,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p
+@@ -747,7 +749,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p
}
out:
return ret;
}
-@@ -741,14 +743,13 @@ out:
+@@ -755,14 +757,13 @@ out:
static int
mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
{
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -771,7 +772,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr
+@@ -785,7 +786,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
return ret;
}
-@@ -780,14 +781,13 @@ static int
+@@ -794,14 +795,13 @@ static int
mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
u16 data)
{
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
-@@ -809,7 +809,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p
+@@ -823,7 +823,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p
}
out:
return ret;
}
-@@ -1161,7 +1161,6 @@ static int
+@@ -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;
int length;
u32 val;
-@@ -1172,7 +1171,7 @@ mt7530_port_change_mtu(struct dsa_switch
+@@ -1354,7 +1353,7 @@ mt7530_port_change_mtu(struct dsa_switch
if (!dsa_is_cpu_port(ds, port))
return 0;
val = mt7530_mii_read(priv, MT7530_GMACCR);
val &= ~MAX_RX_PKT_LEN_MASK;
-@@ -1193,7 +1192,7 @@ mt7530_port_change_mtu(struct dsa_switch
+@@ -1375,7 +1374,7 @@ mt7530_port_change_mtu(struct dsa_switch
mt7530_mii_write(priv, MT7530_GMACCR, val);
return 0;
}
-@@ -1994,10 +1993,10 @@ mt7530_irq_thread_fn(int irq, void *dev_
+@@ -2176,10 +2175,10 @@ mt7530_irq_thread_fn(int irq, void *dev_
u32 val;
int p;
for (p = 0; p < MT7530_NUM_PHYS; p++) {
if (BIT(p) & val) {
-@@ -2033,7 +2032,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
+@@ -2215,7 +2214,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
{
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
}
static void
-@@ -2042,7 +2041,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da
+@@ -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);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -950,6 +950,24 @@ mt7530_set_ageing_time(struct dsa_switch
+@@ -964,6 +964,24 @@ mt7530_set_ageing_time(struct dsa_switch
return 0;
}
struct mt7530_priv *priv = ds->priv;
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -709,24 +709,6 @@ enum p5_interface_select {
+@@ -720,24 +720,6 @@ enum p5_interface_select {
P5_INTF_SEL_GMAC5_SGMII,
};
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3210,44 +3210,21 @@ static const struct of_device_id mt7530_
+@@ -3399,44 +3399,21 @@ static const struct of_device_id mt7530_
MODULE_DEVICE_TABLE(of, mt7530_of_match);
static int
if (!priv->info)
return -EINVAL;
-@@ -3261,23 +3238,53 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3450,23 +3427,53 @@ mt7530_probe(struct mdio_device *mdiodev
return -EINVAL;
priv->id = priv->info->id;
priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(priv->reset)) {
-@@ -3286,12 +3293,15 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3475,12 +3482,15 @@ mt7530_probe(struct mdio_device *mdiodev
}
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3328,6 +3328,17 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -3517,6 +3517,17 @@ mt7530_probe(struct mdio_device *mdiodev
}
static void
mt7530_remove(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-@@ -3346,15 +3357,10 @@ mt7530_remove(struct mdio_device *mdiode
+@@ -3535,15 +3546,10 @@ mt7530_remove(struct mdio_device *mdiode
dev_err(priv->dev, "Failed to disable io pwr: %d\n",
ret);
static u32
mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
{
-@@ -3008,72 +2959,6 @@ static const struct phylink_pcs_ops mt75
+@@ -3196,72 +3147,6 @@ static const struct phylink_pcs_ops mt75
.pcs_an_restart = mt7530_pcs_an_restart,
};
static int
mt753x_setup(struct dsa_switch *ds)
{
-@@ -3132,7 +3017,7 @@ static int mt753x_set_mac_eee(struct dsa
+@@ -3320,7 +3205,7 @@ static int mt753x_set_mac_eee(struct dsa
return 0;
}
+const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
- .get_strings = mt7530_get_strings,
-@@ -3166,8 +3051,9 @@ static const struct dsa_switch_ops mt753
+ .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,
};
[ID_MT7621] = {
.id = ID_MT7621,
.pcs_ops = &mt7530_pcs_ops,
-@@ -3200,16 +3086,9 @@ static const struct mt753x_info mt753x_t
+@@ -3389,16 +3275,9 @@ static const struct mt753x_info mt753x_t
.mac_port_config = mt7531_mac_config,
},
};
mt7530_probe_common(struct mt7530_priv *priv)
{
struct device *dev = priv->dev;
-@@ -3246,88 +3125,9 @@ mt7530_probe_common(struct mt7530_priv *
+@@ -3435,88 +3314,9 @@ mt7530_probe_common(struct mt7530_priv *
return 0;
}
mt7530_remove_common(struct mt7530_priv *priv)
{
if (priv->irq)
-@@ -3337,55 +3137,7 @@ mt7530_remove_common(struct mt7530_priv
+@@ -3526,55 +3326,7 @@ mt7530_remove_common(struct mt7530_priv
mutex_destroy(&priv->reg_mutex);
}
MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -834,4 +834,10 @@ static inline void INIT_MT7530_DUMMY_POL
+@@ -845,4 +845,10 @@ static inline void INIT_MT7530_DUMMY_POL
p->reg = reg;
}
+MODULE_LICENSE("GPL");
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2041,6 +2041,47 @@ static const struct irq_domain_ops mt753
+@@ -2223,6 +2223,47 @@ static const struct irq_domain_ops mt753
};
static void
mt7530_setup_mdio_irq(struct mt7530_priv *priv)
{
struct dsa_switch *ds = priv->ds;
-@@ -2074,8 +2115,15 @@ mt7530_setup_irq(struct mt7530_priv *pri
+@@ -2256,8 +2297,15 @@ mt7530_setup_irq(struct mt7530_priv *pri
return priv->irq ? : -EINVAL;
}
if (!priv->irq_domain) {
dev_err(dev, "failed to create IRQ domain\n");
return -ENOMEM;
-@@ -2574,6 +2622,25 @@ static void mt7531_mac_port_get_caps(str
+@@ -2762,6 +2810,25 @@ static void mt7531_mac_port_get_caps(str
}
}
static int
mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
{
-@@ -2650,6 +2717,17 @@ static bool mt753x_is_mac_port(u32 port)
+@@ -2838,6 +2905,17 @@ static bool mt753x_is_mac_port(u32 port)
}
static int
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
{
-@@ -2719,7 +2797,8 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2907,7 +2985,8 @@ mt753x_phylink_mac_config(struct dsa_swi
switch (port) {
case 0 ... 4: /* Internal phy */
goto unsupported;
break;
case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
-@@ -2797,7 +2876,8 @@ static void mt753x_phylink_mac_link_up(s
+@@ -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.
*/
(phy_interface_mode_is_8023z(interface))) {
speed = SPEED_1000;
duplex = DUPLEX_FULL;
-@@ -2877,6 +2957,21 @@ mt7531_cpu_port_config(struct dsa_switch
+@@ -3065,6 +3145,21 @@ 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)
{
-@@ -3019,6 +3114,27 @@ static int mt753x_set_mac_eee(struct dsa
+@@ -3207,6 +3302,27 @@ static int mt753x_set_mac_eee(struct dsa
return 0;
}
const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
-@@ -3087,6 +3203,17 @@ const struct mt753x_info mt753x_table[]
+@@ -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,
},
};
#define NUM_TRGMII_CTRL 5
-@@ -54,11 +55,11 @@ enum mt753x_id {
- #define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
+@@ -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_MIRROR_MASK : MIRROR_MASK)
/* Registers for BPDU and PAE frame control*/
-@@ -322,9 +323,8 @@ enum mt7530_vlan_port_acc_frm {
+@@ -332,9 +333,8 @@ enum mt7530_vlan_port_acc_frm {
MT7531_FORCE_DPX | \
MT7531_FORCE_RX_FC | \
MT7531_FORCE_TX_FC)
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3081,6 +3081,12 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3269,6 +3269,12 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -768,10 +768,10 @@ struct mt753x_info {
+@@ -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
*/
struct mt7530_priv {
struct device *dev;
-@@ -790,7 +790,6 @@ struct mt7530_priv {
+@@ -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*/
-@@ -798,6 +797,7 @@ struct mt7530_priv {
+@@ -809,6 +808,7 @@ struct mt7530_priv {
int irq;
struct irq_domain *irq_domain;
u32 irq_enable;
+++ /dev/null
-From 4b11e3eb0eb7245a0d22a5dc4161c54eea42910c 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, 17 Jun 2023 09:26:44 +0300
-Subject: [PATCH 16/48] net: dsa: mt7530: set all CPU ports in MT7531_CPU_PMAP
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-MT7531_CPU_PMAP represents the destination port mask for trapped-to-CPU
-frames (further restricted by PCR_MATRIX).
-
-Currently the driver sets the first CPU port as the single port in this bit
-mask, which works fine regardless of whether the device tree defines port
-5, 6 or 5+6 as CPU ports. This is because the logic coincides with DSA's
-logic of picking the first CPU port as the CPU port that all user ports are
-affine to, by default.
-
-An upcoming change would like to influence DSA's selection of the default
-CPU port to no longer be the first one, and in that case, this logic needs
-adaptation.
-
-Since there is no observed leakage or duplication of frames if all CPU
-ports are defined in this bit mask, simply include them all.
-
-Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
-Suggested-by: Vladimir Oltean <olteanv@gmail.com>
-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>
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 15 +++++++--------
- drivers/net/dsa/mt7530.h | 1 +
- 2 files changed, 8 insertions(+), 8 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1069,6 +1069,13 @@ mt753x_cpu_port_enable(struct dsa_switch
- 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 and the switch on
-+ * the MT7988 SoC. Trapped frames will be forwarded to the CPU port that
-+ * is affine to the inbound user port.
-+ */
-+ if (priv->id == ID_MT7531 || priv->id == ID_MT7988)
-+ mt7530_set(priv, MT7531_CFC, MT7531_CPU_PMAP(BIT(port)));
-+
- /* CPU port gets connected to all user ports of
- * the switch.
- */
-@@ -2411,16 +2418,8 @@ static int
- mt7531_setup_common(struct dsa_switch *ds)
- {
- struct mt7530_priv *priv = ds->priv;
-- struct dsa_port *cpu_dp;
- int ret, i;
-
-- /* BPDU to CPU port */
-- dsa_switch_for_each_cpu_port(cpu_dp, ds) {
-- mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
-- BIT(cpu_dp->index));
-- break;
-- }
--
- mt753x_trap_frames(priv);
-
- /* Enable and reset MIB counters */
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -54,6 +54,7 @@ enum mt753x_id {
- #define MT7531_MIRROR_PORT_GET(x) (((x) >> 16) & MIRROR_MASK)
- #define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
- #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)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3036,7 +3036,7 @@ static void mt7530_pcs_get_state(struct
+@@ -3225,7 +3225,7 @@ static void mt7530_pcs_get_state(struct
state->pause |= MLO_PAUSE_TX;
}
phy_interface_t interface,
const unsigned long *advertising,
bool permit_pause_to_mac)
-@@ -3064,6 +3064,7 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -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;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2851,15 +2851,6 @@ static void mt753x_phylink_mac_link_down
+@@ -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_mac_link_up(struct dsa_switch *ds, int port,
unsigned int mode,
phy_interface_t interface,
-@@ -2948,8 +2939,6 @@ mt7531_cpu_port_config(struct dsa_switch
+@@ -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));
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -829,8 +829,7 @@ mt7530_get_strings(struct dsa_switch *ds
+@@ -843,8 +843,7 @@ mt7530_get_strings(struct dsa_switch *ds
return;
for (i = 0; i < ARRAY_SIZE(mt7530_mib); i++)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2175,24 +2175,40 @@ mt7530_free_irq_common(struct mt7530_pri
+@@ -2350,24 +2350,40 @@ mt7530_free_irq_common(struct mt7530_pri
static void
mt7530_free_irq(struct mt7530_priv *priv)
{
bus->priv = priv;
bus->name = KBUILD_MODNAME "-mii";
snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d", idx++);
-@@ -2201,16 +2217,18 @@ mt7530_setup_mdio(struct mt7530_priv *pr
+@@ -2376,16 +2392,18 @@ mt7530_setup_mdio(struct mt7530_priv *pr
bus->parent = dev;
bus->phy_mask = ~ds->phys_mii_mask;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2883,8 +2883,7 @@ static void mt753x_phylink_mac_link_up(s
+@@ -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.
*/
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -1064,10 +1064,6 @@ mt753x_cpu_port_enable(struct dsa_switch
+@@ -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)));
- 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 and the switch on
- * the MT7988 SoC. Trapped frames will be forwarded to the CPU port that
- * is affine to the inbound user port.
-@@ -3125,6 +3121,36 @@ static int mt753x_set_mac_eee(struct dsa
+ /* 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 int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
{
return 0;
-@@ -3179,6 +3205,7 @@ const struct dsa_switch_ops mt7530_switc
+@@ -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,
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -41,8 +41,8 @@ enum mt753x_id {
+@@ -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 MIRROR_EN BIT(3)
#define MIRROR_PORT(x) ((x) & 0x7)
#define MIRROR_MASK 0x7
-@@ -773,6 +773,7 @@ struct mt753x_info {
+@@ -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)
*/
struct mt7530_priv {
struct device *dev;
-@@ -799,6 +800,7 @@ struct mt7530_priv {
+@@ -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);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -703,7 +703,7 @@ struct mt7530_port {
+@@ -713,7 +713,7 @@ struct mt7530_port {
/* Port 5 interface select definitions */
enum p5_interface_select {
P5_INTF_SEL_PHY_P0,
P5_INTF_SEL_PHY_P4,
P5_INTF_SEL_GMAC5,
-@@ -789,7 +789,7 @@ struct mt7530_priv {
+@@ -799,7 +799,7 @@ struct mt7530_priv {
bool mcm;
phy_interface_t p6_interface;
phy_interface_t p5_interface;
GFP_KERNEL);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -473,15 +473,6 @@ mt7530_pad_clk_setup(struct dsa_switch *
+@@ -487,15 +487,6 @@ mt7530_pad_clk_setup(struct dsa_switch *
return 0;
}
static int
mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
{
-@@ -496,9 +487,6 @@ mt7531_pll_setup(struct mt7530_priv *pri
+@@ -510,9 +501,6 @@ mt7531_pll_setup(struct mt7530_priv *pri
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);
-@@ -913,8 +901,6 @@ static const char *p5_intf_modes(unsigne
+@@ -927,8 +915,6 @@ static const char *p5_intf_modes(unsigne
return "PHY P4";
case P5_INTF_SEL_GMAC5:
return "GMAC5";
default:
return "unknown";
}
-@@ -2515,6 +2501,12 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -2697,6 +2683,12 @@ 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);
-@@ -2524,21 +2516,18 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -2706,21 +2698,18 @@ mt7531_setup(struct dsa_switch *ds)
SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
SYS_CTRL_REG_RST);
mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
MT7531_GPIO0_INTERRUPT);
-@@ -2598,11 +2587,6 @@ static void mt7530_mac_port_get_caps(str
+@@ -2787,11 +2776,6 @@ static void mt7530_mac_port_get_caps(str
}
}
static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
struct phylink_config *config)
{
-@@ -2615,7 +2599,7 @@ static void mt7531_mac_port_get_caps(str
+@@ -2804,7 +2788,7 @@ static void mt7531_mac_port_get_caps(str
break;
case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
phy_interface_set_rgmii(config->supported_interfaces);
break;
}
-@@ -2682,7 +2666,7 @@ static int mt7531_rgmii_setup(struct mt7
+@@ -2871,7 +2855,7 @@ static int mt7531_rgmii_setup(struct mt7
{
u32 val;
dev_err(priv->dev, "RGMII mode is not available for port %d\n",
port);
return -EINVAL;
-@@ -2925,7 +2909,7 @@ mt7531_cpu_port_config(struct dsa_switch
+@@ -3114,7 +3098,7 @@ mt7531_cpu_port_config(struct dsa_switch
switch (port) {
case 5:
interface = PHY_INTERFACE_MODE_RGMII;
else
interface = PHY_INTERFACE_MODE_2500BASEX;
-@@ -3083,7 +3067,7 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3272,7 +3256,7 @@ mt753x_setup(struct dsa_switch *ds)
mt7530_free_irq_common(priv);
if (priv->create_sgmii) {
}
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -707,7 +707,6 @@ enum p5_interface_select {
+@@ -717,7 +717,6 @@ enum p5_interface_select {
P5_INTF_SEL_PHY_P0,
P5_INTF_SEL_PHY_P4,
P5_INTF_SEL_GMAC5,
};
struct mt7530_priv;
-@@ -769,6 +768,8 @@ struct mt753x_info {
+@@ -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
* @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
-@@ -790,6 +791,7 @@ struct mt7530_priv {
+@@ -800,6 +801,7 @@ struct mt7530_priv {
phy_interface_t p6_interface;
phy_interface_t p5_interface;
enum p5_interface_select p5_intf_sel;
u8 mirror_rx;
u8 mirror_tx;
struct mt7530_port ports[MT7530_NUM_PORTS];
-@@ -799,7 +801,7 @@ struct mt7530_priv {
+@@ -809,7 +811,7 @@ struct mt7530_priv {
int irq;
struct irq_domain *irq_domain;
u32 irq_enable;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2565,12 +2565,14 @@ static void mt7530_mac_port_get_caps(str
+@@ -2754,12 +2754,14 @@ static void mt7530_mac_port_get_caps(str
struct phylink_config *config)
{
switch (port) {
phy_interface_set_rgmii(config->supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_MII,
config->supported_interfaces);
-@@ -2578,7 +2580,8 @@ static void mt7530_mac_port_get_caps(str
+@@ -2767,7 +2769,8 @@ static void mt7530_mac_port_get_caps(str
config->supported_interfaces);
break;
__set_bit(PHY_INTERFACE_MODE_RGMII,
config->supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_TRGMII,
-@@ -2593,19 +2596,24 @@ static void mt7531_mac_port_get_caps(str
+@@ -2782,19 +2785,24 @@ static void mt7531_mac_port_get_caps(str
struct mt7530_priv *priv = ds->priv;
switch (port) {
__set_bit(PHY_INTERFACE_MODE_SGMII,
config->supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_1000BASEX,
-@@ -2624,11 +2632,13 @@ static void mt7988_mac_port_get_caps(str
+@@ -2813,11 +2821,13 @@ static void mt7988_mac_port_get_caps(str
phy_interface_zero(config->supported_interfaces);
switch (port) {
case 6:
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
config->supported_interfaces);
-@@ -2792,12 +2802,12 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2981,12 +2991,12 @@ mt753x_phylink_mac_config(struct dsa_swi
u32 mcr_cur, mcr_new;
switch (port) {
if (priv->p5_interface == state->interface)
break;
-@@ -2807,7 +2817,7 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2996,7 +3006,7 @@ mt753x_phylink_mac_config(struct dsa_swi
if (priv->p5_intf_sel != P5_DISABLED)
priv->p5_interface = state->interface;
break;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2353,16 +2353,15 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2532,16 +2532,15 @@ mt7530_setup(struct dsa_switch *ds)
return ret;
/* Setup port 5 */
for_each_child_of_node(dn, mac_np) {
if (!of_device_is_compatible(mac_np,
"mediatek,eth-mac"))
-@@ -2393,6 +2392,8 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2572,6 +2571,8 @@ mt7530_setup(struct dsa_switch *ds)
of_node_put(phy_node);
break;
}
}
#ifdef CONFIG_GPIOLIB
-@@ -2403,8 +2404,6 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2582,8 +2583,6 @@ mt7530_setup(struct dsa_switch *ds)
}
#endif /* CONFIG_GPIOLIB */
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -971,8 +971,6 @@ static void mt7530_setup_port5(struct ds
+@@ -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));
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -935,9 +935,6 @@ static void mt7530_setup_port5(struct ds
+@@ -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;
default:
dev_err(ds->dev, "Unsupported p5_intf_sel %d\n",
priv->p5_intf_sel);
-@@ -2358,8 +2355,6 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2537,8 +2534,6 @@ mt7530_setup(struct dsa_switch *ds)
* Set priv->p5_intf_sel to the appropriate value if PHY muxing
* is detected.
*/
for_each_child_of_node(dn, mac_np) {
if (!of_device_is_compatible(mac_np,
"mediatek,eth-mac"))
-@@ -2391,7 +2386,9 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2570,7 +2565,9 @@ mt7530_setup(struct dsa_switch *ds)
break;
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -936,9 +936,7 @@ static void mt7530_setup_port5(struct ds
+@@ -950,9 +950,7 @@ static void mt7530_setup_port5(struct ds
val &= ~MHWTRAP_P5_DIS;
break;
default:
}
/* Setup RGMII settings */
-@@ -968,7 +966,6 @@ static void mt7530_setup_port5(struct ds
+@@ -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));
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -408,13 +408,6 @@ mt7530_pad_clk_setup(struct dsa_switch *
+@@ -422,13 +422,6 @@ mt7530_pad_clk_setup(struct dsa_switch *
xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK;
switch (interface) {
case PHY_INTERFACE_MODE_RGMII:
trgint = 0;
-@@ -2286,6 +2279,12 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2461,6 +2454,12 @@ mt7530_setup(struct dsa_switch *ds)
return -ENODEV;
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -404,65 +404,54 @@ static int
+@@ -418,65 +418,54 @@ static int
mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
{
struct mt7530_priv *priv = ds->priv;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -400,8 +400,8 @@ static void mt7530_pll_setup(struct mt75
+@@ -414,8 +414,8 @@ mt753x_preferred_default_local_cpu_port(
}
/* Setup port 6 interface mode and TRGMII TX circuit */
{
struct mt7530_priv *priv = ds->priv;
u32 ncpo1, ssc_delta, xtal;
-@@ -412,7 +412,7 @@ mt7530_pad_clk_setup(struct dsa_switch *
+@@ -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));
}
mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
-@@ -451,7 +451,11 @@ mt7530_pad_clk_setup(struct dsa_switch *
+@@ -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);
return 0;
}
-@@ -2640,11 +2644,10 @@ mt7530_mac_config(struct dsa_switch *ds,
+@@ -2829,11 +2833,10 @@ mt7530_mac_config(struct dsa_switch *ds,
{
struct mt7530_priv *priv = ds->priv;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -453,18 +453,6 @@ mt7530_setup_port6(struct dsa_switch *ds
+@@ -467,18 +467,6 @@ mt7530_setup_port6(struct dsa_switch *ds
core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN);
}
static void
mt7531_pll_setup(struct mt7530_priv *priv)
{
-@@ -2631,14 +2619,6 @@ static void mt7988_mac_port_get_caps(str
+@@ -2820,14 +2808,6 @@ static void mt7988_mac_port_get_caps(str
}
static int
mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
{
-@@ -2803,8 +2783,6 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2992,8 +2972,6 @@ 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;
-@@ -3127,11 +3105,6 @@ mt753x_conduit_state_change(struct dsa_s
+@@ -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_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
-@@ -3192,7 +3165,6 @@ const struct mt753x_info mt753x_table[]
+@@ -3382,7 +3355,6 @@ const struct mt753x_info mt753x_table[]
.sw_setup = mt7530_setup,
.phy_read = mt7530_phy_read,
.phy_write = mt7530_phy_write,
.mac_port_get_caps = mt7530_mac_port_get_caps,
.mac_port_config = mt7530_mac_config,
},
-@@ -3202,7 +3174,6 @@ const struct mt753x_info mt753x_table[]
+@@ -3392,7 +3364,6 @@ const struct mt753x_info mt753x_table[]
.sw_setup = mt7530_setup,
.phy_read = mt7530_phy_read,
.phy_write = mt7530_phy_write,
.mac_port_get_caps = mt7530_mac_port_get_caps,
.mac_port_config = mt7530_mac_config,
},
-@@ -3212,7 +3183,6 @@ const struct mt753x_info mt753x_table[]
+@@ -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,
.cpu_port_config = mt7531_cpu_port_config,
.mac_port_get_caps = mt7531_mac_port_get_caps,
.mac_port_config = mt7531_mac_config,
-@@ -3223,7 +3193,6 @@ const struct mt753x_info mt753x_table[]
+@@ -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,
.cpu_port_config = mt7988_cpu_port_config,
.mac_port_get_caps = mt7988_mac_port_get_caps,
.mac_port_config = mt7988_mac_config,
-@@ -3253,9 +3222,8 @@ mt7530_probe_common(struct mt7530_priv *
+@@ -3443,9 +3412,8 @@ mt7530_probe_common(struct mt7530_priv *
/* Sanity check if these required device operations are filled
* properly.
*/
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -722,8 +722,6 @@ struct mt753x_pcs {
+@@ -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
* @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
-@@ -739,7 +737,6 @@ struct mt753x_info {
+@@ -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);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2604,7 +2604,7 @@ static void mt7988_mac_port_get_caps(str
+@@ -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. */
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2600,8 +2600,6 @@ static void mt7531_mac_port_get_caps(str
+@@ -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)
{
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2683,17 +2683,6 @@ static bool mt753x_is_mac_port(u32 port)
+@@ -2872,17 +2872,6 @@ static bool mt753x_is_mac_port(u32 port)
}
static int
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
{
-@@ -2733,6 +2722,9 @@ mt753x_mac_config(struct dsa_switch *ds,
+@@ -2922,6 +2911,9 @@ mt753x_mac_config(struct dsa_switch *ds,
{
struct mt7530_priv *priv = ds->priv;
return priv->info->mac_port_config(ds, port, mode, state->interface);
}
-@@ -3193,7 +3185,6 @@ const struct mt753x_info mt753x_table[]
+@@ -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,
},
};
EXPORT_SYMBOL_GPL(mt753x_table);
-@@ -3221,8 +3212,7 @@ mt7530_probe_common(struct mt7530_priv *
+@@ -3411,8 +3402,7 @@ mt7530_probe_common(struct mt7530_priv *
* properly.
*/
if (!priv->info->sw_setup || !priv->info->phy_read ||
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2084,7 +2084,7 @@ mt7530_setup_irq(struct mt7530_priv *pri
+@@ -2259,7 +2259,7 @@ mt7530_setup_irq(struct mt7530_priv *pri
}
/* This register must be set for MT7530 to properly fire interrupts */
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2478,14 +2478,12 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -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);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2614,7 +2614,7 @@ static void mt7988_mac_port_get_caps(str
+@@ -2803,7 +2803,7 @@ static void mt7988_mac_port_get_caps(str
}
}
mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
{
-@@ -2624,22 +2624,14 @@ mt7530_mac_config(struct dsa_switch *ds,
+@@ -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);
val = mt7530_read(priv, MT7531_CLKGEN_CTRL);
val |= GP_CLK_EN;
val &= ~GP_MODE_MASK;
-@@ -2667,20 +2659,14 @@ static int mt7531_rgmii_setup(struct mt7
+@@ -2856,20 +2848,14 @@ static int mt7531_rgmii_setup(struct mt7
case PHY_INTERFACE_MODE_RGMII_ID:
break;
default:
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
{
-@@ -2688,42 +2674,21 @@ mt7531_mac_config(struct dsa_switch *ds,
+@@ -2877,42 +2863,21 @@ mt7531_mac_config(struct dsa_switch *ds,
struct phy_device *phydev;
struct dsa_port *dp;
}
static struct phylink_pcs *
-@@ -2752,17 +2717,11 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2941,17 +2906,11 @@ mt753x_phylink_mac_config(struct dsa_swi
u32 mcr_cur, mcr_new;
switch (port) {
if (priv->p5_intf_sel != P5_DISABLED)
priv->p5_interface = state->interface;
-@@ -2771,16 +2730,10 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2960,16 +2919,10 @@ mt753x_phylink_mac_config(struct dsa_swi
if (priv->p6_interface == state->interface)
break;
}
mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
-@@ -2863,7 +2816,6 @@ mt7531_cpu_port_config(struct dsa_switch
+@@ -3052,7 +3005,6 @@ mt7531_cpu_port_config(struct dsa_switch
struct mt7530_priv *priv = ds->priv;
phy_interface_t interface;
int speed;
switch (port) {
case 5:
-@@ -2888,9 +2840,8 @@ mt7531_cpu_port_config(struct dsa_switch
+@@ -3077,9 +3029,8 @@ mt7531_cpu_port_config(struct dsa_switch
else
speed = SPEED_1000;
mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -743,9 +743,9 @@ struct mt753x_info {
+@@ -753,9 +753,9 @@ struct mt753x_info {
void (*mac_port_validate)(struct dsa_switch *ds, int port,
phy_interface_t interface,
unsigned long *supported);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -995,18 +995,10 @@ mt753x_trap_frames(struct mt7530_priv *p
- MT753X_BPDU_CPU_ONLY);
+@@ -1170,18 +1170,10 @@ mt753x_trap_frames(struct mt7530_priv *p
+ MT753X_BPDU_CPU_ONLY);
}
-static int
/* Enable Mediatek header mode on the cpu port */
mt7530_write(priv, MT7530_PVC_P(port),
-@@ -1032,8 +1024,6 @@ mt753x_cpu_port_enable(struct dsa_switch
+@@ -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);
}
static int
-@@ -2288,8 +2278,6 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -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;
-
- mt753x_trap_frames(priv);
+ if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ)
+ mt7530_pll_setup(priv);
- /* Enable and reset MIB counters */
-@@ -2304,9 +2292,7 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -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)) {
} else {
mt7530_port_disable(ds, i);
-@@ -2410,9 +2396,7 @@ mt7531_setup_common(struct dsa_switch *d
+@@ -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)) {
} else {
mt7530_port_disable(ds, i);
-@@ -2501,10 +2485,6 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -2683,10 +2667,6 @@ mt7531_setup(struct dsa_switch *ds)
mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
MT7531_GPIO0_INTERRUPT);
- priv->p5_interface = PHY_INTERFACE_MODE_NA;
- priv->p6_interface = PHY_INTERFACE_MODE_NA;
-
- /* Enable PHY core PLL, since phy_device has not yet been created
- * provided for phy_[read,write]_mmd_indirect is called, we provide
- * our own mt7531_ind_mmd_phy_[read,write] to complete this
-@@ -2716,26 +2696,9 @@ mt753x_phylink_mac_config(struct dsa_swi
+ /* 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;
mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
mcr_new = mcr_cur;
mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
-@@ -2771,17 +2734,10 @@ static void mt753x_phylink_mac_link_up(s
+@@ -2960,17 +2923,10 @@ static void mt753x_phylink_mac_link_up(s
mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
mcr |= PMCR_FORCE_SPEED_1000;
break;
case SPEED_100:
-@@ -2799,6 +2755,7 @@ static void mt753x_phylink_mac_link_up(s
+@@ -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:
mcr |= PMCR_FORCE_EEE1G;
break;
case SPEED_100:
-@@ -2810,61 +2767,6 @@ static void mt753x_phylink_mac_link_up(s
+@@ -2999,61 +2956,6 @@ static void mt753x_phylink_mac_link_up(s
mt7530_set(priv, MT7530_PMCR_P(port), mcr);
}
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
struct phylink_config *config)
{
-@@ -3122,7 +3024,6 @@ const struct mt753x_info mt753x_table[]
+@@ -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,
.mac_port_get_caps = mt7531_mac_port_get_caps,
.mac_port_config = mt7531_mac_config,
},
-@@ -3132,7 +3033,6 @@ const struct mt753x_info mt753x_table[]
+@@ -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,
};
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
-@@ -331,13 +331,6 @@ enum mt7530_vlan_port_acc_frm {
+@@ -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 MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100)
#define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24)
-@@ -737,7 +730,6 @@ struct mt753x_info {
+@@ -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);
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,
-@@ -763,7 +755,6 @@ struct mt753x_info {
+@@ -773,7 +765,6 @@ 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_sgmii: Flag for distinguishing if port 5 of the MT7531 switch
* has got SGMII
-@@ -785,8 +776,6 @@ struct mt7530_priv {
+@@ -795,8 +786,6 @@ struct mt7530_priv {
const struct mt753x_info *info;
unsigned int id;
bool mcm;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2661,16 +2661,6 @@ mt7531_mac_config(struct dsa_switch *ds,
+@@ -2850,16 +2850,6 @@ mt7531_mac_config(struct dsa_switch *ds,
}
}
static struct phylink_pcs *
mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
phy_interface_t interface)
-@@ -2696,8 +2686,8 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2885,8 +2875,8 @@ mt753x_phylink_mac_config(struct dsa_swi
struct mt7530_priv *priv = ds->priv;
u32 mcr_cur, mcr_new;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2845,17 +2845,9 @@ static int
+@@ -3034,17 +3034,9 @@ static int
mt753x_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
if (ret)
return ret;
-@@ -2867,6 +2859,14 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3056,6 +3048,14 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -1047,7 +1047,6 @@ mt7530_port_enable(struct dsa_switch *ds
+@@ -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);
mutex_unlock(&priv->reg_mutex);
-@@ -1067,7 +1066,6 @@ mt7530_port_disable(struct dsa_switch *d
+@@ -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);
mutex_unlock(&priv->reg_mutex);
}
-@@ -2284,6 +2282,12 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2460,6 +2458,12 @@ mt7530_setup(struct dsa_switch *ds)
mt7530_mib_reset(ds);
for (i = 0; i < MT7530_NUM_PORTS; i++) {
/* Disable forwarding by default on all ports */
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
PCR_MATRIX_CLR);
-@@ -2386,6 +2390,12 @@ mt7531_setup_common(struct dsa_switch *d
+@@ -2565,6 +2569,12 @@ mt7531_setup_common(struct dsa_switch *d
UNU_FFP_MASK);
for (i = 0; i < MT7530_NUM_PORTS; i++) {
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2694,23 +2694,13 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2883,23 +2883,13 @@ mt753x_phylink_mac_config(struct dsa_swi
const struct phylink_link_state *state)
{
struct mt7530_priv *priv = ds->priv;
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
-@@ -324,8 +324,6 @@ enum mt7530_vlan_port_acc_frm {
+@@ -333,8 +333,6 @@ enum mt7530_vlan_port_acc_frm {
MT7531_FORCE_DPX | \
MT7531_FORCE_RX_FC | \
MT7531_FORCE_TX_FC)
+++ /dev/null
-From cfa7c85f92cd3814ad9748eb1ab25658c7f7cc67 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, 20 Mar 2024 23:45:30 +0300
-Subject: [PATCH 48/48] net: dsa: mt7530: fix improper frames on all 25MHz and
- 40MHz XTAL MT7530
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The MT7530 switch after reset initialises with a core clock frequency that
-works with a 25MHz XTAL connected to it. For 40MHz XTAL, the core clock
-frequency must be set to 500MHz.
-
-The mt7530_pll_setup() function is responsible of setting the core clock
-frequency. Currently, it runs on MT7530 with 25MHz and 40MHz XTAL. This
-causes MT7530 switch with 25MHz XTAL to egress and ingress frames
-improperly.
-
-Introduce a check to run it only on MT7530 with 40MHz XTAL.
-
-The core clock frequency is set by writing to a switch PHY's register.
-Access to the PHY's register is done via the MDIO bus the switch is also
-on. Therefore, it works only when the switch makes switch PHYs listen on
-the MDIO bus the switch is on. This is controlled either by the state of
-the ESW_P1_LED_1 pin after reset deassertion or modifying bit 5 of the
-modifiable trap register.
-
-When ESW_P1_LED_1 is pulled high, PHY indirect access is used. That means
-accessing PHY registers via the PHY indirect access control register of the
-switch.
-
-When ESW_P1_LED_1 is pulled low, PHY direct access is used. That means
-accessing PHY registers via the MDIO bus the switch is on.
-
-For MT7530 switch with 40MHz XTAL on a board with ESW_P1_LED_1 pulled high,
-the core clock frequency won't be set to 500MHz, causing the switch to
-egress and ingress frames improperly.
-
-Run mt7530_pll_setup() after PHY direct access is set on the modifiable
-trap register.
-
-With these two changes, all MT7530 switches with 25MHz and 40MHz, and
-P1_LED_1 pulled high or low, will egress and ingress frames properly.
-
-Link: https://github.com/BPI-SINOVOIP/BPI-R2-bsp/blob/4a5dd143f2172ec97a2872fa29c7c4cd520f45b5/linux-mt/drivers/net/ethernet/mediatek/gsw_mt7623.c#L1039
-Fixes: b8f126a8d543 ("net-next: dsa: add dsa support for Mediatek MT7530 switch")
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Link: https://lore.kernel.org/r/20240320-for-net-mt7530-fix-25mhz-xtal-with-direct-phy-access-v1-1-d92f605f1160@arinc9.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/dsa/mt7530.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2259,8 +2259,6 @@ mt7530_setup(struct dsa_switch *ds)
- SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
- SYS_CTRL_REG_RST);
-
-- mt7530_pll_setup(priv);
--
- /* Lower Tx driving for TRGMII path */
- for (i = 0; i < NUM_TRGMII_CTRL; i++)
- mt7530_write(priv, MT7530_TRGMII_TD_ODT(i),
-@@ -2276,6 +2274,9 @@ mt7530_setup(struct dsa_switch *ds)
- val |= MHWTRAP_MANUAL;
- mt7530_write(priv, MT7530_MHWTRAP, val);
-
-+ if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ)
-+ mt7530_pll_setup(priv);
-+
- mt753x_trap_frames(priv);
-
- /* Enable and reset MIB counters */
+++ /dev/null
-From ef972fc9f5743da589ce9546dd565d6c56e679b8 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, 8 Apr 2024 10:08:53 +0300
-Subject: [PATCH 1/2] net: dsa: mt7530: fix enabling EEE on MT7531 switch on
- all boards
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The commit 40b5d2f15c09 ("net: dsa: mt7530: Add support for EEE features")
-brought EEE support but did not enable EEE on MT7531 switch MACs. EEE is
-enabled on MT7531 switch MACs by pulling the LAN2LED0 pin low on the board
-(bootstrapping), unsetting the EEE_DIS bit on the trap register, or setting
-the internal EEE switch bit on the CORE_PLL_GROUP4 register. Thanks to
-SkyLake Huang (黃啟澤) from MediaTek for providing information on the
-internal EEE switch bit.
-
-There are existing boards that were not designed to pull the pin low.
-Because of that, the EEE status currently depends on the board design.
-
-The EEE_DIS bit on the trap pertains to the LAN2LED0 pin which is usually
-used to control an LED. Once the bit is unset, the pin will be low. That
-will make the active low LED turn on. The pin is controlled by the switch
-PHY. It seems that the PHY controls the pin in the way that it inverts the
-pin state. That means depending on the wiring of the LED connected to
-LAN2LED0 on the board, the LED may be on without an active link.
-
-To not cause this unwanted behaviour whilst enabling EEE on all boards, set
-the internal EEE switch bit on the CORE_PLL_GROUP4 register.
-
-My testing on MT7531 shows a certain amount of traffic loss when EEE is
-enabled. That said, I haven't come across a board that enables EEE. So
-enable EEE on the switch MACs but disable EEE advertisement on the switch
-PHYs. This way, we don't change the behaviour of the majority of the boards
-that have this switch. The mediatek-ge PHY driver already disables EEE
-advertisement on the switch PHYs but my testing shows that it is somehow
-enabled afterwards. Disabling EEE advertisement before the PHY driver
-initialises keeps it off.
-
-With this change, EEE can now be enabled using ethtool.
-
-Fixes: 40b5d2f15c09 ("net: dsa: mt7530: Add support for EEE features")
-Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 17 ++++++++++++-----
- drivers/net/dsa/mt7530.h | 1 +
- 2 files changed, 13 insertions(+), 5 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2496,18 +2496,25 @@ mt7531_setup(struct dsa_switch *ds)
- mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK,
- MT7531_GPIO0_INTERRUPT);
-
-- /* Enable PHY core PLL, since phy_device has not yet been created
-- * provided for phy_[read,write]_mmd_indirect is called, we provide
-- * our own mt7531_ind_mmd_phy_[read,write] to complete this
-- * function.
-+ /* 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
-+ * mt7531_ind_mmd_phy_[read,write] to complete this function.
- */
- val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR,
- MDIO_MMD_VEND2, CORE_PLL_GROUP4);
-- val |= MT7531_PHY_PLL_BYPASS_MODE;
-+ 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);
-
-+ /* Disable EEE advertisement on the switch PHYs. */
-+ for (i = MT753X_CTRL_PHY_ADDR;
-+ i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) {
-+ mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
-+ 0);
-+ }
-+
- mt7531_setup_common(ds);
-
- /* Setup VLAN ID 0 for VLAN-unaware bridges */
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -616,6 +616,7 @@ enum mt7531_clk_skew {
- #define RG_SYSPLL_DDSFBK_EN BIT(12)
- #define RG_SYSPLL_BIAS_EN BIT(11)
- #define RG_SYSPLL_BIAS_LPF_EN BIT(10)
-+#define MT7531_RG_SYSPLL_DMY2 BIT(6)
- #define MT7531_PHY_PLL_OFF BIT(5)
- #define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
-
+++ /dev/null
-From b7427d66cb3d6dca5165de5f7d80d59f08c2795b 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, 9 Apr 2024 18:01:14 +0300
-Subject: [PATCH 2/2] net: dsa: mt7530: trap link-local frames regardless of ST
- Port State
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-In Clause 5 of IEEE Std 802-2014, two sublayers of the data link layer
-(DLL) of the Open Systems Interconnection basic reference model (OSI/RM)
-are described; the medium access control (MAC) and logical link control
-(LLC) sublayers. The MAC sublayer is the one facing the physical layer.
-
-In 8.2 of IEEE Std 802.1Q-2022, the Bridge architecture is described. A
-Bridge component comprises a MAC Relay Entity for interconnecting the Ports
-of the Bridge, at least two Ports, and higher layer entities with at least
-a Spanning Tree Protocol Entity included.
-
-Each Bridge Port also functions as an end station and shall provide the MAC
-Service to an LLC Entity. Each instance of the MAC Service is provided to a
-distinct LLC Entity that supports protocol identification, multiplexing,
-and demultiplexing, for protocol data unit (PDU) transmission and reception
-by one or more higher layer entities.
-
-It is described in 8.13.9 of IEEE Std 802.1Q-2022 that in a Bridge, the LLC
-Entity associated with each Bridge Port is modeled as being directly
-connected to the attached Local Area Network (LAN).
-
-On the switch with CPU port architecture, CPU port functions as Management
-Port, and the Management Port functionality is provided by software which
-functions as an end station. Software is connected to an IEEE 802 LAN that
-is wholly contained within the system that incorporates the Bridge.
-Software provides access to the LLC Entity associated with each Bridge Port
-by the value of the source port field on the special tag on the frame
-received by software.
-
-We call frames that carry control information to determine the active
-topology and current extent of each Virtual Local Area Network (VLAN),
-i.e., spanning tree or Shortest Path Bridging (SPB) and Multiple VLAN
-Registration Protocol Data Units (MVRPDUs), and frames from other link
-constrained protocols, such as Extensible Authentication Protocol over LAN
-(EAPOL) and Link Layer Discovery Protocol (LLDP), link-local frames. They
-are not forwarded by a Bridge. Permanently configured entries in the
-filtering database (FDB) ensure that such frames are discarded by the
-Forwarding Process. In 8.6.3 of IEEE Std 802.1Q-2022, this is described in
-detail:
-
-Each of the reserved MAC addresses specified in Table 8-1
-(01-80-C2-00-00-[00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F]) shall be
-permanently configured in the FDB in C-VLAN components and ERs.
-
-Each of the reserved MAC addresses specified in Table 8-2
-(01-80-C2-00-00-[01,02,03,04,05,06,07,08,09,0A,0E]) shall be permanently
-configured in the FDB in S-VLAN components.
-
-Each of the reserved MAC addresses specified in Table 8-3
-(01-80-C2-00-00-[01,02,04,0E]) shall be permanently configured in the FDB
-in TPMR components.
-
-The FDB entries for reserved MAC addresses shall specify filtering for all
-Bridge Ports and all VIDs. Management shall not provide the capability to
-modify or remove entries for reserved MAC addresses.
-
-The addresses in Table 8-1, Table 8-2, and Table 8-3 determine the scope of
-propagation of PDUs within a Bridged Network, as follows:
-
- The Nearest Bridge group address (01-80-C2-00-00-0E) is an address that
- no conformant Two-Port MAC Relay (TPMR) component, Service VLAN (S-VLAN)
- component, Customer VLAN (C-VLAN) component, or MAC Bridge can forward.
- PDUs transmitted using this destination address, or any other addresses
- that appear in Table 8-1, Table 8-2, and Table 8-3
- (01-80-C2-00-00-[00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F]), can
- therefore travel no further than those stations that can be reached via a
- single individual LAN from the originating station.
-
- The Nearest non-TPMR Bridge group address (01-80-C2-00-00-03), is an
- address that no conformant S-VLAN component, C-VLAN component, or MAC
- Bridge can forward; however, this address is relayed by a TPMR component.
- PDUs using this destination address, or any of the other addresses that
- appear in both Table 8-1 and Table 8-2 but not in Table 8-3
- (01-80-C2-00-00-[00,03,05,06,07,08,09,0A,0B,0C,0D,0F]), will be relayed
- by any TPMRs but will propagate no further than the nearest S-VLAN
- component, C-VLAN component, or MAC Bridge.
-
- The Nearest Customer Bridge group address (01-80-C2-00-00-00) is an
- address that no conformant C-VLAN component, MAC Bridge can forward;
- however, it is relayed by TPMR components and S-VLAN components. PDUs
- using this destination address, or any of the other addresses that appear
- in Table 8-1 but not in either Table 8-2 or Table 8-3
- (01-80-C2-00-00-[00,0B,0C,0D,0F]), will be relayed by TPMR components and
- S-VLAN components but will propagate no further than the nearest C-VLAN
- component or MAC Bridge.
-
-Because the LLC Entity associated with each Bridge Port is provided via CPU
-port, we must not filter these frames but forward them to CPU port.
-
-In a Bridge, the transmission Port is majorly decided by ingress and egress
-rules, FDB, and spanning tree Port State functions of the Forwarding
-Process. For link-local frames, only CPU port should be designated as
-destination port in the FDB, and the other functions of the Forwarding
-Process must not interfere with the decision of the transmission Port. We
-call this process trapping frames to CPU port.
-
-Therefore, on the switch with CPU port architecture, link-local frames must
-be trapped to CPU port, and certain link-local frames received by a Port of
-a Bridge comprising a TPMR component or an S-VLAN component must be
-excluded from it.
-
-A Bridge of the switch with CPU port architecture cannot comprise a
-Two-Port MAC Relay (TPMR) component as a TPMR component supports only a
-subset of the functionality of a MAC Bridge. A Bridge comprising two Ports
-(Management Port doesn't count) of this architecture will either function
-as a standard MAC Bridge or a standard VLAN Bridge.
-
-Therefore, a Bridge of this architecture can only comprise S-VLAN
-components, C-VLAN components, or MAC Bridge components. Since there's no
-TPMR component, we don't need to relay PDUs using the destination addresses
-specified on the Nearest non-TPMR section, and the proportion of the
-Nearest Customer Bridge section where they must be relayed by TPMR
-components.
-
-One option to trap link-local frames to CPU port is to add static FDB
-entries with CPU port designated as destination port. However, because that
-Independent VLAN Learning (IVL) is being used on every VID, each entry only
-applies to a single VLAN Identifier (VID). For a Bridge comprising a MAC
-Bridge component or a C-VLAN component, there would have to be 16 times
-4096 entries. This switch intellectual property can only hold a maximum of
-2048 entries. Using this option, there also isn't a mechanism to prevent
-link-local frames from being discarded when the spanning tree Port State of
-the reception Port is discarding.
-
-The remaining option is to utilise the BPC, RGAC1, RGAC2, RGAC3, and RGAC4
-registers. Whilst this applies to every VID, it doesn't contain all of the
-reserved MAC addresses without affecting the remaining Standard Group MAC
-Addresses. The REV_UN frame tag utilised using the RGAC4 register covers
-the remaining 01-80-C2-00-00-[04,05,06,07,08,09,0A,0B,0C,0D,0F] destination
-addresses. It also includes the 01-80-C2-00-00-22 to 01-80-C2-00-00-FF
-destination addresses which may be relayed by MAC Bridges or VLAN Bridges.
-The latter option provides better but not complete conformance.
-
-This switch intellectual property also does not provide a mechanism to trap
-link-local frames with specific destination addresses to CPU port by
-Bridge, to conform to the filtering rules for the distinct Bridge
-components.
-
-Therefore, regardless of the type of the Bridge component, link-local
-frames with these destination addresses will be trapped to CPU port:
-
-01-80-C2-00-00-[00,01,02,03,0E]
-
-In a Bridge comprising a MAC Bridge component or a C-VLAN component:
-
- Link-local frames with these destination addresses won't be trapped to
- CPU port which won't conform to IEEE Std 802.1Q-2022:
-
- 01-80-C2-00-00-[04,05,06,07,08,09,0A,0B,0C,0D,0F]
-
-In a Bridge comprising an S-VLAN component:
-
- Link-local frames with these destination addresses will be trapped to CPU
- port which won't conform to IEEE Std 802.1Q-2022:
-
- 01-80-C2-00-00-00
-
- Link-local frames with these destination addresses won't be trapped to
- CPU port which won't conform to IEEE Std 802.1Q-2022:
-
- 01-80-C2-00-00-[04,05,06,07,08,09,0A]
-
-Currently on this switch intellectual property, if the spanning tree Port
-State of the reception Port is discarding, link-local frames will be
-discarded.
-
-To trap link-local frames regardless of the spanning tree Port State, make
-the switch regard them as Bridge Protocol Data Units (BPDUs). This switch
-intellectual property only lets the frames regarded as BPDUs bypass the
-spanning tree Port State function of the Forwarding Process.
-
-With this change, the only remaining interference is the ingress rules.
-When the reception Port has no PVID assigned on software, VLAN-untagged
-frames won't be allowed in. There doesn't seem to be a mechanism on the
-switch intellectual property to have link-local frames bypass this function
-of the Forwarding Process.
-
-Fixes: b8f126a8d543 ("net-next: dsa: add dsa support for Mediatek MT7530 switch")
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
----
- drivers/net/dsa/mt7530.c | 229 +++++++++++++++++++++++++++++++++------
- drivers/net/dsa/mt7530.h | 5 +
- 2 files changed, 200 insertions(+), 34 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -943,20 +943,173 @@ static void mt7530_setup_port5(struct ds
- mutex_unlock(&priv->reg_mutex);
- }
-
--/* On page 205, section "8.6.3 Frame filtering" of the active standard, IEEE Std
-- * 802.1Q™-2022, it is stated that frames with 01:80:C2:00:00:00-0F as MAC DA
-- * must only be propagated to C-VLAN and MAC Bridge components. That means
-- * VLAN-aware and VLAN-unaware bridges. On the switch designs with CPU ports,
-- * these frames are supposed to be processed by the CPU (software). So we make
-- * the switch only forward them to the CPU port. And if received from a CPU
-- * port, forward to a single port. The software is responsible of making the
-- * switch conform to the latter by setting a single port as destination port on
-- * the special tag.
-- *
-- * This switch intellectual property cannot conform to this part of the standard
-- * fully. Whilst the REV_UN frame tag covers the remaining :04-0D and :0F MAC
-- * DAs, it also includes :22-FF which the scope of propagation is not supposed
-- * to be restricted for these MAC DAs.
-+/* In Clause 5 of IEEE Std 802-2014, two sublayers of the data link layer (DLL)
-+ * of the Open Systems Interconnection basic reference model (OSI/RM) are
-+ * described; the medium access control (MAC) and logical link control (LLC)
-+ * sublayers. The MAC sublayer is the one facing the physical layer.
-+ *
-+ * In 8.2 of IEEE Std 802.1Q-2022, the Bridge architecture is described. A
-+ * Bridge component comprises a MAC Relay Entity for interconnecting the Ports
-+ * of the Bridge, at least two Ports, and higher layer entities with at least a
-+ * Spanning Tree Protocol Entity included.
-+ *
-+ * Each Bridge Port also functions as an end station and shall provide the MAC
-+ * Service to an LLC Entity. Each instance of the MAC Service is provided to a
-+ * distinct LLC Entity that supports protocol identification, multiplexing, and
-+ * demultiplexing, for protocol data unit (PDU) transmission and reception by
-+ * one or more higher layer entities.
-+ *
-+ * It is described in 8.13.9 of IEEE Std 802.1Q-2022 that in a Bridge, the LLC
-+ * Entity associated with each Bridge Port is modeled as being directly
-+ * connected to the attached Local Area Network (LAN).
-+ *
-+ * On the switch with CPU port architecture, CPU port functions as Management
-+ * Port, and the Management Port functionality is provided by software which
-+ * functions as an end station. Software is connected to an IEEE 802 LAN that is
-+ * wholly contained within the system that incorporates the Bridge. Software
-+ * provides access to the LLC Entity associated with each Bridge Port by the
-+ * value of the source port field on the special tag on the frame received by
-+ * software.
-+ *
-+ * We call frames that carry control information to determine the active
-+ * topology and current extent of each Virtual Local Area Network (VLAN), i.e.,
-+ * spanning tree or Shortest Path Bridging (SPB) and Multiple VLAN Registration
-+ * Protocol Data Units (MVRPDUs), and frames from other link constrained
-+ * protocols, such as Extensible Authentication Protocol over LAN (EAPOL) and
-+ * Link Layer Discovery Protocol (LLDP), link-local frames. They are not
-+ * forwarded by a Bridge. Permanently configured entries in the filtering
-+ * database (FDB) ensure that such frames are discarded by the Forwarding
-+ * Process. In 8.6.3 of IEEE Std 802.1Q-2022, this is described in detail:
-+ *
-+ * Each of the reserved MAC addresses specified in Table 8-1
-+ * (01-80-C2-00-00-[00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F]) shall be
-+ * permanently configured in the FDB in C-VLAN components and ERs.
-+ *
-+ * Each of the reserved MAC addresses specified in Table 8-2
-+ * (01-80-C2-00-00-[01,02,03,04,05,06,07,08,09,0A,0E]) shall be permanently
-+ * configured in the FDB in S-VLAN components.
-+ *
-+ * Each of the reserved MAC addresses specified in Table 8-3
-+ * (01-80-C2-00-00-[01,02,04,0E]) shall be permanently configured in the FDB in
-+ * TPMR components.
-+ *
-+ * The FDB entries for reserved MAC addresses shall specify filtering for all
-+ * Bridge Ports and all VIDs. Management shall not provide the capability to
-+ * modify or remove entries for reserved MAC addresses.
-+ *
-+ * The addresses in Table 8-1, Table 8-2, and Table 8-3 determine the scope of
-+ * propagation of PDUs within a Bridged Network, as follows:
-+ *
-+ * The Nearest Bridge group address (01-80-C2-00-00-0E) is an address that no
-+ * conformant Two-Port MAC Relay (TPMR) component, Service VLAN (S-VLAN)
-+ * component, Customer VLAN (C-VLAN) component, or MAC Bridge can forward.
-+ * PDUs transmitted using this destination address, or any other addresses
-+ * that appear in Table 8-1, Table 8-2, and Table 8-3
-+ * (01-80-C2-00-00-[00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F]), can
-+ * therefore travel no further than those stations that can be reached via a
-+ * single individual LAN from the originating station.
-+ *
-+ * The Nearest non-TPMR Bridge group address (01-80-C2-00-00-03), is an
-+ * address that no conformant S-VLAN component, C-VLAN component, or MAC
-+ * Bridge can forward; however, this address is relayed by a TPMR component.
-+ * PDUs using this destination address, or any of the other addresses that
-+ * appear in both Table 8-1 and Table 8-2 but not in Table 8-3
-+ * (01-80-C2-00-00-[00,03,05,06,07,08,09,0A,0B,0C,0D,0F]), will be relayed by
-+ * any TPMRs but will propagate no further than the nearest S-VLAN component,
-+ * C-VLAN component, or MAC Bridge.
-+ *
-+ * The Nearest Customer Bridge group address (01-80-C2-00-00-00) is an address
-+ * that no conformant C-VLAN component, MAC Bridge can forward; however, it is
-+ * relayed by TPMR components and S-VLAN components. PDUs using this
-+ * destination address, or any of the other addresses that appear in Table 8-1
-+ * but not in either Table 8-2 or Table 8-3 (01-80-C2-00-00-[00,0B,0C,0D,0F]),
-+ * will be relayed by TPMR components and S-VLAN components but will propagate
-+ * no further than the nearest C-VLAN component or MAC Bridge.
-+ *
-+ * Because the LLC Entity associated with each Bridge Port is provided via CPU
-+ * port, we must not filter these frames but forward them to CPU port.
-+ *
-+ * In a Bridge, the transmission Port is majorly decided by ingress and egress
-+ * rules, FDB, and spanning tree Port State functions of the Forwarding Process.
-+ * For link-local frames, only CPU port should be designated as destination port
-+ * in the FDB, and the other functions of the Forwarding Process must not
-+ * interfere with the decision of the transmission Port. We call this process
-+ * trapping frames to CPU port.
-+ *
-+ * Therefore, on the switch with CPU port architecture, link-local frames must
-+ * be trapped to CPU port, and certain link-local frames received by a Port of a
-+ * Bridge comprising a TPMR component or an S-VLAN component must be excluded
-+ * from it.
-+ *
-+ * A Bridge of the switch with CPU port architecture cannot comprise a Two-Port
-+ * MAC Relay (TPMR) component as a TPMR component supports only a subset of the
-+ * functionality of a MAC Bridge. A Bridge comprising two Ports (Management Port
-+ * doesn't count) of this architecture will either function as a standard MAC
-+ * Bridge or a standard VLAN Bridge.
-+ *
-+ * Therefore, a Bridge of this architecture can only comprise S-VLAN components,
-+ * C-VLAN components, or MAC Bridge components. Since there's no TPMR component,
-+ * we don't need to relay PDUs using the destination addresses specified on the
-+ * Nearest non-TPMR section, and the proportion of the Nearest Customer Bridge
-+ * section where they must be relayed by TPMR components.
-+ *
-+ * One option to trap link-local frames to CPU port is to add static FDB entries
-+ * with CPU port designated as destination port. However, because that
-+ * Independent VLAN Learning (IVL) is being used on every VID, each entry only
-+ * applies to a single VLAN Identifier (VID). For a Bridge comprising a MAC
-+ * Bridge component or a C-VLAN component, there would have to be 16 times 4096
-+ * entries. This switch intellectual property can only hold a maximum of 2048
-+ * entries. Using this option, there also isn't a mechanism to prevent
-+ * link-local frames from being discarded when the spanning tree Port State of
-+ * the reception Port is discarding.
-+ *
-+ * The remaining option is to utilise the BPC, RGAC1, RGAC2, RGAC3, and RGAC4
-+ * registers. Whilst this applies to every VID, it doesn't contain all of the
-+ * reserved MAC addresses without affecting the remaining Standard Group MAC
-+ * Addresses. The REV_UN frame tag utilised using the RGAC4 register covers the
-+ * remaining 01-80-C2-00-00-[04,05,06,07,08,09,0A,0B,0C,0D,0F] destination
-+ * addresses. It also includes the 01-80-C2-00-00-22 to 01-80-C2-00-00-FF
-+ * destination addresses which may be relayed by MAC Bridges or VLAN Bridges.
-+ * The latter option provides better but not complete conformance.
-+ *
-+ * This switch intellectual property also does not provide a mechanism to trap
-+ * link-local frames with specific destination addresses to CPU port by Bridge,
-+ * to conform to the filtering rules for the distinct Bridge components.
-+ *
-+ * Therefore, regardless of the type of the Bridge component, link-local frames
-+ * with these destination addresses will be trapped to CPU port:
-+ *
-+ * 01-80-C2-00-00-[00,01,02,03,0E]
-+ *
-+ * In a Bridge comprising a MAC Bridge component or a C-VLAN component:
-+ *
-+ * Link-local frames with these destination addresses won't be trapped to CPU
-+ * port which won't conform to IEEE Std 802.1Q-2022:
-+ *
-+ * 01-80-C2-00-00-[04,05,06,07,08,09,0A,0B,0C,0D,0F]
-+ *
-+ * In a Bridge comprising an S-VLAN component:
-+ *
-+ * Link-local frames with these destination addresses will be trapped to CPU
-+ * port which won't conform to IEEE Std 802.1Q-2022:
-+ *
-+ * 01-80-C2-00-00-00
-+ *
-+ * Link-local frames with these destination addresses won't be trapped to CPU
-+ * port which won't conform to IEEE Std 802.1Q-2022:
-+ *
-+ * 01-80-C2-00-00-[04,05,06,07,08,09,0A]
-+ *
-+ * To trap link-local frames to CPU port as conformant as this switch
-+ * intellectual property can allow, link-local frames are made to be regarded as
-+ * Bridge Protocol Data Units (BPDUs). This is because this switch intellectual
-+ * property only lets the frames regarded as BPDUs bypass the spanning tree Port
-+ * State function of the Forwarding Process.
-+ *
-+ * The only remaining interference is the ingress rules. When the reception Port
-+ * has no PVID assigned on software, VLAN-untagged frames won't be allowed in.
-+ * There doesn't seem to be a mechanism on the switch intellectual property to
-+ * have link-local frames bypass this function of the Forwarding Process.
- */
- static void
- mt753x_trap_frames(struct mt7530_priv *priv)
-@@ -964,35 +1117,43 @@ mt753x_trap_frames(struct mt7530_priv *p
- /* Trap 802.1X PAE frames and BPDUs to the CPU port(s) and egress them
- * VLAN-untagged.
- */
-- mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_EG_TAG_MASK |
-- MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK |
-- MT753X_BPDU_PORT_FW_MASK,
-- 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);
-+ 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);
-
- /* 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_EG_TAG_MASK |
-- MT753X_R02_PORT_FW_MASK | MT753X_R01_EG_TAG_MASK |
-- MT753X_R01_PORT_FW_MASK,
-- MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) |
-- MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_BPDU_CPU_ONLY);
-+ 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);
-
- /* 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_EG_TAG_MASK |
-- MT753X_R0E_PORT_FW_MASK | MT753X_R03_EG_TAG_MASK |
-- MT753X_R03_PORT_FW_MASK,
-- MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) |
-- MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
-- MT753X_BPDU_CPU_ONLY);
-+ 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);
- }
-
- static void
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -65,6 +65,7 @@ enum mt753x_id {
-
- /* Registers 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)
-@@ -75,20 +76,24 @@ enum mt753x_id {
-
- /* Register for :01 and :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)
-
- /* Register for :03 and :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)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2841,28 +2841,34 @@ mt7531_mac_config(struct dsa_switch *ds,
+@@ -2861,28 +2861,34 @@ mt7531_mac_config(struct dsa_switch *ds,
}
static struct phylink_pcs *
if ((port == 5 || port == 6) && priv->info->mac_port_config)
priv->info->mac_port_config(ds, port, mode, state->interface);
-@@ -2872,23 +2878,25 @@ mt753x_phylink_mac_config(struct dsa_swi
+@@ -2892,23 +2898,25 @@ mt753x_phylink_mac_config(struct dsa_swi
mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
}
u32 mcr;
mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
-@@ -2923,7 +2931,7 @@ static void mt753x_phylink_mac_link_up(s
+@@ -2943,7 +2951,7 @@ static void mt753x_phylink_mac_link_up(s
}
}
}
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
-@@ -3148,16 +3156,19 @@ const struct dsa_switch_ops mt7530_switc
+@@ -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,
const struct mt753x_info mt753x_table[] = {
[ID_MT7621] = {
.id = ID_MT7621,
-@@ -3227,6 +3238,7 @@ mt7530_probe_common(struct mt7530_priv *
+@@ -3248,6 +3259,7 @@ mt7530_probe_common(struct mt7530_priv *
priv->dev = dev;
priv->ds->priv = priv;
priv->ds->ops = &mt7530_switch_ops;
+++ /dev/null
-From d4097ddef078a113643a6dcde01e99741f852adb 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:39 +0300
-Subject: [PATCH 2/5] net: dsa: mt7530: fix mirroring frames received on local
- port
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This switch intellectual property provides a bit on the ARL global control
-register which controls allowing mirroring frames which are received on the
-local port (monitor port). This bit is unset after reset.
-
-This ability must be enabled to fully support the port mirroring feature on
-this switch intellectual property.
-
-Therefore, this patch fixes the traffic not being reflected on a port,
-which would be configured like below:
-
- tc qdisc add dev swp0 clsact
-
- tc filter add dev swp0 ingress matchall skip_sw \
- action mirred egress mirror dev swp0
-
-As a side note, this configuration provides the hairpinning feature for a
-single port.
-
-Fixes: 37feab6076aa ("net: dsa: mt7530: add support for port mirroring")
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/dsa/mt7530.c | 6 ++++++
- drivers/net/dsa/mt7530.h | 4 ++++
- 2 files changed, 10 insertions(+)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2471,6 +2471,9 @@ mt7530_setup(struct dsa_switch *ds)
- PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
- }
-
-+ /* Allow mirroring frames received on the local port (monitor port). */
-+ mt7530_set(priv, MT753X_AGC, LOCAL_EN);
-+
- /* Setup VLAN ID 0 for VLAN-unaware bridges */
- ret = mt7530_setup_vlan0(priv);
- if (ret)
-@@ -2582,6 +2585,9 @@ mt7531_setup_common(struct dsa_switch *d
- PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
- }
-
-+ /* Allow mirroring frames received on the local port (monitor port). */
-+ mt7530_set(priv, MT753X_AGC, LOCAL_EN);
-+
- /* Flush the FDB table */
- ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
- if (ret < 0)
---- a/drivers/net/dsa/mt7530.h
-+++ b/drivers/net/dsa/mt7530.h
-@@ -32,6 +32,10 @@ enum mt753x_id {
- #define SYSC_REG_RSTCTRL 0x34
- #define RESET_MCM BIT(2)
-
-+/* Register for ARL global control */
-+#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)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -1876,14 +1876,16 @@ mt7530_port_vlan_del(struct dsa_switch *
+@@ -1890,14 +1890,16 @@ mt7530_port_vlan_del(struct dsa_switch *
static int mt753x_mirror_port_get(unsigned int id, u32 val)
{
err:
if (ret < 0)
dev_err(&bus->dev,
-@@ -2670,16 +2678,19 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -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.
*/
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -889,7 +889,7 @@ static void mt7530_setup_port5(struct ds
+@@ -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 */
break;
case P5_INTF_SEL_GMAC5:
/* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */
-@@ -2435,8 +2435,8 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -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.
*/
/* Disable forwarding by default on all ports */
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
-@@ -2546,8 +2546,8 @@ mt7531_setup_common(struct dsa_switch *d
+@@ -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.
*/
/* Disable forwarding by default on all ports */
mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
-@@ -2630,7 +2630,7 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -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++)
/* Reset the switch through internal reset */
mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
-@@ -2872,7 +2872,7 @@ mt753x_phylink_mac_config(struct phylink
+@@ -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))
}
static void mt753x_phylink_mac_link_down(struct phylink_config *config,
-@@ -2882,7 +2882,7 @@ static void mt753x_phylink_mac_link_down
+@@ -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;
}
static void mt753x_phylink_mac_link_up(struct phylink_config *config,
-@@ -2896,7 +2896,7 @@ static void mt753x_phylink_mac_link_up(s
+@@ -2910,7 +2910,7 @@ static void mt753x_phylink_mac_link_up(s
struct mt7530_priv *priv = dp->ds->priv;
u32 mcr;
switch (speed) {
case SPEED_1000:
-@@ -2911,9 +2911,9 @@ static void mt753x_phylink_mac_link_up(s
+@@ -2925,9 +2925,9 @@ static void mt753x_phylink_mac_link_up(s
if (duplex == DUPLEX_FULL) {
mcr |= PMCR_FORCE_FDX;
if (tx_pause)
}
if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
-@@ -2928,7 +2928,7 @@ static void mt753x_phylink_mac_link_up(s
+@@ -2942,7 +2942,7 @@ static void mt753x_phylink_mac_link_up(s
}
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -850,19 +850,15 @@ mt7530_set_ageing_time(struct dsa_switch
+@@ -864,19 +864,15 @@ mt7530_set_ageing_time(struct dsa_switch
return 0;
}
}
}
-@@ -879,23 +875,23 @@ static void mt7530_setup_port5(struct ds
+@@ -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;
break;
}
-@@ -923,8 +919,8 @@ static void mt7530_setup_port5(struct ds
+@@ -937,8 +933,8 @@ static void mt7530_setup_port5(struct ds
mt7530_write(priv, MT7530_MHWTRAP, val);
mutex_unlock(&priv->reg_mutex);
}
-@@ -2467,13 +2463,11 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2481,13 +2477,11 @@ mt7530_setup(struct dsa_switch *ds)
if (ret)
return ret;
*/
for_each_child_of_node(dn, mac_np) {
if (!of_device_is_compatible(mac_np,
-@@ -2497,17 +2491,16 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2511,17 +2505,16 @@ mt7530_setup(struct dsa_switch *ds)
}
id = of_mdio_parse_addr(ds->dev, phy_node);
if (id == 0)
mt7530_setup_port5(ds, interface);
}
-@@ -2645,9 +2638,6 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -2659,9 +2652,6 @@ mt7531_setup(struct dsa_switch *ds)
MT7531_EXT_P_MDIO_12);
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -1100,42 +1100,34 @@ mt753x_trap_frames(struct mt7530_priv *p
+@@ -1114,42 +1114,34 @@ mt753x_trap_frames(struct mt7530_priv *p
* VLAN-untagged.
*/
mt7530_rmw(priv, MT753X_BPC,
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -1140,7 +1140,7 @@ mt753x_cpu_port_enable(struct dsa_switch
+@@ -1154,7 +1154,7 @@ mt753x_cpu_port_enable(struct dsa_switch
PORT_SPEC_TAG);
/* Enable flooding on the CPU 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 and the switch on
-@@ -1304,15 +1304,15 @@ mt7530_port_bridge_flags(struct dsa_swit
+ /* 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)
flags.val & BR_BCAST_FLOOD ? BC_FFP(BIT(port)) : 0);
return 0;
-@@ -1848,20 +1848,6 @@ mt7530_port_vlan_del(struct dsa_switch *
+@@ -1862,20 +1862,6 @@ mt7530_port_vlan_del(struct dsa_switch *
return 0;
}
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)
-@@ -1877,14 +1863,14 @@ static int mt753x_port_mirror_add(struct
+@@ -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 */
mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val);
val = mt7530_read(priv, MT7530_PCR_P(port));
-@@ -2524,7 +2510,7 @@ mt7531_setup_common(struct dsa_switch *d
+@@ -2538,7 +2524,7 @@ mt7531_setup_common(struct dsa_switch *d
mt7530_mib_reset(ds);
/* Disable flooding on all ports */
UNU_FFP_MASK);
for (i = 0; i < MT7530_NUM_PORTS; i++) {
-@@ -3086,10 +3072,12 @@ mt753x_conduit_state_change(struct dsa_s
+@@ -3100,10 +3086,12 @@ mt753x_conduit_state_change(struct dsa_s
else
priv->active_cpu_ports &= ~mask;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -403,23 +403,23 @@ mt7530_setup_port6(struct dsa_switch *ds
+@@ -417,23 +417,23 @@ mt7530_setup_port6(struct dsa_switch *ds
mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1));
ncpo1 = 0x1400;
}
-@@ -442,19 +442,20 @@ mt7530_setup_port6(struct dsa_switch *ds
+@@ -456,19 +456,20 @@ mt7530_setup_port6(struct dsa_switch *ds
static void
mt7531_pll_setup(struct mt7530_priv *priv)
{
/* Step 1 : Disable MT7531 COREPLL */
val = mt7530_read(priv, MT7531_PLLGP_EN);
-@@ -483,13 +484,13 @@ mt7531_pll_setup(struct mt7530_priv *pri
+@@ -497,13 +498,13 @@ mt7531_pll_setup(struct mt7530_priv *pri
usleep_range(25, 35);
switch (xtal) {
val = mt7530_read(priv, MT7531_PLLGP_CR0);
val &= ~RG_COREPLL_SDM_PCW_M;
val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
-@@ -870,20 +871,20 @@ static void mt7530_setup_port5(struct ds
+@@ -884,20 +885,20 @@ static void mt7530_setup_port5(struct ds
mutex_lock(&priv->reg_mutex);
/* Setup the MAC by default for the cpu port */
mt7530_write(priv, MT753X_PMCR_P(5), 0x56300);
-@@ -891,13 +892,13 @@ static void mt7530_setup_port5(struct ds
+@@ -905,13 +906,13 @@ static void mt7530_setup_port5(struct ds
/* GMAC5: P5 -> SoC MAC or external PHY */
default:
/* P5 RGMII RX Clock Control: delay setting for 1000M */
mt7530_write(priv, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN);
-@@ -917,7 +918,7 @@ static void mt7530_setup_port5(struct ds
+@@ -931,7 +932,7 @@ static void mt7530_setup_port5(struct ds
P5_IO_CLK_DRV(1) | P5_IO_DATA_DRV(1));
}
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));
-@@ -2356,7 +2357,7 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2370,7 +2371,7 @@ mt7530_setup(struct dsa_switch *ds)
}
/* Waiting for MT7530 got to stable */
ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0,
20, 1000000);
if (ret < 0) {
-@@ -2371,7 +2372,7 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2385,7 +2386,7 @@ mt7530_setup(struct dsa_switch *ds)
return -ENODEV;
}
dev_err(priv->dev,
"MT7530 with a 20MHz XTAL is not supported!\n");
return -EINVAL;
-@@ -2392,12 +2393,12 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2406,12 +2407,12 @@ mt7530_setup(struct dsa_switch *ds)
RD_TAP_MASK, RD_TAP(16));
/* Enable port 6 */
mt7530_pll_setup(priv);
mt753x_trap_frames(priv);
-@@ -2577,7 +2578,7 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -2591,7 +2592,7 @@ mt7531_setup(struct dsa_switch *ds)
}
/* Waiting for MT7530 got to stable */
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -873,8 +873,7 @@ static void mt7530_setup_port5(struct ds
+@@ -887,8 +887,7 @@ static void mt7530_setup_port5(struct ds
val = mt7530_read(priv, MT753X_MTRAP);
switch (priv->p5_mode) {
/* MUX_PHY_P0: P0 -> P5 -> SoC MAC */
-@@ -884,15 +883,13 @@ static void mt7530_setup_port5(struct ds
+@@ -898,15 +897,13 @@ static void mt7530_setup_port5(struct ds
/* MUX_PHY_P4: P4 -> P5 -> SoC MAC */
case MUX_PHY_P4:
break;
}
-@@ -1186,6 +1183,14 @@ mt7530_port_enable(struct dsa_switch *ds
+@@ -1200,6 +1197,14 @@ mt7530_port_enable(struct dsa_switch *ds
mutex_unlock(&priv->reg_mutex);
return 0;
}
-@@ -1204,6 +1209,14 @@ mt7530_port_disable(struct dsa_switch *d
+@@ -1218,6 +1223,14 @@ mt7530_port_disable(struct dsa_switch *d
PCR_MATRIX_CLR);
mutex_unlock(&priv->reg_mutex);
}
static int
-@@ -2392,11 +2405,11 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2406,11 +2419,11 @@ mt7530_setup(struct dsa_switch *ds)
mt7530_rmw(priv, MT7530_TRGMII_RD(i),
RD_TAP_MASK, RD_TAP(16));
if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ)
mt7530_pll_setup(priv);
-@@ -2479,8 +2492,11 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2493,8 +2506,11 @@ mt7530_setup(struct dsa_switch *ds)
break;
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2658,7 +2658,9 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -2672,7 +2672,9 @@ mt7531_setup(struct dsa_switch *ds)
0);
}
/* Setup VLAN ID 0 for VLAN-unaware bridges */
ret = mt7530_setup_vlan0(priv);
-@@ -3017,6 +3019,8 @@ mt753x_setup(struct dsa_switch *ds)
+@@ -3031,6 +3033,8 @@ mt753x_setup(struct dsa_switch *ds)
ret = mt7530_setup_mdio(priv);
if (ret && priv->irq)
mt7530_free_irq_common(priv);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2676,6 +2676,8 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -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)
{
switch (port) {
/* Ports which are connected to switch PHYs. There is no MII pinout. */
case 0 ... 4:
-@@ -2707,6 +2709,8 @@ static void mt7531_mac_port_get_caps(str
+@@ -2721,6 +2723,8 @@ static void mt7531_mac_port_get_caps(str
{
struct mt7530_priv *priv = ds->priv;
switch (port) {
/* Ports which are connected to switch PHYs. There is no MII pinout. */
case 0 ... 4:
-@@ -2746,14 +2750,17 @@ static void mt7988_mac_port_get_caps(str
+@@ -2760,14 +2764,17 @@ static void mt7988_mac_port_get_caps(str
case 0 ... 3:
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
config->supported_interfaces);
}
}
-@@ -2923,9 +2930,7 @@ static void mt753x_phylink_get_caps(stru
+@@ -2937,9 +2944,7 @@ static void mt753x_phylink_get_caps(stru
{
struct mt7530_priv *priv = ds->priv;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3220,13 +3220,6 @@ mt7530_probe_common(struct mt7530_priv *
+@@ -3235,13 +3235,6 @@ mt7530_probe_common(struct mt7530_priv *
if (!priv->info)
return -EINVAL;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -3048,10 +3048,10 @@ static int mt753x_get_mac_eee(struct dsa
+@@ -3062,10 +3062,10 @@ static int mt753x_get_mac_eee(struct dsa
struct ethtool_eee *e)
{
struct mt7530_priv *priv = ds->priv;
return 0;
}
-@@ -3065,11 +3065,11 @@ static int mt753x_set_mac_eee(struct dsa
+@@ -3079,11 +3079,11 @@ static int mt753x_set_mac_eee(struct dsa
if (e->tx_lpi_timer > 0xFFF)
return -EINVAL;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -1404,7 +1404,7 @@ mt7530_port_set_vlan_unaware(struct dsa_
+@@ -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);
if (dsa_is_user_port(ds, i) &&
dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
all_user_ports_removed = false;
-@@ -2419,7 +2419,7 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -2433,7 +2433,7 @@ mt7530_setup(struct dsa_switch *ds)
/* Enable and reset MIB counters */
mt7530_mib_reset(ds);
/* Clear link settings and enable force mode to force link down
* on all ports until they're enabled later.
*/
-@@ -2530,7 +2530,7 @@ mt7531_setup_common(struct dsa_switch *d
+@@ -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);
/* Clear link settings and enable force mode to force link down
* on all ports until they're enabled later.
*/
-@@ -2617,7 +2617,7 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -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 */
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2776,7 +2776,7 @@ mt7530_mac_config(struct dsa_switch *ds,
+@@ -2790,7 +2790,7 @@ mt7530_mac_config(struct dsa_switch *ds,
mt7530_setup_port6(priv->ds, interface);
}
phy_interface_t interface,
struct phy_device *phydev)
{
-@@ -2827,7 +2827,7 @@ mt7531_mac_config(struct dsa_switch *ds,
+@@ -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;
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2626,7 +2626,10 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -2640,7 +2640,10 @@ mt7531_setup(struct dsa_switch *ds)
if (!priv->p5_sgmii) {
mt7531_pll_setup(priv);
} else {
--- /dev/null
+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);
--- /dev/null
+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);
--- /dev/null
+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");
--- /dev/null
+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;
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
-@@ -72,9 +72,9 @@ config SFP
- comment "MII PHY device drivers"
+@@ -77,9 +77,9 @@ config AIR_EN8811H_PHY
+ Currently supports the Airoha EN8811H PHY.
config AMD_PHY
- tristate "AMD PHYs"
--- /dev/null
+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
+@@ -47,6 +47,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/filelock.h>
+ #include <linux/namei.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
+@@ -38,14 +38,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
--- /dev/null
+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
+@@ -32,6 +32,8 @@
+ #include <linux/sprintf.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>
+@@ -57,34 +59,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
--- /dev/null
+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
+@@ -37,6 +37,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;
+@@ -206,28 +240,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--;
--- /dev/null
+From: Richard Gobert <richardbgobert@gmail.com>
+Date: Tue, 30 Apr 2024 16:35:54 +0200
+Subject: [PATCH] net: gro: fix udp bad offset in socket lookup by adding
+ {inner_}network_offset to napi_gro_cb
+
+Commits a602456 ("udp: Add GRO functions to UDP socket") and 57c67ff ("udp:
+additional GRO support") introduce incorrect usage of {ip,ipv6}_hdr in the
+complete phase of gro. The functions always return skb->network_header,
+which in the case of encapsulated packets at the gro complete phase, is
+always set to the innermost L3 of the packet. That means that calling
+{ip,ipv6}_hdr for skbs which completed the GRO receive phase (both in
+gro_list and *_gro_complete) when parsing an encapsulated packet's _outer_
+L3/L4 may return an unexpected value.
+
+This incorrect usage leads to a bug in GRO's UDP socket lookup.
+udp{4,6}_lib_lookup_skb functions use ip_hdr/ipv6_hdr respectively. These
+*_hdr functions return network_header which will point to the innermost L3,
+resulting in the wrong offset being used in __udp{4,6}_lib_lookup with
+encapsulated packets.
+
+This patch adds network_offset and inner_network_offset to napi_gro_cb, and
+makes sure both are set correctly.
+
+To fix the issue, network_offsets union is used inside napi_gro_cb, in
+which both the outer and the inner network offsets are saved.
+
+Reproduction example:
+
+Endpoint configuration example (fou + local address bind)
+
+ # ip fou add port 6666 ipproto 4
+ # ip link add name tun1 type ipip remote 2.2.2.1 local 2.2.2.2 encap fou encap-dport 5555 encap-sport 6666 mode ipip
+ # ip link set tun1 up
+ # ip a add 1.1.1.2/24 dev tun1
+
+Netperf TCP_STREAM result on net-next before patch is applied:
+
+net-next main, GRO enabled:
+ $ netperf -H 1.1.1.2 -t TCP_STREAM -l 5
+ Recv Send Send
+ Socket Socket Message Elapsed
+ Size Size Size Time Throughput
+ bytes bytes bytes secs. 10^6bits/sec
+
+ 131072 16384 16384 5.28 2.37
+
+net-next main, GRO disabled:
+ $ netperf -H 1.1.1.2 -t TCP_STREAM -l 5
+ Recv Send Send
+ Socket Socket Message Elapsed
+ Size Size Size Time Throughput
+ bytes bytes bytes secs. 10^6bits/sec
+
+ 131072 16384 16384 5.01 2745.06
+
+patch applied, GRO enabled:
+ $ netperf -H 1.1.1.2 -t TCP_STREAM -l 5
+ Recv Send Send
+ Socket Socket Message Elapsed
+ Size Size Size Time Throughput
+ bytes bytes bytes secs. 10^6bits/sec
+
+ 131072 16384 16384 5.01 2877.38
+
+Fixes: a6024562ffd7 ("udp: Add GRO functions to UDP socket")
+Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+
+--- a/include/net/gro.h
++++ b/include/net/gro.h
+@@ -86,6 +86,15 @@ struct napi_gro_cb {
+
+ /* used to support CHECKSUM_COMPLETE for tunneling protocols */
+ __wsum csum;
++
++ /* L3 offsets */
++ union {
++ struct {
++ u16 network_offset;
++ u16 inner_network_offset;
++ };
++ u16 network_offsets[2];
++ };
+ };
+
+ #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
+--- a/net/8021q/vlan_core.c
++++ b/net/8021q/vlan_core.c
+@@ -478,6 +478,8 @@ static struct sk_buff *vlan_gro_receive(
+ if (unlikely(!vhdr))
+ goto out;
+
++ NAPI_GRO_CB(skb)->network_offsets[NAPI_GRO_CB(skb)->encap_mark] = hlen;
++
+ type = vhdr->h_vlan_encapsulated_proto;
+
+ ptype = gro_find_receive_by_type(type);
+--- a/net/core/gro.c
++++ b/net/core/gro.c
+@@ -373,6 +373,7 @@ static inline void skb_gro_reset_offset(
+ const struct skb_shared_info *pinfo = skb_shinfo(skb);
+ const skb_frag_t *frag0 = &pinfo->frags[0];
+
++ NAPI_GRO_CB(skb)->network_offset = 0;
+ NAPI_GRO_CB(skb)->data_offset = 0;
+ NAPI_GRO_CB(skb)->frag0 = NULL;
+ NAPI_GRO_CB(skb)->frag0_len = 0;
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -1571,6 +1571,7 @@ struct sk_buff *inet_gro_receive(struct
+ /* The above will be needed by the transport layer if there is one
+ * immediately following this IP hdr.
+ */
++ NAPI_GRO_CB(skb)->inner_network_offset = off;
+
+ /* Note : No need to call skb_gro_postpull_rcsum() here,
+ * as we already checked checksum over ipv4 header was 0
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -534,7 +534,8 @@ static inline struct sock *__udp4_lib_lo
+ struct sock *udp4_lib_lookup_skb(const struct sk_buff *skb,
+ __be16 sport, __be16 dport)
+ {
+- const struct iphdr *iph = ip_hdr(skb);
++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation];
++ const struct iphdr *iph = (struct iphdr *)(skb->data + offset);
+ struct net *net = dev_net(skb->dev);
+ int iif, sdif;
+
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -718,7 +718,8 @@ EXPORT_SYMBOL(udp_gro_complete);
+
+ INDIRECT_CALLABLE_SCOPE int udp4_gro_complete(struct sk_buff *skb, int nhoff)
+ {
+- const struct iphdr *iph = ip_hdr(skb);
++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation];
++ const struct iphdr *iph = (struct iphdr *)(skb->data + offset);
+ struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
+
+ /* do fraglist only if there is no outer UDP encap (or we already processed it) */
+--- a/net/ipv6/ip6_offload.c
++++ b/net/ipv6/ip6_offload.c
+@@ -240,6 +240,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *
+ goto out;
+
+ skb_set_network_header(skb, off);
++ NAPI_GRO_CB(skb)->inner_network_offset = off;
+
+ flush += ntohs(iph->payload_len) != skb->len - hlen;
+
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -275,7 +275,8 @@ static struct sock *__udp6_lib_lookup_sk
+ struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb,
+ __be16 sport, __be16 dport)
+ {
+- const struct ipv6hdr *iph = ipv6_hdr(skb);
++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation];
++ const struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + offset);
+ struct net *net = dev_net(skb->dev);
+ int iif, sdif;
+
+--- a/net/ipv6/udp_offload.c
++++ b/net/ipv6/udp_offload.c
+@@ -164,7 +164,8 @@ flush:
+
+ INDIRECT_CALLABLE_SCOPE int udp6_gro_complete(struct sk_buff *skb, int nhoff)
+ {
+- const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation];
++ const struct ipv6hdr *ipv6h = (struct ipv6hdr *)(skb->data + offset);
+ struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
+
+ /* do fraglist only if there is no outer UDP encap (or we already processed it) */
--- /dev/null
+From: Richard Gobert <richardbgobert@gmail.com>
+Date: Tue, 30 Apr 2024 16:35:55 +0200
+Subject: [PATCH] net: gro: add flush check in udp_gro_receive_segment
+
+GRO-GSO path is supposed to be transparent and as such L3 flush checks are
+relevant to all UDP flows merging in GRO. This patch uses the same logic
+and code from tcp_gro_receive, terminating merge if flush is non zero.
+
+Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.")
+Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -471,6 +471,7 @@ static struct sk_buff *udp_gro_receive_s
+ struct sk_buff *p;
+ unsigned int ulen;
+ int ret = 0;
++ int flush;
+
+ /* requires non zero csum, for symmetry with GSO */
+ if (!uh->check) {
+@@ -504,13 +505,22 @@ static struct sk_buff *udp_gro_receive_s
+ return p;
+ }
+
++ flush = NAPI_GRO_CB(p)->flush;
++
++ if (NAPI_GRO_CB(p)->flush_id != 1 ||
++ NAPI_GRO_CB(p)->count != 1 ||
++ !NAPI_GRO_CB(p)->is_atomic)
++ flush |= NAPI_GRO_CB(p)->flush_id;
++ else
++ NAPI_GRO_CB(p)->is_atomic = false;
++
+ /* Terminate the flow on len mismatch or if it grow "too much".
+ * Under small packet flood GRO count could elsewhere grow a lot
+ * leading to excessive truesize values.
+ * On len mismatch merge the first packet shorter than gso_size,
+ * otherwise complete the GRO packet.
+ */
+- if (ulen > ntohs(uh2->len)) {
++ if (ulen > ntohs(uh2->len) || flush) {
+ pp = p;
+ } else {
+ if (NAPI_GRO_CB(skb)->is_flist) {
--- /dev/null
+From abb45a2477f533cd4aab3085defdff131e2e8c4f Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Mon, 6 May 2024 14:32:46 +0200
+Subject: [PATCH] net: stmmac: dwmac-ipq806x: account for rgmii-txid/rxid/id
+ phy-mode
+
+Currently the ipq806x dwmac driver is almost always used attached to the
+CPU port of a switch and phy-mode was always set to "rgmii" or "sgmii".
+
+Some device came up with a special configuration where the PHY is
+directly attached to the GMAC port and in those case phy-mode needs to
+be set to "rgmii-id" to make the PHY correctly work and receive packets.
+
+Since the driver supports only "rgmii" and "sgmii" mode, when "rgmii-id"
+(or variants) mode is set, the mode is rejected and probe fails.
+
+Add support also for these phy-modes to correctly setup PHYs that requires
+delay applied to tx/rx.
+
+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/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+@@ -171,6 +171,9 @@ static int ipq806x_gmac_set_speed(struct
+
+ switch (gmac->phy_mode) {
+ case PHY_INTERFACE_MODE_RGMII:
++ case PHY_INTERFACE_MODE_RGMII_ID:
++ case PHY_INTERFACE_MODE_RGMII_RXID:
++ case PHY_INTERFACE_MODE_RGMII_TXID:
+ div = get_clk_div_rgmii(gmac, speed);
+ clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
+ NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
+@@ -412,6 +415,9 @@ static int ipq806x_gmac_probe(struct pla
+ val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
+ switch (gmac->phy_mode) {
+ case PHY_INTERFACE_MODE_RGMII:
++ case PHY_INTERFACE_MODE_RGMII_ID:
++ case PHY_INTERFACE_MODE_RGMII_RXID:
++ case PHY_INTERFACE_MODE_RGMII_TXID:
+ val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+@@ -427,6 +433,9 @@ static int ipq806x_gmac_probe(struct pla
+ val &= ~(1 << NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id));
+ switch (gmac->phy_mode) {
+ case PHY_INTERFACE_MODE_RGMII:
++ case PHY_INTERFACE_MODE_RGMII_ID:
++ case PHY_INTERFACE_MODE_RGMII_RXID:
++ case PHY_INTERFACE_MODE_RGMII_TXID:
+ val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
+ break;
+@@ -444,6 +453,9 @@ static int ipq806x_gmac_probe(struct pla
+ val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
+ switch (gmac->phy_mode) {
+ case PHY_INTERFACE_MODE_RGMII:
++ case PHY_INTERFACE_MODE_RGMII_ID:
++ case PHY_INTERFACE_MODE_RGMII_RXID:
++ case PHY_INTERFACE_MODE_RGMII_TXID:
+ val |= NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
+ NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
+ break;
--- /dev/null
+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
+@@ -1220,7 +1220,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);
--- /dev/null
+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
+@@ -2484,7 +2484,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);
--- /dev/null
+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
+@@ -68,6 +68,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
+@@ -34,6 +34,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");
--- /dev/null
+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;
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
-@@ -69,9 +69,9 @@ config SFP
- comment "MII PHY device drivers"
+@@ -74,9 +74,9 @@ config AIR_EN8811H_PHY
+ Currently supports the Airoha EN8811H PHY.
config AMD_PHY
- tristate "AMD PHYs"
# 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_ARM_CCI_PMU is not set
# CONFIG_ARM_CCN is not set
# CONFIG_ARM_CMN is not set
+# CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU is not set
# CONFIG_ARM_CPUIDLE is not set
CONFIG_ARM_CPU_TOPOLOGY=y
# CONFIG_ARM_CRYPTO 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_SMMU_V3_PMU is not set
# CONFIG_ARM_SP805_WATCHDOG is not set
# CONFIG_ARM_SPE_PMU is not set
# CONFIG_ARM_THUMBEE 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_HIMAX_HX8394 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_JADARD_JD9365DA_H3 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_LG_LB035Q02 is not set
# CONFIG_DRM_PANEL_LG_LG4573 is not set
# CONFIG_DRM_PANEL_LVDS is not set
+# CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966 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_NEWVISION_NV3051D 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_NT36523 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_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_TD4353_JDI is not set
# CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set
+# CONFIG_DRM_PANEL_STARTEK_KD070FHFID015 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_R66451 is not set
# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set
+# CONFIG_DRM_PANEL_VISIONOX_VTDR6130 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_REGULATOR_QCOM_REFGEN is not set
# CONFIG_REGULATOR_RAA215300 is not set
# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set
+# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2 is not set
# CONFIG_REGULATOR_RT4801 is not set
# CONFIG_REGULATOR_RT4803 is not set
# CONFIG_REGULATOR_RT5190A is not set
depends on NETFILTER_ADVANCED
help
H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -1105,7 +1104,6 @@ config NETFILTER_XT_TARGET_SECMARK
+@@ -1114,7 +1113,6 @@ config NETFILTER_XT_TARGET_SECMARK
config NETFILTER_XT_TARGET_TCPMSS
tristate '"TCPMSS" target support'
help
This option adds the flow table core infrastructure.
-@@ -1010,6 +1009,15 @@ config NETFILTER_XT_TARGET_NOTRACK
+@@ -1019,6 +1018,15 @@ config NETFILTER_XT_TARGET_NOTRACK
depends on NETFILTER_ADVANCED
select NETFILTER_XT_TARGET_CT
depends on NETFILTER_ADVANCED
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
-@@ -143,6 +143,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF
+@@ -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
#define QUECTEL_VENDOR_ID 0x2c7c
/* These Quectel products use Quectel's vendor ID */
-@@ -1152,6 +1157,11 @@ static const struct usb_device_id option
+@@ -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) },
/* Quectel products using Qualcomm vendor ID */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
-@@ -1193,6 +1203,11 @@ static const struct usb_device_id option
+@@ -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) },
#define QUECTEL_VENDOR_ID 0x2c7c
/* These Quectel products use Quectel's vendor ID */
-@@ -1152,6 +1157,11 @@ static const struct usb_device_id option
+@@ -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) },
/* Quectel products using Qualcomm vendor ID */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
-@@ -1193,6 +1203,11 @@ static const struct usb_device_id option
+@@ -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) },
--- /dev/null
+--- a/tools/scripts/Makefile.include
++++ b/tools/scripts/Makefile.include
+@@ -72,8 +72,6 @@ $(call allow-override,CXX,$(CROSS_COMPIL
+ $(call allow-override,STRIP,$(CROSS_COMPILE)strip)
+ endif
+
+-CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?)
+-
+ ifneq ($(LLVM),)
+ HOSTAR ?= $(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX)
+ HOSTCC ?= $(LLVM_PREFIX)clang$(LLVM_SUFFIX)
+@@ -84,6 +82,9 @@ HOSTCC ?= gcc
+ HOSTLD ?= ld
+ endif
+
++CC_NO_CLANG := $(shell $(CC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?)
++HOSTCC_NO_CLANG := $(shell $(HOSTCC) -dM -E -x c /dev/null | grep -Fq "__clang__"; echo $$?)
++
+ # Some tools require Clang, LLC and/or LLVM utils
+ CLANG ?= clang
+ LLC ?= llc
+@@ -92,8 +93,9 @@ LLVM_OBJCOPY ?= llvm-objcopy
+ LLVM_STRIP ?= llvm-strip
+
+ ifeq ($(CC_NO_CLANG), 1)
+-EXTRA_WARNINGS += -Wstrict-aliasing=3
+-
++ ifeq ($(HOSTCC_NO_CLANG), 1)
++ EXTRA_WARNINGS += -Wstrict-aliasing=3
++ endif
+ else ifneq ($(CROSS_COMPILE),)
+ # Allow userspace to override CLANG_CROSS_FLAGS to specify their own
+ # 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;
+ #define __user
+ #endif
+ #define __must_check
++#undef __cold
+ #define __cold
+
+ typedef __u16 __bitwise __le16;
+--- a/tools/objtool/include/objtool/objtool.h
++++ b/tools/objtool/include/objtool/objtool.h
+@@ -12,6 +12,7 @@
+
+ #include <objtool/elf.h>
+
++#undef __weak
+ #define __weak __attribute__((weak))
+
+ struct pv_state {
+--- 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,6 +12,7 @@
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
++#define fls __linux_fls
+ static __always_inline int fls(unsigned int x)
+ {
+ int r = 32;
+--- a/tools/lib/string.c
++++ b/tools/lib/string.c
+@@ -96,6 +96,7 @@ int strtobool(const char *s, bool *res)
+ * If libc has strlcpy() then that version will override this
+ * implementation:
+ */
++#ifndef __APPLE__
+ #ifdef __clang__
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wignored-attributes"
+@@ -114,6 +115,7 @@ size_t __weak strlcpy(char *dest, const
+ #ifdef __clang__
+ #pragma clang diagnostic pop
+ #endif
++#endif
+
+ /**
+ * skip_spaces - Removes leading whitespace from @str.
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -3305,6 +3305,9 @@ static int mv88e6xxx_setup_port(struct m
+@@ -3353,6 +3353,9 @@ static int mv88e6xxx_setup_port(struct m
else
reg = 1 << port;
static void sock_def_write_space_wfree(struct sock *sk);
static void sock_def_write_space(struct sock *sk);
-@@ -589,6 +591,21 @@ discard_and_relse:
+@@ -590,6 +592,21 @@ discard_and_relse:
}
EXPORT_SYMBOL(__sk_receive_skb);
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 *,
-@@ -2246,9 +2263,11 @@ static void __sk_free(struct sock *sk)
+@@ -2247,9 +2264,11 @@ static void __sk_free(struct sock *sk)
if (likely(sk->sk_net_refcnt))
sock_inuse_add(sock_net(sk), -1);
--- a/net/core/sock.c
+++ b/net/core/sock.c
-@@ -4144,6 +4144,8 @@ static __net_initdata struct pernet_oper
+@@ -4145,6 +4145,8 @@ static __net_initdata struct pernet_oper
static int __init proto_init(void)
{
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
-@@ -204,6 +204,9 @@ static void __br_handle_local_finish(str
+@@ -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)
{
__br_handle_local_finish(skb);
/* return 1 to signal the okfn() was called so it's ok to use the skb */
-@@ -369,6 +372,17 @@ static rx_handler_result_t br_handle_fra
+@@ -376,6 +379,17 @@ static rx_handler_result_t br_handle_fra
forward:
switch (p->state) {
for (i = sizeof(struct ipt_entry);
i < e->target_offset;
i += m->u.match_size) {
-@@ -1224,12 +1261,15 @@ compat_copy_entry_to_user(struct ipt_ent
+@@ -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;
/**
* eth_type_trans - determine the packet's protocol ID.
* @skb: received socket data
-@@ -173,6 +185,10 @@ __be16 eth_type_trans(struct sk_buff *sk
- } else {
- skb->pkt_type = PACKET_OTHERHOST;
- }
-+
-+ if (eth_check_local_mask(eth->h_dest, dev->dev_addr,
-+ dev->local_addr_mask))
-+ skb->gro_skip = 1;
- }
+@@ -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
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
-@@ -606,13 +606,41 @@ void nf_flow_table_free(struct nf_flowta
- }
- EXPORT_SYMBOL_GPL(nf_flow_table_free);
+@@ -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)
+
static int __init nf_flow_table_module_init(void)
{
-- return nf_flow_table_offload_init();
-+ int ret;
-+
-+ ret = nf_flow_table_offload_init();
-+ if (ret)
-+ return ret;
-+
+ 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)
-+ nf_flow_table_offload_exit();
++ goto out_offload_init;
+
-+ return ret;
- }
+ 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
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
-@@ -7803,7 +7803,7 @@ static int nft_register_flowtable_net_ho
+@@ -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 (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev)
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
-@@ -326,6 +326,8 @@ static rx_handler_result_t br_handle_fra
+@@ -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 */
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2467,7 +2467,7 @@ mt7531_setup(struct dsa_switch *ds)
- struct mt7530_priv *priv = ds->priv;
- struct mt7530_dummy_poll p;
- u32 val, id;
-- int ret;
-+ int ret, i;
-
- /* Reset whole chip through gpio pin or memory-mapped registers for
- * different type of hardware
-@@ -2499,6 +2499,10 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -2680,6 +2680,10 @@ mt7531_setup(struct dsa_switch *ds)
return -ENODEV;
}
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -744,6 +744,38 @@ static int rtl8226_match_phy_device(stru
+@@ -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);
}
+ id |= val;
+ }
+
-+ return (id == 0x001cc849);
++ return (id == RTL_8221B_VB_CG_PHYID);
+}
+
static int rtl822x_probe(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
-@@ -1082,7 +1114,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1082,7 +1115,7 @@ static struct phy_driver realtek_drvs[]
.write_page = rtl821x_write_page,
.soft_reset = genphy_soft_reset,
}, {
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -971,6 +971,51 @@ static int rtl8221b_config_init(struct p
+@@ -972,6 +972,51 @@ static int rtl8221b_config_init(struct p
return 0;
}
static struct phy_driver realtek_drvs[] = {
{
PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1119,6 +1164,8 @@ static struct phy_driver realtek_drvs[]
+@@ -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,
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2174,10 +2174,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr
+@@ -2356,10 +2356,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr
{
struct dsa_switch *ds = priv->ds;
struct device *dev = priv->dev;
bus = devm_mdiobus_alloc(dev);
if (!bus)
return -ENOMEM;
-@@ -2194,7 +2197,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr
+@@ -2376,7 +2379,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr
if (priv->irq)
mt7530_setup_mdio_irq(priv);
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
-@@ -2877,8 +2877,7 @@ static void mt753x_phylink_mac_link_up(s
+@@ -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.
*/
/*
* We need to store the untouched command line for future reference.
* We also need to store the touched command line since the parameter
-@@ -958,6 +981,7 @@ asmlinkage __visible void __init __no_sa
+@@ -960,6 +983,7 @@ asmlinkage __visible void __init __no_sa
pr_notice("%s", linux_banner);
early_security_init();
setup_arch(&command_line);
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
-@@ -222,6 +222,9 @@ static void __br_handle_local_finish(str
+@@ -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)
{
__br_handle_local_finish(skb);
/* return 1 to signal the okfn() was called so it's ok to use the skb */
-@@ -390,6 +393,17 @@ forward:
+@@ -397,6 +400,17 @@ forward:
goto defer_stp_filtering;
switch (p->state) {
--- /dev/null
+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
for (i = sizeof(struct ipt_entry);
i < e->target_offset;
i += m->u.match_size) {
-@@ -1225,12 +1262,15 @@ compat_copy_entry_to_user(struct ipt_ent
+@@ -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;
flush = NAPI_GRO_CB(p)->flush;
flush |= (__force int)(flags & TCP_FLAG_CWR);
flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
-@@ -268,6 +350,18 @@ found:
+@@ -268,6 +350,19 @@ found:
flush |= p->decrypted ^ skb->decrypted;
#endif
+ 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))
if (flush || skb_gro_receive(p, skb)) {
mss = 1;
goto out_check_final;
-@@ -289,7 +383,6 @@ out_check_final:
+@@ -289,7 +384,6 @@ out_check_final:
if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
pp = p;
NAPI_GRO_CB(skb)->flush |= (flush != 0);
return pp;
-@@ -315,18 +408,58 @@ int tcp_gro_complete(struct sk_buff *skb
+@@ -315,18 +409,58 @@ int tcp_gro_complete(struct sk_buff *skb
}
EXPORT_SYMBOL(tcp_gro_complete);
}
INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff)
-@@ -334,6 +467,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
+@@ -334,6 +468,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sun, 5 May 2024 20:36:56 +0200
+Subject: [PATCH] net: bridge: fix corrupted ethernet header on
+ multicast-to-unicast
+
+The change from skb_copy to pskb_copy unfortunately changed the data
+copying to omit the ethernet header, since it was pulled before reaching
+this point. Fix this by calling __skb_push/pull around pskb_copy.
+
+Fixes: 59c878cbcdd8 ("net: bridge: fix multicast-to-unicast with fraglist GSO")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/bridge/br_forward.c
++++ b/net/bridge/br_forward.c
+@@ -253,6 +253,7 @@ static void maybe_deliver_addr(struct ne
+ {
+ struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
+ const unsigned char *src = eth_hdr(skb)->h_source;
++ struct sk_buff *nskb;
+
+ if (!should_deliver(p, skb))
+ return;
+@@ -261,12 +262,16 @@ static void maybe_deliver_addr(struct ne
+ if (skb->dev == p->dev && ether_addr_equal(src, addr))
+ return;
+
+- skb = pskb_copy(skb, GFP_ATOMIC);
+- if (!skb) {
++ __skb_push(skb, ETH_HLEN);
++ nskb = pskb_copy(skb, GFP_ATOMIC);
++ __skb_pull(skb, ETH_HLEN);
++ if (!nskb) {
+ DEV_STATS_INC(dev, tx_dropped);
+ return;
+ }
+
++ skb = nskb;
++ __skb_pull(skb, ETH_HLEN);
+ if (!is_broadcast_ether_addr(addr))
+ memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);
+
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
-@@ -7951,7 +7951,7 @@ static int nft_register_flowtable_net_ho
+@@ -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 (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev)
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
-@@ -344,6 +344,8 @@ static rx_handler_result_t br_handle_fra
+@@ -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 */
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -754,6 +754,38 @@ static int rtl8226_match_phy_device(stru
+@@ -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);
}
+ id |= val;
+ }
+
-+ return (id == 0x001cc849);
++ return (id == RTL_8221B_VB_CG_PHYID);
+}
+
static int rtl822x_probe(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
-@@ -1104,7 +1136,7 @@ static struct phy_driver realtek_drvs[]
+@@ -1104,7 +1137,7 @@ static struct phy_driver realtek_drvs[]
.write_page = rtl821x_write_page,
.soft_reset = genphy_soft_reset,
}, {
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -981,6 +981,51 @@ static int rtl8221b_config_init(struct p
+@@ -982,6 +982,51 @@ static int rtl8221b_config_init(struct p
return 0;
}
static struct phy_driver realtek_drvs[] = {
{
PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1141,6 +1186,8 @@ static struct phy_driver realtek_drvs[]
+@@ -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,
--- /dev/null
+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),
+++ /dev/null
-From patchwork Tue Feb 6 19:47:51 2024
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Eric Woudstra <ericwouds@gmail.com>
-X-Patchwork-Id: 13547762
-X-Patchwork-Delegate: kuba@kernel.org
-From: Eric Woudstra <ericwouds@gmail.com>
-To: "David S. Miller" <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Rob Herring <robh+dt@kernel.org>,
- Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
- Conor Dooley <conor+dt@kernel.org>,
- Andrew Lunn <andrew@lunn.ch>,
- Heiner Kallweit <hkallweit1@gmail.com>,
- Russell King <linux@armlinux.org.uk>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- "Frank Wunderlich" <frank-w@public-files.de>,
- Daniel Golle <daniel@makrotopia.org>,
- Lucien Jheng <lucien.jheng@airoha.com>,
- Zhi-Jun You <hujy652@protonmail.com>
-Cc: netdev@vger.kernel.org,
- devicetree@vger.kernel.org,
- Eric Woudstra <ericwouds@gmail.com>
-Subject: [PATCH net-next 2/2] net: phy: air_en8811h: Add the Airoha EN8811H
- PHY driver
-Date: Tue, 6 Feb 2024 20:47:51 +0100
-Message-ID: <20240206194751.1901802-3-ericwouds@gmail.com>
-X-Mailer: git-send-email 2.42.1
-In-Reply-To: <20240206194751.1901802-1-ericwouds@gmail.com>
-References: <20240206194751.1901802-1-ericwouds@gmail.com>
-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
-X-Patchwork-Delegate: kuba@kernel.org
-
-* Source originated from airoha's en8811h v1.2.1 driver
- * Moved air_en8811h.h to air_en8811h.c
- * Removed air_pbus_reg_write() as it writes to another device on mdio-bus
- * Load firmware from /lib/firmware/airoha/ instead of /lib/firmware/
- * Added .get_rate_matching()
- * Use generic phy_read/write() and phy_read/write_mmd()
- * Edited .get_features() to use generic C45 functions
- * Edited .config_aneg() and .read_status() to use a mix of generic C22/C45
- * Use led handling functions from mediatek-ge-soc.c
- * Simplified led handling by storing led rules
- * Cleanup macro definitions
- * Cleanup code to pass checkpatch.pl
- * General code cleanup
-
-Changes from original RFC patch:
-
- * Use the correct order in Kconfig and Makefile
- * Change some register naming to correspond with datasheet
- * Use phy_driver .read_page() and .write_page()
- * Use module_phy_driver()
- * Use get_unaligned_le16() instead of macro
- * In .config_aneg() and .read_status() use genphy_xxx() C22
- * Use another vendor register to read real speed
- * Load firmware only once and store firmware version
- * Apply 2.5G LPA work-around (firmware before 24011202)
- * Read 2.5G LPA from vendor register (firmware 24011202 and later)
-
-Changes to be committed:
- modified: drivers/net/phy/Kconfig
- modified: drivers/net/phy/Makefile
- new file: drivers/net/phy/air_en8811h.c
-
-Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
----
- drivers/net/phy/Kconfig | 5 +
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/air_en8811h.c | 1006 +++++++++++++++++++++++++++++++++
- 3 files changed, 1012 insertions(+)
- create mode 100644 drivers/net/phy/air_en8811h.c
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -69,6 +69,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 and Altima 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,1006 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Driver for Airoha Ethernet PHYs
-+ *
-+ * Currently supporting the EN8811H.
-+ *
-+ * 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 <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
-+
-+/* u32 (DWORD) component macros */
-+#define LOWORD(d) ((u16)(u32)(d))
-+#define HIWORD(d) ((u16)(((u32)(d)) >> 16))
-+
-+/* 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_PBUS_MODE 0x10
-+#define AIR_PBUS_MODE_ADDR_FIXED 0x0000
-+#define AIR_PBUS_MODE_ADDR_INCR BIT(15)
-+#define AIR_PBUS_WR_ADDR_HIGH 0x11
-+#define AIR_PBUS_WR_ADDR_LOW 0x12
-+#define AIR_PBUS_WR_DATA_HIGH 0x13
-+#define AIR_PBUS_WR_DATA_LOW 0x14
-+#define AIR_PBUS_RD_ADDR_HIGH 0x15
-+#define AIR_PBUS_RD_ADDR_LOW 0x16
-+#define AIR_PBUS_RD_DATA_HIGH 0x17
-+#define AIR_PBUS_RD_DATA_LOW 0x18
-+
-+/* Registers on MDIO_MMD_VEND1 */
-+#define EN8811H_PHY_FW_STATUS 0x8009
-+#define EN8811H_PHY_READY 0x02
-+
-+#define AIR_PHY_HOST_CMD_1 0x800c
-+#define AIR_PHY_HOST_CMD_1_MODE1 0x0
-+#define AIR_PHY_HOST_CMD_2 0x800d
-+#define AIR_PHY_HOST_CMD_2_MODE1 0x0
-+#define AIR_PHY_HOST_CMD_3 0x800e
-+#define AIR_PHY_HOST_CMD_3_MODE1 0x1101
-+#define AIR_PHY_HOST_CMD_3_DOCMD 0x1100
-+#define AIR_PHY_HOST_CMD_4 0x800f
-+#define AIR_PHY_HOST_CMD_4_MODE1 0x0002
-+#define AIR_PHY_HOST_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)
-+
-+#define EN8811H_LED_COUNT 3
-+
-+/* GPIO5 <-> BASE_T_LED0
-+ * GPIO4 <-> BASE_T_LED1
-+ * GPIO3 <-> BASE_T_LED2
-+ *
-+ * Default setup suitable for 2 leds connected:
-+ * 100M link up triggers led0, only led0 blinking on traffic
-+ * 1000M link up triggers led1, only led1 blinking on traffic
-+ * 2500M link up triggers led0 and led1, both blinking on traffic
-+ * Also suitable for 1 led connected:
-+ * any link up triggers led2
-+ */
-+#define AIR_DEFAULT_TRIGGER_LED0 (BIT(TRIGGER_NETDEV_LINK_2500) | \
-+ BIT(TRIGGER_NETDEV_LINK_100) | \
-+ BIT(TRIGGER_NETDEV_RX) | \
-+ BIT(TRIGGER_NETDEV_TX))
-+#define AIR_DEFAULT_TRIGGER_LED1 (BIT(TRIGGER_NETDEV_LINK_2500) | \
-+ BIT(TRIGGER_NETDEV_LINK_1000) | \
-+ BIT(TRIGGER_NETDEV_RX) | \
-+ BIT(TRIGGER_NETDEV_TX))
-+#define AIR_DEFAULT_TRIGGER_LED2 BIT(TRIGGER_NETDEV_LINK)
-+
-+struct led {
-+ unsigned long rules;
-+ unsigned long state;
-+};
-+
-+struct en8811h_priv {
-+ u32 firmware_version;
-+ 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_32M,
-+ AIR_PHY_LED_DUR_BLINK_64M,
-+ AIR_PHY_LED_DUR_BLINK_128M,
-+ AIR_PHY_LED_DUR_BLINK_256M,
-+ AIR_PHY_LED_DUR_BLINK_512M,
-+ AIR_PHY_LED_DUR_BLINK_1024M,
-+};
-+
-+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_64M)
-+
-+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_PBUS_MODE, AIR_PBUS_MODE_ADDR_FIXED);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_HIGH, HIWORD(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_LOW, LOWORD(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_DATA_HIGH, HIWORD(pbus_data));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_DATA_LOW, LOWORD(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 ret, saved_page;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ 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_PBUS_MODE, AIR_PBUS_MODE_ADDR_FIXED);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_RD_ADDR_HIGH, HIWORD(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_RD_ADDR_LOW, LOWORD(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ pbus_data_high = __phy_read(phydev, AIR_PBUS_RD_DATA_HIGH);
-+ if (pbus_data_high < 0)
-+ return ret;
-+
-+ pbus_data_low = __phy_read(phydev, AIR_PBUS_RD_DATA_LOW);
-+ if (pbus_data_low < 0)
-+ return ret;
-+
-+ *pbus_data = (u16)pbus_data_low | ((u32)(u16)pbus_data_high << 16);
-+ return 0;
-+}
-+
-+static int air_buckpbus_reg_read(struct phy_device *phydev,
-+ u32 pbus_address, u32 *pbus_data)
-+{
-+ int ret, saved_page;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ 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_write_buf(struct phy_device *phydev, u32 address,
-+ const struct firmware *fw)
-+{
-+ unsigned int offset;
-+ int ret;
-+ u16 val;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_MODE, AIR_PBUS_MODE_ADDR_INCR);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_HIGH, HIWORD(address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_LOW, LOWORD(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_PBUS_WR_DATA_HIGH, val);
-+ if (ret < 0)
-+ return ret;
-+
-+ val = get_unaligned_le16(&fw->data[offset]);
-+ ret = __phy_write(phydev, AIR_PBUS_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 ret, saved_page;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ 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_load_firmware(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ const struct firmware *fw1, *fw2;
-+ u32 pbus_value;
-+ 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_read(phydev, EN8811H_FW_CTRL_2, &pbus_value);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+ pbus_value |= EN8811H_FW_CTRL_2_LOADING;
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_2, pbus_value);
-+ 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_read(phydev, EN8811H_FW_CTRL_2, &pbus_value);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+ pbus_value &= ~EN8811H_FW_CTRL_2_LOADING;
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_2, pbus_value);
-+ 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 = 0;
-+
-+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_host(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;
-+
-+ return air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
-+ EN8811H_FW_CTRL_1_FINISH);
-+}
-+
-+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;
-+
-+ priv->led[index].rules = rules;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) {
-+ on |= AIR_PHY_LED_ON_LINK10;
-+ if (rules & BIT(TRIGGER_NETDEV_RX))
-+ blink |= AIR_PHY_LED_BLINK_10RX;
-+ if (rules & BIT(TRIGGER_NETDEV_TX))
-+ blink |= AIR_PHY_LED_BLINK_10TX;
-+ }
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) {
-+ on |= AIR_PHY_LED_ON_LINK100;
-+ if (rules & BIT(TRIGGER_NETDEV_RX))
-+ blink |= AIR_PHY_LED_BLINK_100RX;
-+ if (rules & BIT(TRIGGER_NETDEV_TX))
-+ blink |= AIR_PHY_LED_BLINK_100TX;
-+ }
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) {
-+ on |= AIR_PHY_LED_ON_LINK1000;
-+ if (rules & BIT(TRIGGER_NETDEV_RX))
-+ blink |= AIR_PHY_LED_BLINK_1000RX;
-+ if (rules & BIT(TRIGGER_NETDEV_TX))
-+ blink |= AIR_PHY_LED_BLINK_1000TX;
-+ }
-+
-+ 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_2500RX;
-+ if (rules & BIT(TRIGGER_NETDEV_TX))
-+ blink |= AIR_PHY_LED_BLINK_2500TX;
-+ }
-+
-+ if (on == 0) {
-+ 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 (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
-+ on |= AIR_PHY_LED_ON_FDX;
-+
-+ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
-+ on |= AIR_PHY_LED_ON_HDX;
-+
-+ 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 cl45_data;
-+ int err;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ cl45_data = phy_read_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index));
-+ if (cl45_data < 0)
-+ return cl45_data;
-+
-+ if (state == AIR_LED_ENABLE)
-+ cl45_data |= AIR_PHY_LED_ON_ENABLE;
-+ else
-+ cl45_data &= ~AIR_PHY_LED_ON_ENABLE;
-+
-+ if (pol == AIR_ACTIVE_HIGH)
-+ cl45_data |= AIR_PHY_LED_ON_POLARITY;
-+ else
-+ cl45_data &= ~AIR_PHY_LED_ON_POLARITY;
-+
-+ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index),
-+ cl45_data);
-+ 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 cl45_data = dur;
-+ int ret, i;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_BLINK,
-+ cl45_data);
-+ if (ret < 0)
-+ return ret;
-+
-+ cl45_data >>= 1;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_ON,
-+ cl45_data);
-+ if (ret < 0)
-+ return ret;
-+
-+ cl45_data = phy_read_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR);
-+ if (cl45_data < 0)
-+ return cl45_data;
-+
-+ switch (mode) {
-+ case AIR_LED_MODE_DISABLE:
-+ cl45_data &= ~AIR_PHY_LED_BCR_EXT_CTRL;
-+ cl45_data &= ~AIR_PHY_LED_BCR_MODE_MASK;
-+ break;
-+ case AIR_LED_MODE_USER_DEFINE:
-+ cl45_data |= AIR_PHY_LED_BCR_EXT_CTRL;
-+ cl45_data |= AIR_PHY_LED_BCR_CLK_EN;
-+ break;
-+ default:
-+ phydev_err(phydev, "LED mode %d is not supported\n", mode);
-+ return -EINVAL;
-+ }
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR, cl45_data);
-+ if (ret < 0)
-+ return ret;
-+
-+ 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;
-+
-+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct en8811h_priv),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->led[0].rules = AIR_DEFAULT_TRIGGER_LED0;
-+ priv->led[1].rules = AIR_DEFAULT_TRIGGER_LED1;
-+ priv->led[2].rules = AIR_DEFAULT_TRIGGER_LED2;
-+
-+ phydev->priv = priv;
-+
-+ /* MDIO_DEVS1/2 empty, so set mmds_present bits here */
-+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_AN;
-+
-+ return 0;
-+}
-+
-+static int en8811h_config_init(struct phy_device *phydev)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ struct device *dev = &phydev->mdio.dev;
-+ int ret, pollret, reg_value;
-+ u32 pbus_value;
-+
-+ if (!priv->firmware_version)
-+ ret = en8811h_load_firmware(phydev);
-+ else
-+ ret = en8811h_restart_host(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Because of mdio-lock, may have to wait for multiple loads */
-+ pollret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-+ EN8811H_PHY_FW_STATUS, reg_value,
-+ reg_value == EN8811H_PHY_READY,
-+ 20000, 7500000, true);
-+
-+ ret = air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION, &pbus_value);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (pollret || !pbus_value) {
-+ phydev_err(phydev, "Firmware not ready: 0x%x\n", reg_value);
-+ return -ENODEV;
-+ }
-+
-+ if (!priv->firmware_version) {
-+ phydev_info(phydev, "MD32 firmware version: %08x\n", pbus_value);
-+ priv->firmware_version = pbus_value;
-+ }
-+
-+ /* Select mode 1, the only mode supported */
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_1,
-+ AIR_PHY_HOST_CMD_1_MODE1);
-+ if (ret < 0)
-+ return ret;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_2,
-+ AIR_PHY_HOST_CMD_2_MODE1);
-+ if (ret < 0)
-+ return ret;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_3,
-+ AIR_PHY_HOST_CMD_3_MODE1);
-+ if (ret < 0)
-+ return ret;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_4,
-+ AIR_PHY_HOST_CMD_4_MODE1);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Serdes polarity */
-+ ret = air_buckpbus_reg_read(phydev, EN8811H_POLARITY, &pbus_value);
-+ if (ret < 0)
-+ return ret;
-+ 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_write(phydev, EN8811H_POLARITY, 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;
-+ }
-+
-+ ret = air_buckpbus_reg_read(phydev, EN8811H_GPIO_OUTPUT, &pbus_value);
-+ if (ret < 0)
-+ return ret;
-+ pbus_value |= EN8811H_GPIO_OUTPUT_345;
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_GPIO_OUTPUT, pbus_value);
-+ if (ret < 0)
-+ 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 err, val;
-+
-+ val = 0;
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-+ phydev->advertising))
-+ val |= MDIO_AN_10GBT_CTRL_ADV2_5G;
-+ err = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-+ MDIO_AN_10GBT_CTRL_ADV2_5G, val);
-+ if (err < 0)
-+ return err;
-+ if (err > 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;
-+
-+ 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 == AUTONEG_ENABLE && 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;
-+ }
-+
-+ /* BUG in PHY firmware: MDIO_AN_10GBT_STAT_LP2_5G does not get set.
-+ * 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_HOST_CMD_3,
-+ AIR_PHY_HOST_CMD_3_DOCMD);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_4,
-+ AIR_PHY_HOST_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");
+++ /dev/null
-From patchwork Sat Apr 27 11:24:42 2024
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?b?QXLEsW7DpyDDnE5BTCB2aWEgQjQgUmVsYXk=?=
- <devnull+arinc.unal.arinc9.com@kernel.org>
-X-Patchwork-Id: 13645655
-From: =?utf-8?b?QXLEsW7DpyDDnE5BTCB2aWEgQjQgUmVsYXk=?=
- <devnull+arinc.unal.arinc9.com@kernel.org>
-Date: Sat, 27 Apr 2024 14:24:42 +0300
-Subject: [PATCH net-next] net: dsa: mt7530: do not set MT7530_P5_DIS when
- PHY muxing is being used
-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
-Message-Id:
- <20240427-for-netnext-mt7530-do-not-disable-port5-when-phy-muxing-v1-1-793cdf9d7707@arinc9.com>
-To: 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>
-Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org,
- =?utf-8?b?QXLEsW7DpyDDnE5BTA==?= <arinc.unal@arinc9.com>
-X-Mailer: b4 0.13.0
-X-Patchwork-Delegate: kuba@kernel.org
-
-From: Arınç ÜNAL <arinc.unal@arinc9.com>
-
-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 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>
----
-Hello.
-
-I've sent this to net-next as the patch it fixes is on the current
-development cycle.
----
- drivers/net/dsa/mt7530.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-
----
-base-commit: 5c4c0edca68a5841a8d53ccd49596fe199c8334c
-change-id: 20240427-for-netnext-mt7530-do-not-disable-port5-when-phy-muxing-7ff5fd0995d7
-
-Best regards,
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1213,7 +1213,7 @@ mt7530_port_disable(struct dsa_switch *d
- if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
- return;
-
-- if (port == 5)
-+ 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);
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
+@@ -631,6 +633,10 @@ bool usb_amd_pt_check_port(struct device
}
EXPORT_SYMBOL_GPL(usb_amd_pt_check_port);
/*
* Make sure the controller is completely inactive, unable to
* generate interrupts or do DMA.
-@@ -712,8 +718,17 @@ reset_needed:
+@@ -710,8 +716,17 @@ reset_needed:
uhci_reset_hc(pdev, base);
return 1;
}
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
+@@ -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 /* __LINUX_USB_PCI_QUIRKS_H */
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
-@@ -483,7 +483,14 @@ extern int usb_hcd_pci_probe(struct pci_
+@@ -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);
/*
* We need to store the untouched command line for future reference.
* We also need to store the touched command line since the parameter
-@@ -959,6 +982,7 @@ asmlinkage __visible void __init __no_sa
+@@ -961,6 +984,7 @@ asmlinkage __visible void __init __no_sa
pr_notice("%s", linux_banner);
early_security_init();
setup_arch(&command_line);
--- /dev/null
+From patchwork Sun Apr 21 07:39:52 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: INAGAKI Hiroshi <musashino.open@gmail.com>
+X-Patchwork-Id: 13637306
+From: INAGAKI Hiroshi <musashino.open@gmail.com>
+To: axboe@kernel.dk
+Cc: yang.yang29@zte.com,
+ justinstitt@google.com,
+ xu.panda@zte.com.cn,
+ linux-block@vger.kernel.org,
+ linux-kernel@vger.kernel.org,
+ INAGAKI Hiroshi <musashino.open@gmail.com>,
+ Naohiro Aota <naota@elisp.net>
+Subject: [PATCH] block: fix and simplify blkdevparts= cmdline parsing
+Date: Sun, 21 Apr 2024 16:39:52 +0900
+Message-ID: <20240421074005.565-1-musashino.open@gmail.com>
+X-Mailer: git-send-email 2.42.0.windows.2
+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
+
+Fix the cmdline parsing of the "blkdevparts=" parameter using strsep(),
+which makes the code simpler.
+
+Before commit 146afeb235cc ("block: use strscpy() to instead of
+strncpy()"), we used a strncpy() to copy a block device name and partition
+names. The commit simply replaced a strncpy() and NULL termination with
+a strscpy(). It did not update calculations of length passed to strscpy().
+While the length passed to strncpy() is just a length of valid characters
+without NULL termination ('\0'), strscpy() takes it as a length of the
+destination buffer, including a NULL termination.
+
+Since the source buffer is not necessarily NULL terminated, the current
+code copies "length - 1" characters and puts a NULL character in the
+destination buffer. It replaces the last character with NULL and breaks
+the parsing.
+
+As an example, that buffer will be passed to parse_parts() and breaks
+parsing sub-partitions due to the missing ')' at the end, like the
+following.
+
+example (Check Point V-80 & OpenWrt):
+
+- Linux Kernel 6.6
+
+ [ 0.000000] Kernel command line: console=ttyS0,115200 earlycon=uart8250,mmio32,0xf0512000 crashkernel=30M mvpp2x.queue_mode=1 blkdevparts=mmcblk1:48M@10M(kernel-1),1M(dtb-1),720M(rootfs-1),48M(kernel-2),1M(dtb-2),720M(rootfs-2),300M(default_sw),650M(logs),1M(preset_cfg),1M(adsl),-(storage) maxcpus=4
+ ...
+ [ 0.884016] mmc1: new HS200 MMC card at address 0001
+ [ 0.889951] mmcblk1: mmc1:0001 004GA0 3.69 GiB
+ [ 0.895043] cmdline partition format is invalid.
+ [ 0.895704] mmcblk1: p1
+ [ 0.903447] mmcblk1boot0: mmc1:0001 004GA0 2.00 MiB
+ [ 0.908667] mmcblk1boot1: mmc1:0001 004GA0 2.00 MiB
+ [ 0.913765] mmcblk1rpmb: mmc1:0001 004GA0 512 KiB, chardev (248:0)
+
+ 1. "48M@10M(kernel-1),..." is passed to strscpy() with length=17
+ from parse_parts()
+ 2. strscpy() returns -E2BIG and the destination buffer has
+ "48M@10M(kernel-1\0"
+ 3. "48M@10M(kernel-1\0" is passed to parse_subpart()
+ 4. parse_subpart() fails to find ')' when parsing a partition name,
+ and returns error
+
+- Linux Kernel 6.1
+
+ [ 0.000000] Kernel command line: console=ttyS0,115200 earlycon=uart8250,mmio32,0xf0512000 crashkernel=30M mvpp2x.queue_mode=1 blkdevparts=mmcblk1:48M@10M(kernel-1),1M(dtb-1),720M(rootfs-1),48M(kernel-2),1M(dtb-2),720M(rootfs-2),300M(default_sw),650M(logs),1M(preset_cfg),1M(adsl),-(storage) maxcpus=4
+ ...
+ [ 0.953142] mmc1: new HS200 MMC card at address 0001
+ [ 0.959114] mmcblk1: mmc1:0001 004GA0 3.69 GiB
+ [ 0.964259] mmcblk1: p1(kernel-1) p2(dtb-1) p3(rootfs-1) p4(kernel-2) p5(dtb-2) 6(rootfs-2) p7(default_sw) p8(logs) p9(preset_cfg) p10(adsl) p11(storage)
+ [ 0.979174] mmcblk1boot0: mmc1:0001 004GA0 2.00 MiB
+ [ 0.984674] mmcblk1boot1: mmc1:0001 004GA0 2.00 MiB
+ [ 0.989926] mmcblk1rpmb: mmc1:0001 004GA0 512 KiB, chardev (248:0
+
+By the way, strscpy() takes a length of destination buffer and it is
+often confusing when copying characters with a specified length. Using
+strsep() helps to separate the string by the specified character. Then,
+we can use strscpy() naturally with the size of the destination buffer.
+
+Separating the string on the fly is also useful to omit the redundant
+string copy, reducing memory usage and improve the code readability.
+
+Fixes: 146afeb235cc ("block: use strscpy() to instead of strncpy()")
+Suggested-by: Naohiro Aota <naota@elisp.net>
+Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+---
+ block/partitions/cmdline.c | 49 ++++++++++----------------------------
+ 1 file changed, 12 insertions(+), 37 deletions(-)
+
+--- a/block/partitions/cmdline.c
++++ b/block/partitions/cmdline.c
+@@ -70,8 +70,8 @@ static int parse_subpart(struct cmdline_
+ }
+
+ if (*partdef == '(') {
+- int length;
+- char *next = strchr(++partdef, ')');
++ partdef++;
++ char *next = strsep(&partdef, ")");
+
+ if (!next) {
+ pr_warn("cmdline partition format is invalid.");
+@@ -79,11 +79,7 @@ static int parse_subpart(struct cmdline_
+ goto fail;
+ }
+
+- length = min_t(int, next - partdef,
+- sizeof(new_subpart->name) - 1);
+- strscpy(new_subpart->name, partdef, length);
+-
+- partdef = ++next;
++ strscpy(new_subpart->name, next, sizeof(new_subpart->name));
+ } else
+ new_subpart->name[0] = '\0';
+
+@@ -117,14 +113,12 @@ static void free_subpart(struct cmdline_
+ }
+ }
+
+-static int parse_parts(struct cmdline_parts **parts, const char *bdevdef)
++static int parse_parts(struct cmdline_parts **parts, char *bdevdef)
+ {
+ int ret = -EINVAL;
+ char *next;
+- int length;
+ struct cmdline_subpart **next_subpart;
+ struct cmdline_parts *newparts;
+- char buf[BDEVNAME_SIZE + 32 + 4];
+
+ *parts = NULL;
+
+@@ -132,28 +126,19 @@ static int parse_parts(struct cmdline_pa
+ if (!newparts)
+ return -ENOMEM;
+
+- next = strchr(bdevdef, ':');
++ next = strsep(&bdevdef, ":");
+ if (!next) {
+ pr_warn("cmdline partition has no block device.");
+ goto fail;
+ }
+
+- length = min_t(int, next - bdevdef, sizeof(newparts->name) - 1);
+- strscpy(newparts->name, bdevdef, length);
++ strscpy(newparts->name, next, sizeof(newparts->name));
+ newparts->nr_subparts = 0;
+
+ next_subpart = &newparts->subpart;
+
+- while (next && *(++next)) {
+- bdevdef = next;
+- next = strchr(bdevdef, ',');
+-
+- length = (!next) ? (sizeof(buf) - 1) :
+- min_t(int, next - bdevdef, sizeof(buf) - 1);
+-
+- strscpy(buf, bdevdef, length);
+-
+- ret = parse_subpart(next_subpart, buf);
++ while ((next = strsep(&bdevdef, ","))) {
++ ret = parse_subpart(next_subpart, next);
+ if (ret)
+ goto fail;
+
+@@ -199,24 +184,17 @@ static int cmdline_parts_parse(struct cm
+
+ *parts = NULL;
+
+- next = pbuf = buf = kstrdup(cmdline, GFP_KERNEL);
++ pbuf = buf = kstrdup(cmdline, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ next_parts = parts;
+
+- while (next && *pbuf) {
+- next = strchr(pbuf, ';');
+- if (next)
+- *next = '\0';
+-
+- ret = parse_parts(next_parts, pbuf);
++ while ((next = strsep(&pbuf, ";"))) {
++ ret = parse_parts(next_parts, next);
+ if (ret)
+ goto fail;
+
+- if (next)
+- pbuf = ++next;
+-
+ next_parts = &(*next_parts)->next_parts;
+ }
+
+@@ -250,7 +228,6 @@ static struct cmdline_parts *bdev_parts;
+ static int add_part(int slot, struct cmdline_subpart *subpart,
+ struct parsed_partitions *state)
+ {
+- int label_min;
+ struct partition_meta_info *info;
+ char tmp[sizeof(info->volname) + 4];
+
+@@ -262,9 +239,7 @@ static int add_part(int slot, struct cmd
+
+ info = &state->parts[slot].info;
+
+- label_min = min_t(int, sizeof(info->volname) - 1,
+- sizeof(subpart->name));
+- strscpy(info->volname, subpart->name, label_min);
++ strscpy(info->volname, subpart->name, sizeof(info->volname));
+
+ snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
+ strlcat(state->pp_buf, tmp, PAGE_SIZE);
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/kernel/setup.c | 16 +++++++++++-----
- 1 file changed, 11 insertions(+), 5 deletions(-)
+ 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
-@@ -46,6 +46,8 @@
- #include <asm/prom.h>
- #include <asm/fw/fw.h>
-
-+#define MIPS_MEM_TEST_PATTERN 0xaa5555aa
-+
- #ifdef CONFIG_MIPS_ELF_APPENDED_DTB
- char __section(".appended_dtb") __appended_dtb[0x100000];
- #endif /* CONFIG_MIPS_ELF_APPENDED_DTB */
-@@ -90,7 +92,7 @@ static struct resource bss_resource = {
+@@ -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;
-+static u32 detect_magic __initdata;
-
+-
#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
unsigned long ARCH_PFN_OFFSET;
-@@ -99,12 +101,16 @@ EXPORT_SYMBOL(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;
}
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
--- /dev/null
+From ecb8f9a7d69698ce20fc6f4d107718d56fa861df Mon Sep 17 00:00:00 2001
+From: Tony Ambardar <Tony.Ambardar@gmail.com>
+Date: Sat, 9 Mar 2024 16:44:53 -0800
+Subject: [PATCH] selftests/bpf: Improve portability of unprivileged tests
+
+The addition of general support for unprivileged tests in test_loader.c
+breaks building test_verifier on non-glibc (e.g. musl) systems, due to the
+inclusion of glibc extension '<error.h>' in 'unpriv_helpers.c'. However,
+the header is actually not needed, so remove it to restore building.
+
+Fixes: 1d56ade032a4 ("selftests/bpf: Unprivileged tests for test_loader.c")
+Signed-off-by: Tony Ambardar <Tony.Ambardar@gmail.com>
+---
+ tools/testing/selftests/bpf/unpriv_helpers.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/tools/testing/selftests/bpf/unpriv_helpers.c
++++ b/tools/testing/selftests/bpf/unpriv_helpers.c
+@@ -2,7 +2,6 @@
+
+ #include <stdbool.h>
+ #include <stdlib.h>
+-#include <error.h>
+ #include <stdio.h>
+
+ #include "unpriv_helpers.h"
--- a/include/net/gro.h
+++ b/include/net/gro.h
-@@ -430,6 +430,7 @@ static inline __wsum ip6_gro_compute_pse
+@@ -439,6 +439,7 @@ static inline __wsum ip6_gro_compute_pse
}
int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb);
flush = NAPI_GRO_CB(p)->flush;
flush |= (__force int)(flags & TCP_FLAG_CWR);
flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
-@@ -269,6 +351,18 @@ found:
+@@ -269,6 +351,19 @@ found:
flush |= p->decrypted ^ skb->decrypted;
#endif
+ 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))
if (flush || skb_gro_receive(p, skb)) {
mss = 1;
goto out_check_final;
-@@ -290,7 +384,6 @@ out_check_final:
+@@ -290,7 +385,6 @@ out_check_final:
if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
pp = p;
NAPI_GRO_CB(skb)->flush |= (flush != 0);
return pp;
-@@ -314,18 +407,58 @@ void tcp_gro_complete(struct sk_buff *sk
+@@ -314,18 +408,58 @@ void tcp_gro_complete(struct sk_buff *sk
}
EXPORT_SYMBOL(tcp_gro_complete);
}
INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff)
-@@ -333,6 +466,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
+@@ -333,6 +467,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
--- /dev/null
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sun, 5 May 2024 20:36:56 +0200
+Subject: [PATCH] net: bridge: fix corrupted ethernet header on
+ multicast-to-unicast
+
+The change from skb_copy to pskb_copy unfortunately changed the data
+copying to omit the ethernet header, since it was pulled before reaching
+this point. Fix this by calling __skb_push/pull around pskb_copy.
+
+Fixes: 59c878cbcdd8 ("net: bridge: fix multicast-to-unicast with fraglist GSO")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/bridge/br_forward.c
++++ b/net/bridge/br_forward.c
+@@ -258,6 +258,7 @@ static void maybe_deliver_addr(struct ne
+ {
+ struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
+ const unsigned char *src = eth_hdr(skb)->h_source;
++ struct sk_buff *nskb;
+
+ if (!should_deliver(p, skb))
+ return;
+@@ -266,12 +267,16 @@ static void maybe_deliver_addr(struct ne
+ if (skb->dev == p->dev && ether_addr_equal(src, addr))
+ return;
+
+- skb = pskb_copy(skb, GFP_ATOMIC);
+- if (!skb) {
++ __skb_push(skb, ETH_HLEN);
++ nskb = pskb_copy(skb, GFP_ATOMIC);
++ __skb_pull(skb, ETH_HLEN);
++ if (!nskb) {
+ DEV_STATS_INC(dev, tx_dropped);
+ return;
+ }
+
++ skb = nskb;
++ __skb_pull(skb, ETH_HLEN);
+ if (!is_broadcast_ether_addr(addr))
+ memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);
+
-From e52faf1564a8bcaf866f9a6c7bf0e8a8748afb15 Mon Sep 17 00:00:00 2001
+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
over the implemented MMDs.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 50 ++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 49 insertions(+), 1 deletion(-)
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
#define RTL_GENERIC_PHYID 0x001cc800
#define RTL_8211FVD_PHYID 0x001cc878
-+#define RTL_8221B_VB_CG 0x001cc849
++#define RTL_8221B_VB_CG_PHYID 0x001cc849
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
-@@ -801,6 +802,54 @@ static int rtl822x_probe(struct phy_devi
- return 0;
+@@ -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->is_c45) {
-+ if (phydev->c45_ids.device_ids[1])
-+ return phydev->c45_ids.device_ids[1] == RTL_8221B_VB_CG;
-+ } else {
-+ if (phydev->phy_id)
-+ return phydev->phy_id == RTL_8221B_VB_CG;
-+ }
-+
+ if (phydev->mdio.bus->read_c45) {
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
+ if (val < 0)
+ id |= val;
+ }
+
-+ if (id != RTL_8221B_VB_CG)
-+ return 0;
-+
-+ if (phydev->is_c45)
-+ phydev->c45_ids.device_ids[1] = id;
-+ else
-+ phydev->phy_id = id;
-+
-+ return 1;
++ return (id == RTL_8221B_VB_CG_PHYID);
+}
+
- static int rtlgen_resume(struct phy_device *phydev)
+ static int rtl822x_probe(struct phy_device *phydev)
{
- int ret = genphy_resume(phydev);
-@@ -1134,7 +1183,7 @@ static struct phy_driver realtek_drvs[]
+ 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,
}, {
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
-@@ -1026,6 +1026,51 @@ static int rtl8221b_config_init(struct p
+@@ -1010,6 +1010,51 @@ static int rtl8221b_config_init(struct p
return 0;
}
static struct phy_driver realtek_drvs[] = {
{
PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1188,6 +1233,8 @@ static struct phy_driver realtek_drvs[]
+@@ -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,
--- /dev/null
+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),
+++ /dev/null
-From patchwork Tue Feb 6 19:47:51 2024
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Eric Woudstra <ericwouds@gmail.com>
-X-Patchwork-Id: 13547762
-X-Patchwork-Delegate: kuba@kernel.org
-From: Eric Woudstra <ericwouds@gmail.com>
-To: "David S. Miller" <davem@davemloft.net>,
- Eric Dumazet <edumazet@google.com>,
- Jakub Kicinski <kuba@kernel.org>,
- Paolo Abeni <pabeni@redhat.com>,
- Rob Herring <robh+dt@kernel.org>,
- Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
- Conor Dooley <conor+dt@kernel.org>,
- Andrew Lunn <andrew@lunn.ch>,
- Heiner Kallweit <hkallweit1@gmail.com>,
- Russell King <linux@armlinux.org.uk>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- "Frank Wunderlich" <frank-w@public-files.de>,
- Daniel Golle <daniel@makrotopia.org>,
- Lucien Jheng <lucien.jheng@airoha.com>,
- Zhi-Jun You <hujy652@protonmail.com>
-Cc: netdev@vger.kernel.org,
- devicetree@vger.kernel.org,
- Eric Woudstra <ericwouds@gmail.com>
-Subject: [PATCH net-next 2/2] net: phy: air_en8811h: Add the Airoha EN8811H
- PHY driver
-Date: Tue, 6 Feb 2024 20:47:51 +0100
-Message-ID: <20240206194751.1901802-3-ericwouds@gmail.com>
-X-Mailer: git-send-email 2.42.1
-In-Reply-To: <20240206194751.1901802-1-ericwouds@gmail.com>
-References: <20240206194751.1901802-1-ericwouds@gmail.com>
-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
-X-Patchwork-Delegate: kuba@kernel.org
-
-* Source originated from airoha's en8811h v1.2.1 driver
- * Moved air_en8811h.h to air_en8811h.c
- * Removed air_pbus_reg_write() as it writes to another device on mdio-bus
- * Load firmware from /lib/firmware/airoha/ instead of /lib/firmware/
- * Added .get_rate_matching()
- * Use generic phy_read/write() and phy_read/write_mmd()
- * Edited .get_features() to use generic C45 functions
- * Edited .config_aneg() and .read_status() to use a mix of generic C22/C45
- * Use led handling functions from mediatek-ge-soc.c
- * Simplified led handling by storing led rules
- * Cleanup macro definitions
- * Cleanup code to pass checkpatch.pl
- * General code cleanup
-
-Changes from original RFC patch:
-
- * Use the correct order in Kconfig and Makefile
- * Change some register naming to correspond with datasheet
- * Use phy_driver .read_page() and .write_page()
- * Use module_phy_driver()
- * Use get_unaligned_le16() instead of macro
- * In .config_aneg() and .read_status() use genphy_xxx() C22
- * Use another vendor register to read real speed
- * Load firmware only once and store firmware version
- * Apply 2.5G LPA work-around (firmware before 24011202)
- * Read 2.5G LPA from vendor register (firmware 24011202 and later)
-
-Changes to be committed:
- modified: drivers/net/phy/Kconfig
- modified: drivers/net/phy/Makefile
- new file: drivers/net/phy/air_en8811h.c
-
-Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
----
- drivers/net/phy/Kconfig | 5 +
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/air_en8811h.c | 1006 +++++++++++++++++++++++++++++++++
- 3 files changed, 1012 insertions(+)
- create mode 100644 drivers/net/phy/air_en8811h.c
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -68,6 +68,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 and Altima PHYs"
- help
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -34,6 +34,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,1006 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Driver for Airoha Ethernet PHYs
-+ *
-+ * Currently supporting the EN8811H.
-+ *
-+ * 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 <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
-+
-+/* u32 (DWORD) component macros */
-+#define LOWORD(d) ((u16)(u32)(d))
-+#define HIWORD(d) ((u16)(((u32)(d)) >> 16))
-+
-+/* 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_PBUS_MODE 0x10
-+#define AIR_PBUS_MODE_ADDR_FIXED 0x0000
-+#define AIR_PBUS_MODE_ADDR_INCR BIT(15)
-+#define AIR_PBUS_WR_ADDR_HIGH 0x11
-+#define AIR_PBUS_WR_ADDR_LOW 0x12
-+#define AIR_PBUS_WR_DATA_HIGH 0x13
-+#define AIR_PBUS_WR_DATA_LOW 0x14
-+#define AIR_PBUS_RD_ADDR_HIGH 0x15
-+#define AIR_PBUS_RD_ADDR_LOW 0x16
-+#define AIR_PBUS_RD_DATA_HIGH 0x17
-+#define AIR_PBUS_RD_DATA_LOW 0x18
-+
-+/* Registers on MDIO_MMD_VEND1 */
-+#define EN8811H_PHY_FW_STATUS 0x8009
-+#define EN8811H_PHY_READY 0x02
-+
-+#define AIR_PHY_HOST_CMD_1 0x800c
-+#define AIR_PHY_HOST_CMD_1_MODE1 0x0
-+#define AIR_PHY_HOST_CMD_2 0x800d
-+#define AIR_PHY_HOST_CMD_2_MODE1 0x0
-+#define AIR_PHY_HOST_CMD_3 0x800e
-+#define AIR_PHY_HOST_CMD_3_MODE1 0x1101
-+#define AIR_PHY_HOST_CMD_3_DOCMD 0x1100
-+#define AIR_PHY_HOST_CMD_4 0x800f
-+#define AIR_PHY_HOST_CMD_4_MODE1 0x0002
-+#define AIR_PHY_HOST_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)
-+
-+#define EN8811H_LED_COUNT 3
-+
-+/* GPIO5 <-> BASE_T_LED0
-+ * GPIO4 <-> BASE_T_LED1
-+ * GPIO3 <-> BASE_T_LED2
-+ *
-+ * Default setup suitable for 2 leds connected:
-+ * 100M link up triggers led0, only led0 blinking on traffic
-+ * 1000M link up triggers led1, only led1 blinking on traffic
-+ * 2500M link up triggers led0 and led1, both blinking on traffic
-+ * Also suitable for 1 led connected:
-+ * any link up triggers led2
-+ */
-+#define AIR_DEFAULT_TRIGGER_LED0 (BIT(TRIGGER_NETDEV_LINK_2500) | \
-+ BIT(TRIGGER_NETDEV_LINK_100) | \
-+ BIT(TRIGGER_NETDEV_RX) | \
-+ BIT(TRIGGER_NETDEV_TX))
-+#define AIR_DEFAULT_TRIGGER_LED1 (BIT(TRIGGER_NETDEV_LINK_2500) | \
-+ BIT(TRIGGER_NETDEV_LINK_1000) | \
-+ BIT(TRIGGER_NETDEV_RX) | \
-+ BIT(TRIGGER_NETDEV_TX))
-+#define AIR_DEFAULT_TRIGGER_LED2 BIT(TRIGGER_NETDEV_LINK)
-+
-+struct led {
-+ unsigned long rules;
-+ unsigned long state;
-+};
-+
-+struct en8811h_priv {
-+ u32 firmware_version;
-+ 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_32M,
-+ AIR_PHY_LED_DUR_BLINK_64M,
-+ AIR_PHY_LED_DUR_BLINK_128M,
-+ AIR_PHY_LED_DUR_BLINK_256M,
-+ AIR_PHY_LED_DUR_BLINK_512M,
-+ AIR_PHY_LED_DUR_BLINK_1024M,
-+};
-+
-+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_64M)
-+
-+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_PBUS_MODE, AIR_PBUS_MODE_ADDR_FIXED);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_HIGH, HIWORD(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_LOW, LOWORD(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_DATA_HIGH, HIWORD(pbus_data));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_DATA_LOW, LOWORD(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 ret, saved_page;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ 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_PBUS_MODE, AIR_PBUS_MODE_ADDR_FIXED);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_RD_ADDR_HIGH, HIWORD(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_RD_ADDR_LOW, LOWORD(pbus_address));
-+ if (ret < 0)
-+ return ret;
-+
-+ pbus_data_high = __phy_read(phydev, AIR_PBUS_RD_DATA_HIGH);
-+ if (pbus_data_high < 0)
-+ return ret;
-+
-+ pbus_data_low = __phy_read(phydev, AIR_PBUS_RD_DATA_LOW);
-+ if (pbus_data_low < 0)
-+ return ret;
-+
-+ *pbus_data = (u16)pbus_data_low | ((u32)(u16)pbus_data_high << 16);
-+ return 0;
-+}
-+
-+static int air_buckpbus_reg_read(struct phy_device *phydev,
-+ u32 pbus_address, u32 *pbus_data)
-+{
-+ int ret, saved_page;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ 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_write_buf(struct phy_device *phydev, u32 address,
-+ const struct firmware *fw)
-+{
-+ unsigned int offset;
-+ int ret;
-+ u16 val;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_MODE, AIR_PBUS_MODE_ADDR_INCR);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_HIGH, HIWORD(address));
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = __phy_write(phydev, AIR_PBUS_WR_ADDR_LOW, LOWORD(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_PBUS_WR_DATA_HIGH, val);
-+ if (ret < 0)
-+ return ret;
-+
-+ val = get_unaligned_le16(&fw->data[offset]);
-+ ret = __phy_write(phydev, AIR_PBUS_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 ret, saved_page;
-+
-+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4);
-+
-+ 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_load_firmware(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ const struct firmware *fw1, *fw2;
-+ u32 pbus_value;
-+ 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_read(phydev, EN8811H_FW_CTRL_2, &pbus_value);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+ pbus_value |= EN8811H_FW_CTRL_2_LOADING;
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_2, pbus_value);
-+ 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_read(phydev, EN8811H_FW_CTRL_2, &pbus_value);
-+ if (ret < 0)
-+ goto en8811h_load_firmware_out;
-+ pbus_value &= ~EN8811H_FW_CTRL_2_LOADING;
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_2, pbus_value);
-+ 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 = 0;
-+
-+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_host(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;
-+
-+ return air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1,
-+ EN8811H_FW_CTRL_1_FINISH);
-+}
-+
-+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;
-+
-+ priv->led[index].rules = rules;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) {
-+ on |= AIR_PHY_LED_ON_LINK10;
-+ if (rules & BIT(TRIGGER_NETDEV_RX))
-+ blink |= AIR_PHY_LED_BLINK_10RX;
-+ if (rules & BIT(TRIGGER_NETDEV_TX))
-+ blink |= AIR_PHY_LED_BLINK_10TX;
-+ }
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) {
-+ on |= AIR_PHY_LED_ON_LINK100;
-+ if (rules & BIT(TRIGGER_NETDEV_RX))
-+ blink |= AIR_PHY_LED_BLINK_100RX;
-+ if (rules & BIT(TRIGGER_NETDEV_TX))
-+ blink |= AIR_PHY_LED_BLINK_100TX;
-+ }
-+
-+ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) {
-+ on |= AIR_PHY_LED_ON_LINK1000;
-+ if (rules & BIT(TRIGGER_NETDEV_RX))
-+ blink |= AIR_PHY_LED_BLINK_1000RX;
-+ if (rules & BIT(TRIGGER_NETDEV_TX))
-+ blink |= AIR_PHY_LED_BLINK_1000TX;
-+ }
-+
-+ 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_2500RX;
-+ if (rules & BIT(TRIGGER_NETDEV_TX))
-+ blink |= AIR_PHY_LED_BLINK_2500TX;
-+ }
-+
-+ if (on == 0) {
-+ 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 (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
-+ on |= AIR_PHY_LED_ON_FDX;
-+
-+ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
-+ on |= AIR_PHY_LED_ON_HDX;
-+
-+ 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 cl45_data;
-+ int err;
-+
-+ if (index >= EN8811H_LED_COUNT)
-+ return -EINVAL;
-+
-+ cl45_data = phy_read_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index));
-+ if (cl45_data < 0)
-+ return cl45_data;
-+
-+ if (state == AIR_LED_ENABLE)
-+ cl45_data |= AIR_PHY_LED_ON_ENABLE;
-+ else
-+ cl45_data &= ~AIR_PHY_LED_ON_ENABLE;
-+
-+ if (pol == AIR_ACTIVE_HIGH)
-+ cl45_data |= AIR_PHY_LED_ON_POLARITY;
-+ else
-+ cl45_data &= ~AIR_PHY_LED_ON_POLARITY;
-+
-+ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index),
-+ cl45_data);
-+ 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 cl45_data = dur;
-+ int ret, i;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_BLINK,
-+ cl45_data);
-+ if (ret < 0)
-+ return ret;
-+
-+ cl45_data >>= 1;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_ON,
-+ cl45_data);
-+ if (ret < 0)
-+ return ret;
-+
-+ cl45_data = phy_read_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR);
-+ if (cl45_data < 0)
-+ return cl45_data;
-+
-+ switch (mode) {
-+ case AIR_LED_MODE_DISABLE:
-+ cl45_data &= ~AIR_PHY_LED_BCR_EXT_CTRL;
-+ cl45_data &= ~AIR_PHY_LED_BCR_MODE_MASK;
-+ break;
-+ case AIR_LED_MODE_USER_DEFINE:
-+ cl45_data |= AIR_PHY_LED_BCR_EXT_CTRL;
-+ cl45_data |= AIR_PHY_LED_BCR_CLK_EN;
-+ break;
-+ default:
-+ phydev_err(phydev, "LED mode %d is not supported\n", mode);
-+ return -EINVAL;
-+ }
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR, cl45_data);
-+ if (ret < 0)
-+ return ret;
-+
-+ 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;
-+
-+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct en8811h_priv),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->led[0].rules = AIR_DEFAULT_TRIGGER_LED0;
-+ priv->led[1].rules = AIR_DEFAULT_TRIGGER_LED1;
-+ priv->led[2].rules = AIR_DEFAULT_TRIGGER_LED2;
-+
-+ phydev->priv = priv;
-+
-+ /* MDIO_DEVS1/2 empty, so set mmds_present bits here */
-+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_AN;
-+
-+ return 0;
-+}
-+
-+static int en8811h_config_init(struct phy_device *phydev)
-+{
-+ struct en8811h_priv *priv = phydev->priv;
-+ struct device *dev = &phydev->mdio.dev;
-+ int ret, pollret, reg_value;
-+ u32 pbus_value;
-+
-+ if (!priv->firmware_version)
-+ ret = en8811h_load_firmware(phydev);
-+ else
-+ ret = en8811h_restart_host(phydev);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Because of mdio-lock, may have to wait for multiple loads */
-+ pollret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-+ EN8811H_PHY_FW_STATUS, reg_value,
-+ reg_value == EN8811H_PHY_READY,
-+ 20000, 7500000, true);
-+
-+ ret = air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION, &pbus_value);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (pollret || !pbus_value) {
-+ phydev_err(phydev, "Firmware not ready: 0x%x\n", reg_value);
-+ return -ENODEV;
-+ }
-+
-+ if (!priv->firmware_version) {
-+ phydev_info(phydev, "MD32 firmware version: %08x\n", pbus_value);
-+ priv->firmware_version = pbus_value;
-+ }
-+
-+ /* Select mode 1, the only mode supported */
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_1,
-+ AIR_PHY_HOST_CMD_1_MODE1);
-+ if (ret < 0)
-+ return ret;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_2,
-+ AIR_PHY_HOST_CMD_2_MODE1);
-+ if (ret < 0)
-+ return ret;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_3,
-+ AIR_PHY_HOST_CMD_3_MODE1);
-+ if (ret < 0)
-+ return ret;
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_4,
-+ AIR_PHY_HOST_CMD_4_MODE1);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* Serdes polarity */
-+ ret = air_buckpbus_reg_read(phydev, EN8811H_POLARITY, &pbus_value);
-+ if (ret < 0)
-+ return ret;
-+ 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_write(phydev, EN8811H_POLARITY, 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;
-+ }
-+
-+ ret = air_buckpbus_reg_read(phydev, EN8811H_GPIO_OUTPUT, &pbus_value);
-+ if (ret < 0)
-+ return ret;
-+ pbus_value |= EN8811H_GPIO_OUTPUT_345;
-+ ret = air_buckpbus_reg_write(phydev, EN8811H_GPIO_OUTPUT, pbus_value);
-+ if (ret < 0)
-+ 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 err, val;
-+
-+ val = 0;
-+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-+ phydev->advertising))
-+ val |= MDIO_AN_10GBT_CTRL_ADV2_5G;
-+ err = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-+ MDIO_AN_10GBT_CTRL_ADV2_5G, val);
-+ if (err < 0)
-+ return err;
-+ if (err > 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;
-+
-+ 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 == AUTONEG_ENABLE && 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;
-+ }
-+
-+ /* BUG in PHY firmware: MDIO_AN_10GBT_STAT_LP2_5G does not get set.
-+ * 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_HOST_CMD_3,
-+ AIR_PHY_HOST_CMD_3_DOCMD);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_HOST_CMD_4,
-+ AIR_PHY_HOST_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");
static int min_rcvbuf = SOCK_MIN_RCVBUF;
static int max_skb_frags = MAX_SKB_FRAGS;
+static int backlog_threaded;
+ static int min_mem_pcpu_rsv = SK_MEMORY_PCPU_RESERVE;
static int net_msg_warn; /* Unused, but still a sysctl */
-
-@@ -188,6 +189,23 @@ static int rps_sock_flow_sysctl(struct c
+@@ -189,6 +190,23 @@ static int rps_sock_flow_sysctl(struct c
}
#endif /* CONFIG_RPS */
#ifdef CONFIG_NET_FLOW_LIMIT
static DEFINE_MUTEX(flow_limit_update_mutex);
-@@ -532,6 +550,15 @@ static struct ctl_table net_core_table[]
+@@ -541,6 +559,15 @@ static struct ctl_table net_core_table[]
.proc_handler = rps_sock_flow_sysctl
},
#endif
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -6887,6 +6887,7 @@ static int mv88e6xxx_register_switch(str
+@@ -6935,6 +6935,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;
+++ /dev/null
-From patchwork Sat Apr 27 11:24:42 2024
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 8bit
-X-Patchwork-Submitter: =?utf-8?b?QXLEsW7DpyDDnE5BTCB2aWEgQjQgUmVsYXk=?=
- <devnull+arinc.unal.arinc9.com@kernel.org>
-X-Patchwork-Id: 13645655
-From: =?utf-8?b?QXLEsW7DpyDDnE5BTCB2aWEgQjQgUmVsYXk=?=
- <devnull+arinc.unal.arinc9.com@kernel.org>
-Date: Sat, 27 Apr 2024 14:24:42 +0300
-Subject: [PATCH net-next] net: dsa: mt7530: do not set MT7530_P5_DIS when
- PHY muxing is being used
-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
-Message-Id:
- <20240427-for-netnext-mt7530-do-not-disable-port5-when-phy-muxing-v1-1-793cdf9d7707@arinc9.com>
-To: 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>
-Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org,
- =?utf-8?b?QXLEsW7DpyDDnE5BTA==?= <arinc.unal@arinc9.com>
-X-Mailer: b4 0.13.0
-X-Patchwork-Delegate: kuba@kernel.org
-
-From: Arınç ÜNAL <arinc.unal@arinc9.com>
-
-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 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>
----
-Hello.
-
-I've sent this to net-next as the patch it fixes is on the current
-development cycle.
----
- drivers/net/dsa/mt7530.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-
----
-base-commit: 5c4c0edca68a5841a8d53ccd49596fe199c8334c
-change-id: 20240427-for-netnext-mt7530-do-not-disable-port5-when-phy-muxing-7ff5fd0995d7
-
-Best regards,
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -1220,7 +1220,7 @@ mt7530_port_disable(struct dsa_switch *d
- if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
- return;
-
-- if (port == 5)
-+ 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);
glinet,gl-ap1300|\
glinet,gl-b2200|\
google,wifi|\
+ linksys,whw03|\
linksys,whw03v2|\
luma,wrtq-329acn|\
mikrotik,cap-ac|\
aruba,ap-365|\
avm,fritzrepeater-1200|\
dlink,dap-2610|\
+ engenius,eap1300|\
extreme-networks,ws-ap3915i|\
meraki,mr33|\
meraki,mr74|\
wan_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
lan_mac=$(macaddr_add "$wan_mac" 1)
;;
+ linksys,whw03)
+ wan_mac=$(mmc_get_mac_ascii devinfo hw_mac_addr)
+ lan_mac="$wan_mac"
+ ;;
mikrotik,cap-ac |\
mikrotik,hap-ac2|\
mikrotik,hap-ac3|\
# OEM assigns 4 sequential MACs
ath10k_patch_mac $(macaddr_setbit_la $(macaddr_add "$(cat /sys/class/net/eth0/address)" 4))
;;
+ linksys,whw03)
+ caldata_extract_mmc "0:ART" 0x9000 0x2f20
+ ath10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 3)
+ ;;
netgear,rbr40|\
netgear,rbs40|\
netgear,rbr50|\
caldata_extract "ART" 0x1000 0x2f20
ath10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 2)
;;
+ linksys,whw03)
+ caldata_extract_mmc "0:ART" 0x1000 0x2f20
+ ath10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 1)
+ ;;
meraki,mr33 |\
meraki,mr74)
caldata_extract_ubi "ART" 0x1000 0x2f20
caldata_extract "ART" 0x5000 0x2f20
ath10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 3)
;;
+ linksys,whw03)
+ caldata_extract_mmc "0:ART" 0x5000 0x2f20
+ ath10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 2)
+ ;;
meraki,mr33 |\
meraki,mr74)
caldata_extract_ubi "ART" 0x5000 0x2f20
START=99
+mmc_resetbc() {
+ local part_label="$1"
+
+ . /lib/functions.sh
+
+ local part_device="$(find_mmc_part "$part_label")"
+ if [ "$part_device" = "" ]; then
+ >&2 echo "mmc_resetbc: Unknown partition label: $part_label"
+ return 1
+ fi
+
+ local magic_number="$(hexdump -e '"0x%02x\n"' -n 4 "$part_device")"
+ if [ "$magic_number" != "0x20110811" ]; then
+ >&2 echo "mmc_resetbc: Unexpected partition magic: $magic_number"
+ return 1
+ fi
+
+ local last_count=$(hexdump -e '"0x%02x\n"' -n 4 -s 4 "$part_device")
+ if [ "$last_count" != "0x00" ]; then
+ printf "\x00" | dd of="$part_device" bs=4 seek=1 count=1 conv=notrunc 2>/dev/null
+
+ last_count=$(hexdump -e '"0x%02x\n"' -n 4 -s 4 "$part_device")
+ if [ "$last_count" != "0x00" ]; then
+ >&2 echo "mmc_resetbc: Unable to reset boot counter"
+ return 1
+ fi
+ fi
+}
+
boot() {
case $(board_name) in
alfa-network,ap120c-ac)
linksys,whw03v2)
mtd resetbc s_env || true
;;
+ linksys,whw03)
+ mmc_resetbc s_env || true
+ ;;
netgear,wac510)
fw_setenv boot_cnt=0
;;
ip link set dev lan1 address $(macaddr_add "$base_mac" 1)
ip link set dev eth0 address $(macaddr_setbit "$base_mac" 7)
;;
+ linksys,whw03)
+ base_mac=$(mmc_get_mac_ascii devinfo hw_mac_addr)
+ ip link set dev eth0 address "$base_mac"
+ ip link set dev lan address "$base_mac"
+ ip link set dev wan address "$base_mac"
+ ;;
mikrotik,wap-ac|\
mikrotik,wap-ac-lte|\
mikrotik,wap-r-ac)
get_image "$1" | mtd -e "$part_label" write - "$part_label"
}
}
+
+linksys_get_cmdline_rootfs_device() {
+ if read cmdline < /proc/cmdline; then
+ case "$cmdline" in
+ *root=*)
+ local str="${cmdline##*root=}"
+ echo "${str%% *}"
+ return
+ ;;
+ esac
+ fi
+ return 1
+}
+
+linksys_get_current_boot_part_emmc() {
+ local boot_part="$(fw_printenv -n boot_part)"
+ if [ "$boot_part" = 1 ] || [ "$boot_part" = 2 ]; then
+ v "Current boot_part=$boot_part selected from bootloader environment"
+ else
+ local rootfs_device="$(linksys_get_cmdline_rootfs_device)"
+ if [ "$rootfs_device" = "$(find_mmc_part "rootfs")" ]; then
+ boot_part=1
+ elif [ "$rootfs_device" = "$(find_mmc_part "alt_rootfs")" ]; then
+ boot_part=2
+ else
+ v "Could not determine current boot_part"
+ return 1
+ fi
+ v "Current boot_part=$boot_part selected from cmdline rootfs=$rootfs_device"
+ fi
+ echo $boot_part
+}
+
+linksys_set_target_partitions_emmc() {
+ local current_boot_part="$1"
+
+ if [ "$current_boot_part" = 1 ]; then
+ CI_KERNPART="alt_kernel"
+ CI_ROOTPART="alt_rootfs"
+ fw_setenv -s - <<-EOF
+ boot_part 2
+ auto_recovery yes
+ EOF
+ elif [ "$current_boot_part" = 2 ]; then
+ CI_KERNPART="kernel"
+ CI_ROOTPART="rootfs"
+ fw_setenv -s - <<-EOF
+ boot_part 1
+ auto_recovery yes
+ EOF
+ else
+ v "Could not set target eMMC partitions"
+ return 1
+ fi
+
+ v "Target eMMC partitions: $CI_KERNPART, $CI_ROOTPART"
+}
+
+platform_do_upgrade_linksys_emmc() {
+ local file="$1"
+
+ mkdir -p /var/lock
+ local current_boot_part="$(linksys_get_current_boot_part_emmc)"
+ linksys_set_target_partitions_emmc "$current_boot_part" || exit 1
+ touch /var/lock/fw_printenv.lock
+
+ emmc_do_upgrade "$file"
+}
linksys,whw03v2)
platform_do_upgrade_linksys "$1"
;;
+ linksys,whw03)
+ platform_do_upgrade_linksys_emmc "$1"
+ ;;
meraki,mr33 |\
meraki,mr74)
CI_KERNPART="part.safe"
platform_copy_config() {
case "$(board_name)" in
glinet,gl-b2200 |\
- google,wifi)
+ google,wifi |\
+ linksys,whw03)
emmc_copy_config
;;
esac
CONFIG_NVMEM_QCOM_QFPROM=y
# CONFIG_NVMEM_QCOM_SEC_QFPROM is not set
# CONFIG_NVMEM_SPMI_SDAM is not set
+CONFIG_NVMEM_U_BOOT_ENV=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
compatible = "openmesh,a42";
soc {
- rng@22000 {
- status = "okay";
- };
-
tcsr@194b000 {
/* select hostmode */
compatible = "qcom,tcsr";
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
-
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
+ };
+};
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- phys = <&usb3_hs_phy>;
- phy-names = "usb2-phy";
- };
- };
+&watchdog {
+ status = "okay";
+};
- crypto@8e3a000 {
- status = "okay";
- };
+&prng {
+ status = "okay";
+};
- watchdog@b017000 {
- status = "okay";
- };
- };
+&crypto {
+ status = "okay";
};
&blsp_dma {
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&usb3_hs_phy {
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ phys = <&usb3_hs_phy>;
+ phy-names = "usb2-phy";
+};
+
+&mdio {
+ status = "okay";
+
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 59 GPIO_ACTIVE_LOW>;
- reset-delay-us = <5000>;
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
leds {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 59 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <5000>;
+};
+
&gmac {
status = "okay";
nvmem-cells = <&macaddr_art_0>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- rng@22000 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
leds {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&blsp1_spi1 {
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&blsp1_uart1 {
pinctrl-0 = <&serial_pins>;
pinctrl-names = "default";
status = "okay";
};
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&usb2_hs_phy {
status = "okay";
};
+
+&usb2 {
+ status = "okay";
+};
compatible = "engenius,eap1300";
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
reg = <0x190000 0x1dc0000>;
};
partition9@1f50000 {
+ compatible = "u-boot,env";
label = "u-boot-env";
reg = <0x01f50000 0x00010000>;
+
+ macaddr_ubootenv_ethaddr: ethaddr {
+ #nvmem-cell-cells = <1>;
+ };
};
partition10@1f60000 {
label = "userconfig";
status = "okay";
};
+&switch {
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+};
+
+&swport5 {
+ status = "okay";
+ label = "lan";
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_ubootenv_ethaddr 0>;
+};
+
+&gmac {
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
- nvmem-cell-names = "pre-calibration";
- nvmem-cells = <&precal_art_1000>;
+ nvmem-cell-names = "pre-calibration", "mac-address";
+ nvmem-cells = <&precal_art_1000>, <&macaddr_ubootenv_ethaddr 1>;
qcom,ath10k-calibration-variant = "EnGenius-EAP1300";
};
&wifi1 {
status = "okay";
- nvmem-cell-names = "pre-calibration";
- nvmem-cells = <&precal_art_5000>;
+ nvmem-cell-names = "pre-calibration", "mac-address";
+ nvmem-cells = <&precal_art_5000>, <&macaddr_ubootenv_ethaddr 2>;
qcom,ath10k-calibration-variant = "EnGenius-EAP1300";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
+ };
+};
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- phys = <&usb3_hs_phy>;
- phy-names = "usb2-phy";
- };
- };
+&watchdog {
+ status = "okay";
+};
- crypto@8e3a000 {
- status = "okay";
- };
+&prng {
+ status = "okay";
+};
- watchdog@b017000 {
- status = "okay";
- };
- };
+&crypto {
+ status = "okay";
};
&tlmm {
qcom,ath10k-calibration-variant = "ALFA-Network-AP120C-AC";
};
+&usb2_hs_phy {
+ status = "okay";
+};
+
+&usb2 {
+ status = "okay";
+};
+
&usb3_hs_phy {
status = "okay";
};
-&usb2_hs_phy {
+&usb3 {
status = "okay";
};
+
+&usb3_dwc {
+ phys = <&usb3_hs_phy>;
+ phy-names = "usb2-phy";
+};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
status = "okay";
};
+&mdio {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
qcom,ath10k-calibration-variant = "EnGenius-EMD1";
compatible = "engenius,emr3500";
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2_hs_phy: hsphy@a8000 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
status = "okay";
};
+&mdio {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
qcom,ath10k-calibration-variant = "EnGenius-EMR3500";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
-
/*
* Disable the broken restart as a workaround for the buggy
* 3.0.0/3.0.1 U-boots that ship with the device.
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&cryptobam {
status = "okay";
};
compatible = "netgear,ex61x0v2";
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
aliases {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
nvmem-cells = <&precal_art_5000>, <&macaddr_dnidata_c>;
};
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
status = "okay";
};
+&mdio {
+ status = "okay";
+};
+
ðphy0 {
gpio-controller;
#gpio-cells = <2>;
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&usb2_hs_phy {
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
qcom,ath10k-calibration-variant = "AVM-FRITZBox-4040";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
+&crypto {
+ status = "okay";
+};
+
&cryptobam {
status = "okay";
};
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&usb3_hs_phy {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- phys = <&usb3_hs_phy>;
- phy-names = "usb2-phy";
- };
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ phys = <&usb3_hs_phy>;
+ phy-names = "usb2-phy";
+};
+
&mdio {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
-
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
+ };
+};
- crypto@8e3a000 {
- status = "okay";
- };
+&watchdog {
+ status = "okay";
+};
- watchdog@b017000 {
- status = "okay";
- };
- };
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
};
&tlmm {
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 59 GPIO_ACTIVE_LOW>;
- reset-delay-us = <2000>;
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
-
gpio_export {
compatible = "gpio-export";
#size-cells = <0>;
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
spi_0_pins: spi_0_pinmux {
mux {
};
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 59 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
status = "okay";
};
+&prng {
+ status = "okay";
+};
+
&watchdog {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
-
- dwc3@6000000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb2_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- usb3_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
status = "okay";
};
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ usb3_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+};
+
&usb2_hs_phy {
status = "okay";
};
+
+&usb2 {
+ status = "okay";
+
+ usb@6000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb2_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+ };
+};
compatible = "plasmacloud,pa1200";
soc {
- rng@22000 {
- status = "okay";
- };
-
tcsr@194b000 {
/* select hostmode */
compatible = "qcom,tcsr";
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- usb3_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&cryptobam {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ usb3_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+};
+
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
};
soc {
- rng@22000 {
- status = "okay";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&qpic_bam {
status = "okay";
};
qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
status = "okay";
};
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- phys = <&usb3_hs_phy>;
- phy-names = "usb2-phy";
- };
- };
};
};
&usb3 {
status = "okay";
};
+
+&usb3_dwc {
+ phys = <&usb3_hs_phy>;
+ phy-names = "usb2-phy";
+};
qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
status = "okay";
};
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- phys = <&usb3_hs_phy>;
- phy-names = "usb2-phy";
- };
- };
};
};
&usb3 {
status = "okay";
};
+
+&usb3_dwc {
+ phys = <&usb3_hs_phy>;
+ phy-names = "usb2-phy";
+};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
leds {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
status = "okay";
};
+&mdio {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
qcom,ath10k-calibration-variant = "ZyXEL-WRE6606";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
+ };
+};
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
+&watchdog {
+ status = "okay";
+};
- crypto@8e3a000 {
- status = "okay";
- };
+&prng {
+ status = "okay";
+};
- watchdog@b017000 {
- status = "okay";
- };
- };
+&crypto {
+ status = "okay";
};
&blsp_dma {
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&usb3_hs_phy {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
nvmem-cell-names = "pre-calibration";
compatible = "openmesh,a62";
soc {
- rng@22000 {
- status = "okay";
- };
-
tcsr@194b000 {
/* select hostmode */
compatible = "qcom,tcsr";
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
- reset-delay-us = <1000>;
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
-
- dwc3@6000000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb2_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- usb3_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
led_spi {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ usb3_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+};
+
&usb2_hs_phy {
status = "okay";
};
+&usb2 {
+ status = "okay";
+
+ usb@6000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb2_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+};
+
&gmac {
status = "okay";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
- serial@78af000 {
- pinctrl-0 = <&serial_0_pins>;
- pinctrl-names = "default";
- status = "okay";
- };
-
- serial@78b0000 {
- pinctrl-0 = <&serial_1_pins>;
- pinctrl-names = "default";
- status = "okay";
- };
-
- i2c@78b7000 { /* BLSP1 QUP2 */
- pinctrl-0 = <&i2c_0_pins>;
- pinctrl-names = "default";
-
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
-
leds {
compatible = "gpio-leds";
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
+&crypto {
+ status = "okay";
+};
+
&cryptobam {
status = "okay";
};
};
};
+&blsp1_uart1 {
+ pinctrl-0 = <&serial_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&blsp1_uart2 {
+ pinctrl-0 = <&serial_1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&blsp1_i2c3 { /* BLSP1 QUP2 */
+ pinctrl-0 = <&i2c_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
&usb3 {
status = "okay";
+};
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
- usb3_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
+ usb3_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
- usb3_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
+ usb3_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
};
};
&usb2 {
status = "okay";
- dwc3@6000000 {
+ usb@6000000 {
#address-cells = <1>;
#size-cells = <0>;
&usb2_hs_phy {
status = "okay";
};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+};
gpios = <&tlmm 50 GPIO_ACTIVE_LOW>;
};
};
+};
- soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
+&watchdog {
+ status = "okay";
+};
- crypto@8e3a000 {
- status = "okay";
- };
+&prng {
+ status = "okay";
+};
- watchdog@b017000 {
- status = "okay";
- };
- };
+&crypto {
+ status = "okay";
};
&blsp_dma {
};
};
+&mdio {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
nvmem-cell-names = "pre-calibration";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb3@8af8800 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_0_pins: serial_pinmux {
mux {
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&qpic_bam {
status = "okay";
};
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
-
- ethphy: ethernet-phy@0 {
- reg = <0x0>;
- };
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
key {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_0_pins: serial_pinmux {
mux {
qcom,ath10k-calibration-variant = "AVM-FRITZRepeater-1200";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ ethphy: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+};
+
&gmac {
status = "okay";
};
phy-mode = "rgmii-id";
};
+&qca807x {
+ status = "disabled";
+};
+
ðphy1 {
status = "disabled";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
key {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_0_pins: serial_pinmux {
mux {
};
};
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
};
keys {
};
};
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&vqmmc {
status = "okay";
};
};
};
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
-
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&vqmmc {
status = "okay";
};
};
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
&usb2 {
status = "okay";
- dwc3@6000000 {
+ usb@6000000 {
#address-cells = <1>;
#size-cells = <0>;
&usb3 {
status = "okay";
+};
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
- usb3_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
+ usb3_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
- usb3_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
+ usb3_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
};
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
};
};
+&mdio {
+ status = "okay";
+
+ ar8035: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&qca807x {
+ status = "disabled";
+};
+
+ðphy0 {
+ status = "disabled";
+};
+
ðphy1 {
status = "disabled";
};
status = "okay";
label = "lan";
- phy-handle = <ðphy0>;
+ phy-handle = <&ar8035>;
phy-mode = "rgmii-id";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&nand {
pinctrl-0 = <&nand_pins>;
pinctrl-names = "default";
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&blsp1_i2c3 {
pinctrl-0 = <&i2c_0_pins>;
pinctrl-names = "default";
status = "okay";
};
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
- reset-delay-us = <2000>;
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
+ };
+};
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
+&watchdog {
+ status = "okay";
+};
- crypto@8e3a000 {
- status = "okay";
- };
+&prng {
+ status = "okay";
+};
- watchdog@b017000 {
- status = "okay";
- };
- };
+&crypto {
+ status = "okay";
};
&blsp_dma {
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+};
+
&gmac {
status = "okay";
nvmem-cell-names = "mac-address";
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&usb3_ss_phy {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
nvmem-cell-names = "pre-calibration", "mac-address";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
- reset-delay-us = <2000>;
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
+ };
+};
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
+&watchdog {
+ status = "okay";
+};
- crypto@8e3a000 {
- status = "okay";
- };
+&prng {
+ status = "okay";
+};
- watchdog@b017000 {
- status = "okay";
- };
- };
+&crypto {
+ status = "okay";
};
&blsp_dma {
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+};
+
&gmac {
status = "okay";
nvmem-cell-names = "mac-address";
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&usb3_ss_phy {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
/*
* The MD5 sum of the board file of the MF286D is identical to the board
* file in the OEM firmware
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
- reset-delay-us = <2000>;
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
+ };
+};
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
+&watchdog {
+ status = "okay";
+};
- crypto@8e3a000 {
- status = "okay";
- };
+&prng {
+ status = "okay";
+};
- watchdog@b017000 {
- status = "okay";
- };
- };
+&crypto {
+ status = "okay";
};
&blsp_dma {
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+};
+
&gmac {
status = "okay";
nvmem-cell-names = "mac-address";
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&usb3_ss_phy {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
nvmem-cell-names = "pre-calibration", "mac-address";
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- dma@7984000 {
- status = "okay";
- };
};
keys-repeat {
pinctrl-0 = <&usb3_pins>, <<e_pins>;
pinctrl-names = "default";
+};
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
- device@1 {
- compatible = "usb1bc7,1900";
- reg = <1>;
- };
+ device@1 {
+ compatible = "usb1bc7,1900";
+ reg = <1>;
};
};
};
soc {
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
status = "okay";
};
-
- usb2@60f8800 {
- status = "okay";
-
- dwc3@6000000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb2_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- usb3_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
key {
};
};
+&watchdog {
+ status = "okay";
+};
+
&tlmm {
serial_0_pins: serial_pinmux {
mux {
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+};
+
&wifi0 {
status = "okay";
nvmem-cell-names = "pre-calibration";
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ usb3_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+};
+
+
&usb2_hs_phy {
status = "okay";
};
+
+&usb2 {
+ status = "okay";
+
+ usb@6000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb2_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+ };
+};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
-
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&vqmmc {
status = "okay";
};
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+};
+
&gmac {
status = "okay";
};
compatible = "plasmacloud,pa2200";
soc {
- rng@22000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_pins: serial_pinmux {
mux {
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
leds {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
};
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+};
+
ðphy0 {
qcom,single-led-1000;
qcom,single-led-100;
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&usb2_hs_phy {
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&vqmmc {
status = "okay";
};
chosen {
bootargs = "root=/dev/mmcblk0p20 blkdevparts=mmcblk0:512K@17K(0:SBL1)ro,512K(0:BOOTCONFIG)ro,512K(0:QSEE)ro,512K(0:QSEE_ALT)ro,256K(0:CDT)ro,256K(0:CDT_ALT)ro,256K(0:DDRPARAMS)ro,256K(0:APPSBLENV)ro,1M(0:APPSBL)ro,1M(0:APPSBL_ALT)ro,256K(0:ART)ro,256K(ARTMTD)ro,2M(language)ro,256K(config)ro,256K(pot)ro,256K(traffic_meter)ro,256K(pot_bak)ro,256K(traffic_meter.bak)ro,3840K(kernel),31488K(rootfs),35328K@9233K(firmware),256K(mtdoops)ro,1457651200(reserved)ro,-(unallocated) rootfstype=squashfs,ext4 rootwait";
};
-
- soc {
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
- };
};
&usb3_hs_phy {
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&usb2_hs_phy {
status = "okay";
};
+
+&usb2 {
+ status = "okay";
+};
chosen {
bootargs = "root=/dev/mmcblk0p20 blkdevparts=mmcblk0:512K@17K(0:SBL1)ro,512K(0:BOOTCONFIG)ro,512K(0:QSEE)ro,512K(0:QSEE_ALT)ro,256K(0:CDT)ro,256K(0:CDT_ALT)ro,256K(0:DDRPARAMS)ro,256K(0:APPSBLENV)ro,1M(0:APPSBL)ro,1M(0:APPSBL_ALT)ro,256K(0:ART)ro,256K(ARTMTD)ro,2M(language)ro,256K(config)ro,256K(pot)ro,256K(traffic_meter)ro,256K(pot_bak)ro,256K(traffic_meter.bak)ro,3840K(kernel),31488K(rootfs),35328K@9233K(firmware),256K(mtdoops)ro,1457651200(reserved)ro,-(unallocated) rootfstype=squashfs,ext4 rootwait";
};
-
- soc {
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
- };
};
&usb3_hs_phy {
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&usb2_hs_phy {
status = "okay";
};
+
+&usb2 {
+ status = "okay";
+};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- usb3_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&cryptobam {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ usb3_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+};
+
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
+ };
+};
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
+&watchdog {
+ status = "okay";
+};
- crypto@8e3a000 {
- status = "okay";
- };
+&prng {
+ status = "okay";
+};
- watchdog@b017000 {
- status = "okay";
- };
- };
+&crypto {
+ status = "okay";
};
&blsp_dma {
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&usb3_ss_phy {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
qcom,ath10k-calibration-variant = "cellc,rtl30vw";
qcom,ath10k-calibration-variant = "cellc,rtl30vw";
};
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
compatible = "unielec,u4019","qcom,ipq4019";
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
- reset-delay-us = <2000>;
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
- usb2@60f8800 {
- status = "okay";
-
- dwc3@6000000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- watchdog@b017000 {
- status = "okay";
- };
-
aliases {
led-boot = &led_status;
led-failsafe = &led_status;
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ usb3_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+};
+
+
&usb2_hs_phy {
status = "okay";
};
+&usb2 {
+ status = "okay";
+
+ usb@6000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb2_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+};
+
&wifi0 {
status = "okay";
nvmem-cell-names = "pre-calibration";
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "qcom-ipq4019-whw03.dtsi"
+
+/ {
+ model = "Linksys WHW03 (Velop)";
+ compatible = "linksys,whw03", "qcom,ipq4019";
+
+ // Default bootargs include rootfstype=ext4 and need to be overriden.
+ chosen {
+ bootargs-append = " rootfstype=squashfs";
+ };
+};
+
+&tlmm {
+ sd_pins: sd-pinmux {
+ pins = "gpio23", "gpio24", "gpio25", "gpio26",
+ "gpio27", "gpio28", "gpio29", "gpio30",
+ "gpio31", "gpio32";
+ function = "sdio";
+ };
+
+ i2c_0_pins: i2c-0-pinmux {
+ pins = "gpio58", "gpio59";
+ function = "blsp_i2c0";
+ bias-disable;
+ };
+
+ spi_0_pins: spi-0-pinmux {
+ pins = "gpio12", "gpio13", "gpio14", "gpio15";
+ function = "blsp_spi0";
+ bias-disable;
+ };
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ reset-gpios = <&tlmm 41 GPIO_ACTIVE_LOW>;
+};
+
+&vqmmc {
+ status = "okay";
+};
+
+&sdhci {
+ status = "okay";
+ pinctrl-0 = <&sd_pins>;
+ pinctrl-names = "default";
+
+ cd-gpios = <&tlmm 22 GPIO_ACTIVE_LOW>;
+ sd-ldo-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>;
+
+ vqmmc-supply = <&vqmmc>;
+};
+
+&wifi0 {
+ qcom,ath10k-calibration-variant = "linksys-whw03";
+};
+
+&wifi1 {
+ qcom,ath10k-calibration-variant = "linksys-whw03";
+};
+
+&wifi2 {
+ reg = <0x00000000 0 0 0 0>;
+
+ qcom,ath10k-calibration-variant = "linksys-whw03";
+};
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "qcom-ipq4019.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/soc/qcom,tcsr.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ aliases {
+ led-boot = &led_blue;
+ led-failsafe = &led_red;
+ led-running = &led_blue;
+ led-upgrade = &led_red;
+ };
+
+ soc {
+ ess-tcsr@1953000 {
+ compatible = "qcom,tcsr";
+ reg = <0x1953000 0x1000>;
+ qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
+ };
+
+
+ tcsr@1949000 {
+ compatible = "qcom,tcsr";
+ reg = <0x1949000 0x100>;
+ qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
+ };
+
+ tcsr@194b000 {
+ compatible = "qcom,tcsr";
+ reg = <0x194b000 0x100>;
+ qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
+ };
+
+ tcsr@1957000 {
+ compatible = "qcom,tcsr";
+ reg = <0x1957000 0x100>;
+ qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+};
+
+&tlmm {
+ mdio_pins: mdio-pinmux {
+ mux-1 {
+ pins = "gpio6";
+ function = "mdio";
+ bias-pull-up;
+ };
+
+ mux-2 {
+ pins = "gpio7";
+ function = "mdc";
+ bias-pull-up;
+ };
+ };
+
+ serial_0_pins: serial0-pinmux {
+ pins = "gpio16", "gpio17";
+ function = "blsp_uart0";
+ bias-disable;
+ };
+
+ serial_1_pins: serial1-pinmux {
+ pins = "gpio8", "gpio9", "gpio10", "gpio11";
+ function = "blsp_uart1";
+ bias-disable;
+ };
+
+ spi_1_pins: spi-1-pinmux {
+ mux-1 {
+ pins = "gpio44", "gpio46", "gpio47";
+ function = "blsp_spi1";
+ bias-disable;
+ };
+
+ mux-2 {
+ pins = "gpio45", "gpio49";
+ function = "gpio";
+ bias-pull-up;
+ output-high;
+ };
+
+ host-interrupt {
+ pins = "gpio42";
+ function = "gpio";
+ input;
+ };
+ };
+
+ wifi_0_pins: wifi0-pinmux {
+ pins = "gpio52";
+ function = "gpio";
+ drive-strength = <6>;
+ bias-pull-up;
+ output-high;
+ };
+
+ zigbee-0 {
+ gpio-hog;
+ gpios = <29 GPIO_ACTIVE_HIGH>;
+ bias-disable;
+ output-low;
+ };
+
+ zigbee-1 {
+ gpio-hog;
+ gpios = <50 GPIO_ACTIVE_HIGH>;
+ bias-disable;
+ input;
+ };
+
+ bluetooth-enable {
+ gpio-hog;
+ gpios = <32 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+};
+
+ðphy0 {
+ status = "disabled";
+};
+
+ðphy1 {
+ status = "disabled";
+};
+
+ðphy2 {
+ status = "disabled";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&blsp_dma {
+ status = "okay";
+};
+
+&cryptobam {
+ status = "okay";
+ num-channels = <4>;
+ qcom,num-ees = <2>;
+};
+
+&crypto {
+ status = "okay";
+};
+
+&blsp1_uart1 {
+ status = "okay";
+ pinctrl-0 = <&serial_0_pins>;
+ pinctrl-names = "default";
+};
+
+&blsp1_uart2 {
+ status = "okay";
+ pinctrl-0 = <&serial_1_pins>;
+ pinctrl-names = "default";
+
+ bluetooth {
+ compatible = "csr,8811";
+
+ enable-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&blsp1_spi2 {
+ status = "okay";
+ pinctrl-0 = <&spi_1_pins>;
+ pinctrl-names = "default";
+
+ cs-gpios = <&tlmm 45 GPIO_ACTIVE_HIGH>;
+
+ zigbee@0 {
+ compatible = "silabs,em3581";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-max-frequency = <12000000>;
+ };
+};
+
+&blsp1_i2c3 {
+ status = "okay";
+ pinctrl-0 = <&i2c_0_pins>;
+ pinctrl-names = "default";
+
+ // RGB LEDs
+ pca9633: led-controller@62 {
+ compatible = "nxp,pca9633";
+ nxp,hw-blink;
+ reg = <0x62>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led_red: red@0 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_INDICATOR;
+ reg = <0>;
+ };
+
+ led_green: green@1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
+ reg = <1>;
+ };
+
+ led_blue: blue@2 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_INDICATOR;
+ reg = <2>;
+ };
+ };
+};
+
+&pcie0 {
+ status = "okay";
+
+ perst-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 40 GPIO_ACTIVE_LOW>;
+ clkreq-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
+
+ bridge@0,0 {
+ reg = <0x00000000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ wifi2: wifi@1,0 {
+ compatible = "qcom,ath10k";
+ };
+ };
+};
+
+&qpic_bam {
+ status = "okay";
+};
+
+&gmac {
+ status = "okay";
+};
+
+&switch {
+ status = "okay";
+};
+
+&swport4 {
+ status = "okay";
+ label = "lan";
+};
+
+&swport5 {
+ status = "okay";
+ label = "wan";
+};
+
+&wifi0 {
+ status = "okay";
+ pinctrl-0 = <&wifi_0_pins>;
+ pinctrl-names = "default";
+
+ qcom,coexist-support = <1>;
+ qcom,coexist-gpio-pin = <52>;
+};
+
+&wifi1 {
+ status = "okay";
+
+ ieee80211-freq-limit = <5170000 5330000>;
+};
+
+&wifi2 {
+ status = "okay";
+
+ ieee80211-freq-limit = <5490000 5835000>;
+};
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include "qcom-ipq4019.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/soc/qcom,tcsr.h>
-#include <dt-bindings/leds/common.h>
+#include "qcom-ipq4019-whw03.dtsi"
/ {
model = "Linksys WHW03 V2 (Velop)";
compatible = "linksys,whw03v2", "qcom,ipq4019";
- aliases {
- led-boot = &led_blue;
- led-failsafe = &led_red;
- led-running = &led_blue;
- led-upgrade = &led_red;
- };
-
- // The arguments rootfstype and ro are needed
- // to override the default bootargs
+ // Default bootargs include rootfstype=ext4 and need to be overriden.
chosen {
bootargs-append = " root=/dev/ubiblock0_0 rootfstype=squashfs ro";
stdout-path = &blsp1_uart1;
};
-
- soc {
- ess-tcsr@1953000 {
- compatible = "qcom,tcsr";
- reg = <0x1953000 0x1000>;
- qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
- };
-
-
- tcsr@1949000 {
- compatible = "qcom,tcsr";
- reg = <0x1949000 0x100>;
- qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
- };
-
- tcsr@194b000 {
- compatible = "qcom,tcsr";
- reg = <0x194b000 0x100>;
- qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
- };
-
- tcsr@1957000 {
- compatible = "qcom,tcsr";
- reg = <0x1957000 0x100>;
- qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
- };
- };
-
-
- keys {
- compatible = "gpio-keys";
-
- reset {
- label = "reset";
- gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_RESTART>;
- };
- };
};
-
&tlmm {
- mdio_pins: mdio-pinmux {
- mux-1 {
- pins = "gpio6";
- function = "mdio";
- bias-pull-up;
- };
-
- mux-2 {
- pins = "gpio7";
- function = "mdc";
- bias-pull-up;
- };
- };
-
i2c_0_pins: i2c-0-pinmux {
- mux {
- function = "blsp_i2c0";
- pins = "gpio20", "gpio21";
- bias-disable;
- };
- };
-
- serial_0_pins: serial0-pinmux {
- mux {
- pins = "gpio16", "gpio17";
- function = "blsp_uart0";
- bias-disable;
- };
- };
-
- serial_1_pins: serial1-pinmux {
- mux {
- pins = "gpio8", "gpio9", "gpio10", "gpio11";
- function = "blsp_uart1";
- bias-disable;
- };
+ pins = "gpio20", "gpio21";
+ function = "blsp_i2c0";
+ bias-disable;
};
spi_0_pins: spi-0-pinmux {
mux {
- function = "blsp_spi0";
pins = "gpio13", "gpio14", "gpio15";
+ function = "blsp_spi0";
drive-strength = <12>;
bias-disable;
};
output-high;
};
};
+};
- spi_1_pins: spi-1-pinmux {
- mux-1 {
- function = "blsp_spi1";
- pins = "gpio44", "gpio46","gpio47";
- bias-disable;
- };
-
- mux-2 {
- pins = "gpio31", "gpio45", "gpio49";
- function = "gpio";
- bias-pull-up;
- output-high;
- };
-
- host-interrupt {
- pins = "gpio42";
- function = "gpio";
- input;
- };
- };
-
- wifi_0_pins: wifi0-pinmux {
- btcoexist {
- bias-pull-up;
- drive-strength = <6>;
- function = "gpio";
- output-high;
- pins = "gpio52";
- };
- };
-
- zigbee-0 {
- gpio-hog;
- gpios = <29 GPIO_ACTIVE_HIGH>;
- bias-disable;
- output-low;
- };
-
- zigbee-1 {
- gpio-hog;
- gpios = <50 GPIO_ACTIVE_HIGH>;
- bias-disable;
- input;
- };
-
- bluetooth-enable {
- gpio-hog;
- gpios = <32 GPIO_ACTIVE_HIGH>;
+&spi_1_pins {
+ mux-wake {
+ pins = "gpio31";
+ function = "gpio";
+ bias-pull-up;
output-high;
};
};
status = "okay";
pinctrl-0 = <&mdio_pins>;
pinctrl-names = "default";
- phy-reset-gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
-};
-
-ðphy0 {
- status = "disabled";
-};
-ðphy1 {
- status = "disabled";
-};
-
-ðphy2 {
- status = "disabled";
+ phy-reset-gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
};
ðphy3 {
reg = <0x1d>;
};
-&watchdog {
- status = "okay";
-};
-
-&prng {
- status = "okay";
-};
-
-&blsp_dma {
- status = "okay";
-};
-
-&cryptobam {
- num-channels = <4>;
- qcom,num-ees = <2>;
-
- status = "okay";
-};
-
-&crypto {
- status = "okay";
-};
-
-&blsp1_uart1 {
- status = "okay";
- pinctrl-0 = <&serial_0_pins>;
- pinctrl-names = "default";
-};
-
-&blsp1_uart2 {
- status = "okay";
- pinctrl-0 = <&serial_1_pins>;
- pinctrl-names = "default";
-
- bluetooth {
- compatible = "csr,8811";
-
- enable-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
- };
-};
-
-&blsp1_spi2 {
- pinctrl-0 = <&spi_1_pins>;
- pinctrl-names = "default";
- status = "okay";
-
- cs-gpios = <&tlmm 45 GPIO_ACTIVE_HIGH>;
-
- zigbee@0 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- compatible = "silabs,em3581";
- reg = <0>;
- spi-max-frequency = <12000000>;
- };
-};
-
-&blsp1_i2c3 {
- pinctrl-0 = <&i2c_0_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-
- // RGB LEDs
- pca9633: led-controller@62 {
- compatible = "nxp,pca9633";
- nxp,hw-blink;
- reg = <0x62>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- led_red: red@0 {
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_INDICATOR;
- reg = <0>;
- };
-
- led_green: green@1 {
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_INDICATOR;
- reg = <1>;
- };
-
- led_blue: blue@2 {
- color = <LED_COLOR_ID_BLUE>;
- function = LED_FUNCTION_INDICATOR;
- reg = <2>;
- };
- };
-};
-
&usb3_ss_phy {
status = "okay";
};
};
};
-&pcie0 {
- status = "okay";
-
- perst-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
- wake-gpios = <&tlmm 40 GPIO_ACTIVE_LOW>;
- clkreq-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
-
- bridge@0,0 {
- reg = <0x00000000 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
- ranges;
-
- wifi2: wifi@1,0 {
- compatible = "qcom,ath10k";
- reg = <0x00010000 0 0 0 0>;
- };
- };
-};
-
-&qpic_bam {
- status = "okay";
-};
-
-&gmac {
- status = "okay";
-};
-
-&switch {
- status = "okay";
-};
-
&swport4 {
- status = "okay";
- label = "lan";
-
nvmem-cell-names = "mac-address";
nvmem-cells = <&macaddr_gmac1>;
};
&swport5 {
- status = "okay";
- label = "wan";
-
nvmem-cell-names = "mac-address";
nvmem-cells = <&macaddr_gmac0 0>;
};
&wifi0 {
- pinctrl-0 = <&wifi_0_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-
- qcom,coexist-support = <1>;
- qcom,coexist-gpio-pin = <0x34>;
-
qcom,ath10k-calibration-variant = "linksys-whw03v2";
nvmem-cell-names = "pre-calibration", "mac-address";
};
&wifi1 {
- status = "okay";
-
- ieee80211-freq-limit = <5170000 5330000>;
qcom,ath10k-calibration-variant = "linksys-whw03v2";
nvmem-cell-names = "pre-calibration", "mac-address";
};
&wifi2 {
- status = "okay";
+ reg = <0x00010000 0 0 0 0>;
- ieee80211-freq-limit = <5490000 5835000>;
qcom,ath10k-calibration-variant = "linksys-whw03v2";
nvmem-cell-names = "pre-calibration", "mac-address";
};
soc {
- pinctrl@1000000 {
- mdio_pins: mdio_pinmux {
- mux_1 {
- pins = "gpio6";
- function = "mdio";
- bias-pull-up;
- };
-
- mux_2 {
- pins = "gpio7";
- function = "mdc";
- bias-pull-up;
- };
- };
-
- serial_0_pins: serial_pinmux {
- mux {
- pins = "gpio16", "gpio17";
- function = "blsp_uart0";
- bias-disable;
- };
- };
-
- serial_1_pins: serial1_pinmux {
- mux {
- pins = "gpio8", "gpio9", "gpio10", "gpio11";
- function = "blsp_uart1";
- bias-disable;
- };
- };
-
- spi_0_pins: spi_0_pinmux {
- pinmux {
- function = "blsp_spi0";
- pins = "gpio13", "gpio14", "gpio15";
- bias-disable;
- };
-
- pinmux_cs {
- function = "gpio";
- pins = "gpio12";
- bias-disable;
- output-high;
- };
- };
-
- i2c_0_pins: i2c_0_pinmux {
- mux {
- pins = "gpio20", "gpio21";
- function = "blsp_i2c0";
- bias-disable;
- };
- };
-
- nand_pins: nand_pins {
- pullups {
- pins = "gpio52", "gpio53", "gpio58", "gpio59";
- function = "qpic";
- bias-pull-up;
- };
-
- pulldowns {
- pins = "gpio54", "gpio55", "gpio56",
- "gpio57", "gpio60", "gpio61",
- "gpio62", "gpio63", "gpio64",
- "gpio65", "gpio66", "gpio67",
- "gpio68", "gpio69";
- function = "qpic";
- bias-pull-down;
- };
- };
-
- led_0_pins: led0_pinmux {
- mux_1 {
- pins = "gpio36";
- function = "led0";
- bias-pull-down;
- };
- mux_2 {
- pins = "gpio40";
- function = "led4";
- bias-pull-down;
- };
- };
- };
-
- blsp_dma: dma@7884000 {
- status = "okay";
- };
-
- spi_0: spi@78b5000 {
- pinctrl-0 = <&spi_0_pins>;
- pinctrl-names = "default";
- status = "okay";
- cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>, <&tlmm 41 GPIO_ACTIVE_HIGH>;
- num-cs = <2>;
-
- flash0@0 {
- reg = <0>;
- compatible = "jedec,spi-nor";
- spi-max-frequency = <24000000>;
- broken-flash-reset;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "0:SBL1";
- reg = <0x000000 0x040000>;
- read-only;
- };
-
- partition@40000 {
- label = "0:MIBIB";
- reg = <0x040000 0x020000>;
- read-only;
- };
-
- partition@60000 {
- label = "0:QSEE";
- reg = <0x060000 0x060000>;
- read-only;
- };
-
- partition@c0000 {
- label = "0:CDT";
- reg = <0x0c0000 0x010000>;
- read-only;
- };
-
- partition@d0000 {
- label = "0:DDRPARAMS";
- reg = <0x0d0000 0x010000>;
- read-only;
- };
-
- partition@e0000 {
- label = "u-boot-env";
- reg = <0x0e0000 0x010000>;
- };
-
- partition@f0000 {
- label = "u-boot";
- reg = <0x0f0000 0x080000>;
- read-only;
- };
-
- partition@170000 {
- label = "0:ART";
- reg = <0x170000 0x010000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- precal_art_1000: precal@1000 {
- reg = <0x1000 0x2f20>;
- };
-
- precal_art_5000: precal@5000 {
- reg = <0x5000 0x2f20>;
- };
- };
- };
- };
- };
-
- nand@1 {
- reg = <1>;
- status = "okay";
- compatible = "spi-nand";
- spi-max-frequency = <24000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- /* The device has 128MB, but we can only address
- * 64MB because of the bootloader's default settings.
- * This is due to the old mt29f driver,
- * which detected the deivce with only 64MB
- */
- partition@0 {
- label = "ubi";
- reg = <0x0000000 0x4000000>;
- };
- };
- };
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
- reset-delay-us = <5000>;
- };
-
tcsr@194b000 {
/* select hostmode */
compatible = "qcom,tcsr";
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
+ };
- i2c_0: i2c@78b7000 {
- pinctrl-0 = <&i2c_0_pins>;
- pinctrl-names = "default";
- status = "okay";
- };
+ keys {
+ compatible = "gpio-keys";
- serial@78af000 {
- pinctrl-0 = <&serial_0_pins>;
- pinctrl-names = "default";
- status = "okay";
+ reset {
+ label = "reset";
+ gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
};
+ };
+};
- serial@78b0000 {
- pinctrl-0 = <&serial_1_pins>;
- pinctrl-names = "default";
- status = "okay";
+&tlmm {
+ mdio_pins: mdio_pinmux {
+ mux_1 {
+ pins = "gpio6";
+ function = "mdio";
+ bias-pull-up;
};
- usb3_ss_phy: ssphy@9a000 {
- status = "okay";
+ mux_2 {
+ pins = "gpio7";
+ function = "mdc";
+ bias-pull-up;
};
+ };
- usb3_hs_phy: hsphy@a6000 {
- status = "okay";
+ serial_0_pins: serial_pinmux {
+ mux {
+ pins = "gpio16", "gpio17";
+ function = "blsp_uart0";
+ bias-disable;
};
+ };
- usb3: usb3@8af8800 {
- status = "okay";
+ serial_1_pins: serial1_pinmux {
+ mux {
+ pins = "gpio8", "gpio9", "gpio10", "gpio11";
+ function = "blsp_uart1";
+ bias-disable;
};
+ };
- usb2_hs_phy: hsphy@a8000 {
- status = "okay";
+ spi_0_pins: spi_0_pinmux {
+ pinmux {
+ function = "blsp_spi0";
+ pins = "gpio13", "gpio14", "gpio15";
+ bias-disable;
};
- usb2: usb2@60f8800 {
- status = "okay";
+ pinmux_cs {
+ function = "gpio";
+ pins = "gpio12";
+ bias-disable;
+ output-high;
};
+ };
- cryptobam: dma@8e04000 {
- status = "okay";
+ i2c_0_pins: i2c_0_pinmux {
+ mux {
+ pins = "gpio20", "gpio21";
+ function = "blsp_i2c0";
+ bias-disable;
};
+ };
- crypto@8e3a000 {
- status = "okay";
+ nand_pins: nand_pins {
+ pullups {
+ pins = "gpio52", "gpio53", "gpio58", "gpio59";
+ function = "qpic";
+ bias-pull-up;
};
- watchdog@b017000 {
- status = "okay";
+ pulldowns {
+ pins = "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio60", "gpio61",
+ "gpio62", "gpio63", "gpio64",
+ "gpio65", "gpio66", "gpio67",
+ "gpio68", "gpio69";
+ function = "qpic";
+ bias-pull-down;
};
+ };
- qpic_bam: dma@7984000 {
- status = "okay";
+ led_0_pins: led0_pinmux {
+ mux_1 {
+ pins = "gpio36";
+ function = "led0";
+ bias-pull-down;
};
-
- pcie0: pci@40000000 {
- status = "okay";
- perst-gpio = <&tlmm 38 GPIO_ACTIVE_LOW>;
- wake-gpio = <&tlmm 50 GPIO_ACTIVE_LOW>;
+ mux_2 {
+ pins = "gpio40";
+ function = "led4";
+ bias-pull-down;
};
};
+};
- keys {
- compatible = "gpio-keys";
+&blsp_dma {
+ status = "okay";
+};
- reset {
- label = "reset";
- gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_RESTART>;
+&blsp1_uart1 {
+ pinctrl-0 = <&serial_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&blsp1_uart2 {
+ pinctrl-0 = <&serial_1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&blsp1_i2c3 {
+ pinctrl-0 = <&i2c_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&blsp1_spi1 {
+ pinctrl-0 = <&spi_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>, <&tlmm 41 GPIO_ACTIVE_HIGH>;
+ num-cs = <2>;
+
+ flash0@0 {
+ reg = <0>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <24000000>;
+ broken-flash-reset;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "0:SBL1";
+ reg = <0x000000 0x040000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "0:MIBIB";
+ reg = <0x040000 0x020000>;
+ read-only;
+ };
+
+ partition@60000 {
+ label = "0:QSEE";
+ reg = <0x060000 0x060000>;
+ read-only;
+ };
+
+ partition@c0000 {
+ label = "0:CDT";
+ reg = <0x0c0000 0x010000>;
+ read-only;
+ };
+
+ partition@d0000 {
+ label = "0:DDRPARAMS";
+ reg = <0x0d0000 0x010000>;
+ read-only;
+ };
+
+ partition@e0000 {
+ label = "u-boot-env";
+ reg = <0x0e0000 0x010000>;
+ };
+
+ partition@f0000 {
+ label = "u-boot";
+ reg = <0x0f0000 0x080000>;
+ read-only;
+ };
+
+ partition@170000 {
+ label = "0:ART";
+ reg = <0x170000 0x010000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ precal_art_1000: precal@1000 {
+ reg = <0x1000 0x2f20>;
+ };
+
+ precal_art_5000: precal@5000 {
+ reg = <0x5000 0x2f20>;
+ };
+ };
+ };
+ };
+ };
+
+ nand@1 {
+ reg = <1>;
+ status = "okay";
+ compatible = "spi-nand";
+ spi-max-frequency = <24000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* The device has 128MB, but we can only address
+ * 64MB because of the bootloader's default settings.
+ * This is due to the old mt29f driver,
+ * which detected the deivce with only 64MB
+ */
+ partition@0 {
+ label = "ubi";
+ reg = <0x0000000 0x4000000>;
+ };
};
};
};
+&watchdog {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
+&cryptobam {
+ status = "okay";
+};
+
+&usb3_ss_phy {
+ status = "okay";
+};
+
+&usb3_hs_phy {
+ status = "okay";
+};
+
+&usb3 {
+ status = "okay";
+};
+
+&usb2_hs_phy {
+ status = "okay";
+};
+
+&usb2 {
+ status = "okay";
+};
+
+&qpic_bam {
+ status = "okay";
+};
+
&nand {
pinctrl-0 = <&nand_pins>;
pinctrl-names = "default";
status = "okay";
};
+&pcie0 {
+ status = "okay";
+ perst-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 50 GPIO_ACTIVE_LOW>;
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <5000>;
+};
+
&wifi0 {
status = "okay";
nvmem-cell-names = "pre-calibration";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
};
leds {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
serial_0_pins: serial0_pinmux {
mux {
&usb3_hs_phy {
status = "okay";
};
+
+&usb3 {
+ status = "okay";
+};
};
soc {
-
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
- reset-delay-us = <2000>;
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
- usb2@60f8800 {
- status = "okay";
-
- dwc3@6000000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- watchdog@b017000 {
- status = "okay";
- };
-
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+};
+
&usb2_hs_phy {
status = "okay";
};
+&usb2 {
+ status = "okay";
+
+ usb@6000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+};
+
&wifi0 {
status = "okay";
nvmem-cell-names = "pre-calibration";
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
-
- dwc3@6000000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb2_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- usb3@8af8800 {
- status = "okay";
-
- dwc3@8a00000 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- usb3_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
- };
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
regulator-usb-vbus {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
&blsp_dma {
status = "okay";
status = "okay";
};
+&usb2 {
+ status = "okay";
+
+ usb@6000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb2_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+ };
+};
+
&usb3_hs_phy {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb3_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ usb3_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+};
+
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- reset-gpios = <&tlmm 59 GPIO_ACTIVE_LOW>;
- reset-delay-us = <2000>;
- };
-
tcsr@194b000 {
/* select hostmode */
compatible = "qcom,tcsr";
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&tlmm {
mdio_pins: mdio_pinmux {
mux_1 {
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 59 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
-
- reset-gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
- reset-delay-us = <2000>;
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
-
- i2c_0: i2c@78b7000 {
- pinctrl-0 = <&i2c_0_pins>;
- pinctrl-names = "default";
- status = "okay";
-
- tpm@29 {
- /* No Driver */
- compatible = "atmel,at97sc3203";
- reg = <0x29>;
- read-only;
- };
-
- power-monitor@40 {
- /* No driver */
- compatible = "isl,isl28022";
- reg = <0x40>;
- };
- };
};
leds {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
pins = "gpio20", "gpio21";
function = "blsp_i2c0";
drive-strength = <4>;
- bias-disable;
+ bias-pull-up;
};
};
};
};
+&blsp1_i2c3 {
+ pinctrl-0 = <&i2c_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ clock-frequency = <400000>;
+
+ tpm@29 {
+ /* No Driver */
+ compatible = "atmel,at97sc3203";
+ reg = <0x29>;
+ read-only;
+ };
+
+ power-monitor@40 {
+ /* No driver */
+ /* Device also replies on address 0x3f, see */
+ /* ISL28022 datasheet, "Broadcast Addressing" */
+ compatible = "isl,isl28022";
+ reg = <0x40>;
+ };
+};
+
&blsp1_spi1 {
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ reset-gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+};
+
&gmac {
status = "okay";
};
};
-&i2c_0 {
+&blsp1_i2c3 {
power-monitor@40 {
/* No driver */
compatible = "isl,isl28022";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
-
- ethphy: ethernet-phy@5 {
- reg = <0x5>;
- };
- };
-
counter@4a1000 {
compatible = "qcom,qca-gcnt";
reg = <0x4a1000 0x4>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
-
- i2c_0: i2c@78b7000 {
- pinctrl-0 = <&i2c_0_pins>;
- pinctrl-names = "default";
- status = "okay";
-
- tpm@29 {
- /* No Driver */
- compatible = "atmel,at97sc3203";
- reg = <0x29>;
- read-only;
- };
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
status = "okay";
};
+&blsp1_i2c3 {
+ pinctrl-0 = <&i2c_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ tpm@29 {
+ /* No Driver */
+ compatible = "atmel,at97sc3203";
+ reg = <0x29>;
+ read-only;
+ };
+};
+
&cryptobam {
status = "okay";
};
};
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ ethphy: ethernet-phy@5 {
+ reg = <0x5>;
+ };
+};
+
&gmac {
status = "okay";
};
phy-mode = "rgmii-id";
};
+&qca807x {
+ status = "disabled";
+};
+
ðphy0 {
status = "disabled";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&usb3_hs_phy {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+};
+
&gmac {
status = "okay";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- usb2@60f8800 {
- status = "okay";
- };
-
- usb3@8af8800 {
- status = "okay";
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&vqmmc {
status = "okay";
};
status = "okay";
};
+&usb2 {
+ status = "okay";
+};
+
&usb3_hs_phy {
status = "okay";
};
status = "okay";
};
+&usb3 {
+ status = "okay";
+};
+
+&mdio {
+ status = "okay";
+};
+
&wifi0 {
status = "okay";
nvmem-cell-names = "pre-calibration";
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- };
-
/* It is a 56-bit counter that supplies the count to the ARM arch
timers and without upstream driver */
counter@4a1000 {
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- serial@78b0000 {
- pinctrl-0 = <&serial_1_pins>;
- pinctrl-names = "default";
- status = "okay";
-
- bluetooth {
- compatible = "ti,cc2650";
- enable-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
- };
- };
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
keys {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
status = "okay";
};
+&blsp1_uart2 {
+ pinctrl-0 = <&serial_1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ bluetooth {
+ compatible = "ti,cc2650";
+ enable-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
+ };
+};
+
&cryptobam {
status = "okay";
};
nvmem-cell-names = "mac-address";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+
+ ar8035: ethernet-phy@1 {
+ reg = <1>;
+ };
+};
+
&gmac {
status = "okay";
nvmem-cells = <&mac_address 0>;
status = "okay";
label = "lan";
- phy-handle = <ðphy1>;
+ phy-handle = <&ar8035>;
phy-mode = "rgmii-rxid";
};
+&qca807x {
+ status = "disabled";
+};
+
ðphy0 {
status = "disabled";
};
+ðphy1 {
+ status = "disabled";
+};
+
ðphy2 {
status = "disabled";
};
};
soc {
- rng@22000 {
- status = "okay";
- };
-
- mdio@90000 {
- status = "okay";
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
- };
-
tcsr@1949000 {
compatible = "qcom,tcsr";
reg = <0x1949000 0x100>;
reg = <0x1957000 0x100>;
qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
};
-
- crypto@8e3a000 {
- status = "okay";
- };
-
- watchdog@b017000 {
- status = "okay";
- };
};
leds {
};
};
+&watchdog {
+ status = "okay";
+};
+
+&prng {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
&blsp_dma {
status = "okay";
};
status = "okay";
};
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+};
+
&gmac {
status = "okay";
};
IMAGE_SIZE := 25344k
IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata
endef
-# Missing DSA Setup
-#TARGET_DEVICES += engenius_eap1300
+TARGET_DEVICES += engenius_eap1300
define Device/engenius_eap2200
$(call Device/FitImage)
endef
TARGET_DEVICES += linksys_mr8300
+define Device/linksys_whw03
+ $(call Device/FitzImage)
+ DEVICE_VENDOR := Linksys
+ DEVICE_MODEL := WHW03
+ SOC := qcom-ipq4019
+ KERNEL_SIZE := 8192k
+ IMAGE_SIZE := 131072k
+ 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
+endef
+TARGET_DEVICES += linksys_whw03
+
define Device/linksys_whw03v2
$(call Device/FitzImage)
DEVICE_VENDOR := Linksys
status = "disabled";
- ethphy0: ethernet-phy@0 {
-+ ethernet-phy-package@0 {
++ qca807x: ethernet-phy-package@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,qca8075-package";
};
aliases {
- led-boot = &ledctrl3;
+ led-boot = &ledctrl1;
led-failsafe = &ledctrl1;
- led-running = &ledctrl2;
- led-upgrade = &ledctrl3;
+ led-running = &ledctrl3;
+ led-upgrade = &ledctrl1;
};
chosen {
ledctrl2: ledctrl2 {
label = "ledctrl2";
gpios = <&qcom_pinmux 23 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
};
ledctrl3: ledctrl3 {
gpios = <&qcom_pinmux 19 GPIO_ACTIVE_HIGH>;
};
- lan2_green {
- label = "green:lan2";
+ lan1_green {
+ label = "green:lan1";
gpios = <&qcom_pinmux 23 GPIO_ACTIVE_HIGH>;
};
- lan1_green {
- label = "green:lan1";
+ lan2_green {
+ label = "green:lan2";
gpios = <&qcom_pinmux 24 GPIO_ACTIVE_HIGH>;
};
gpios = <&qcom_pinmux 26 GPIO_ACTIVE_LOW>;
};
- lan2_orange {
- label = "orange:lan2";
+ lan1_orange {
+ label = "orange:lan1";
gpios = <&qcom_pinmux 60 GPIO_ACTIVE_HIGH>;
};
- lan1_orange {
- label = "orange:lan1";
+ lan2_orange {
+ label = "orange:lan2";
gpios = <&qcom_pinmux 62 GPIO_ACTIVE_HIGH>;
};
};
+++ /dev/null
-From 9732c4f2d93a4a39ffc903c88ab7d531a8bb2e74 Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Wed, 20 Mar 2024 00:47:58 +0100
-Subject: [PATCH] mtd: rawnand: qcom: Fix broken misc_cmd_type in exec_op
-
-misc_cmd_type in exec_op have multiple problems. With commit a82990c8a409
-("mtd: rawnand: qcom: Add read/read_start ops in exec_op path") it was
-reworked and generalized but actually dropped the handling of the
-RESET_DEVICE command.
-
-Also additional logic was added without clear explaination causing the
-erase command to be broken on testing it on a ipq806x nandc.
-
-Add some additional logic to restore RESET_DEVICE command handling and
-fix erase command.
-
-Fixes: a82990c8a409 ("mtd: rawnand: qcom: Add read/read_start ops in exec_op path")
-Cc: stable@vger.kernel.org
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- drivers/mtd/nand/raw/qcom_nandc.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
---- a/drivers/mtd/nand/raw/qcom_nandc.c
-+++ b/drivers/mtd/nand/raw/qcom_nandc.c
-@@ -2815,7 +2815,7 @@ static int qcom_misc_cmd_type_exec(struc
- host->cfg0_raw & ~(7 << CW_PER_PAGE));
- nandc_set_reg(chip, NAND_DEV0_CFG1, host->cfg1_raw);
- instrs = 3;
-- } else {
-+ } else if (q_op.cmd_reg != OP_RESET_DEVICE) {
- return 0;
- }
-
-@@ -2830,9 +2830,8 @@ static int qcom_misc_cmd_type_exec(struc
- nandc_set_reg(chip, NAND_EXEC_CMD, 1);
-
- write_reg_dma(nandc, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL);
-- (q_op.cmd_reg == OP_BLOCK_ERASE) ? write_reg_dma(nandc, NAND_DEV0_CFG0,
-- 2, NAND_BAM_NEXT_SGL) : read_reg_dma(nandc,
-- NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
-+ if (q_op.cmd_reg == OP_BLOCK_ERASE)
-+ write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
-
- write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
- read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
SUBTARGETS:=xrx200 xway xway_legacy falcon ase
KERNEL_PATCHVER:=5.15
+KERNEL_TESTING_PATCHVER:=6.1
define Target/Description
Build firmware images for Lantiq SoC
# CONFIG_CPU_MIPS32_R2 is not set
CONFIG_CPU_MIPSR1=y
CONFIG_CRC16=y
-CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_NLS=y
CONFIG_SGL_ALLOC=y
CONFIG_SOC_AMAZON_SE=y
-CONFIG_SOC_TYPE_XWAY=y
+# CONFIG_SOC_XWAY is not set
CONFIG_SWCONFIG=y
CONFIG_TARGET_ISA_REV=1
CONFIG_USB=y
--- /dev/null
+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
CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
-CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
-CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
-CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
-CONFIG_ARCH_HAS_RESET_CONTROLLER=y
-CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
-CONFIG_ARCH_HAS_UNCACHED_SEGMENT=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_SUPPORTS_UPROBES=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_USE_BUILTIN_BSWAP=y
-CONFIG_ARCH_USE_MEMREMAP_PROT=y
-CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
-CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
-CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
-CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_CEVT_R4K=y
-CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_LOAD_STORE_LR=y
+CONFIG_CPU_HAS_DIEI=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_RIXI=y
CONFIG_CPU_HAS_SYNC=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_CRYPTO_RNG2=y
CONFIG_CSRC_R4K=y
CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
CONFIG_DTC=y
# CONFIG_DT_EASY50712 is not set
CONFIG_EARLY_PRINTK=y
-CONFIG_EFI_EARLYCON=y
CONFIG_FIXED_PHY=y
-CONFIG_FONT_8x16=y
-CONFIG_FONT_AUTOSELECT=y
-CONFIG_FONT_SUPPORT=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_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_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_ARCH_COMPILER_H=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_HAVE_ASM_MODVERSIONS=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_CONTEXT_TRACKING=y
-CONFIG_HAVE_COPY_THREAD_TLS=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DEBUG_KMEMLEAK=y
-CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
-CONFIG_HAVE_DMA_CONTIGUOUS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FAST_GUP=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_GENERIC_VDSO=y
-CONFIG_HAVE_IDE=y
-CONFIG_HAVE_IOREMAP_PROT=y
-CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
-CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
-CONFIG_HAVE_KVM=y
-CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
-CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
-CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
-CONFIG_HAVE_NET_DSA=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_PCI=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_RSEQ=y
-CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
-CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
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_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_MIPS=y
CONFIG_MIPS_ASID_BITS=8
CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CBPF_JIT=y
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_ELF_APPENDED_DTB is not set
+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_MIPS_VPE_LOADER is not set
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=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_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
-CONFIG_OF_NET=y
-# CONFIG_PCIE_LANTIQ is not set
CONFIG_PCI_DRIVERS_LEGACY=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
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_SERIAL_LANTIQ_CONSOLE=y
# CONFIG_SOC_AMAZON_SE is not set
# CONFIG_SOC_FALCON is not set
-# CONFIG_SOC_XWAY is not set
+CONFIG_SOC_TYPE_XWAY=y
+CONFIG_SOC_XWAY=y
CONFIG_SPI=y
CONFIG_SPI_LANTIQ_SSC=y
CONFIG_SPI_MASTER=y
--- /dev/null
+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
-CONFIG_CPU_HAS_DIEI=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_ECC_SW_HAMMING=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
--- /dev/null
+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
compatible = "lantiq,mei-xway";
reg = <0xe116000 0x400>;
interrupt-parent = <&icu0>;
- interrupts = <81>;
+ interrupts = <81 83 92>;
};
usb: usb@e101000 {
compatible = "lantiq,mei-xway";
reg = <0xe116000 0x9c>;
interrupt-parent = <&icu0>;
- interrupts = <63>;
+ interrupts = <63 61 68>;
};
gsw: etop@e180000 {
compatible = "lantiq,mei-xway";
reg = <0xe116000 0x400>;
interrupt-parent = <&icu0>;
- interrupts = <63>;
+ interrupts = <63 61 159>;
};
gsw: etop@e180000 {
reg = <0xd900000 0x1000>;
interrupt-parent = <&icu0>;
- interrupts = <161 144>;
+ interrupts = <161 144 145 146 147>;
phys = <&pcie0_phy LANTIQ_PCIE_PHY_MODE_36MHZ>;
phy-names = "pcie";
obj-y += vmmc.o
--- /dev/null
+++ b/arch/mips/lantiq/xway/timer.c
-@@ -0,0 +1,852 @@
+@@ -0,0 +1,887 @@
+#ifndef CONFIG_SOC_AMAZON_SE
+
+#include <linux/kernel.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"
+ return 0;
+}
+
-+int __init lq_gptu_init(void)
++static int gptu_probe(struct platform_device *pdev)
+{
+ int ret;
-+ unsigned int i;
++ int i;
+
+ ltq_w32(0, LQ_GPTU_IRNEN);
+ ltq_w32(0xfff, LQ_GPTU_IRNCR);
+ }
+
+ for (i = 0; i < timer_dev.number_of_timers; i++) {
-+ ret = request_irq(TIMER_INTERRUPT + i, timer_irq_handler, IRQF_TIMER, gptu_miscdev.name, &timer_dev.timer[i]);
-+ if (ret) {
-+ for (; i >= 0; i--)
-+ free_irq(TIMER_INTERRUPT + i, &timer_dev.timer[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 = TIMER_INTERRUPT + i;
++ 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;
#include "ifxmips_pcie.h"
#include "ifxmips_pcie_reg.h"
-@@ -40,6 +47,11 @@
+@@ -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 ifx_pcie_irq_t pcie_irqs[IFX_PCIE_CORE_NR] = {
{
-@@ -82,6 +94,22 @@ void ifx_pcie_debug(const char *fmt, ...
+ .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 int pcie_ltssm_enable(int pcie_port)
{
-@@ -988,10 +1016,26 @@ int ifx_pcie_bios_plat_dev_init(struct
+@@ -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)
{
pcie_ep_gpio_rst_init(pcie_port);
-@@ -1000,26 +1044,21 @@ pcie_rc_initialize(int 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++) {
/* Enable PCIe PHY and Clock */
pcie_core_pmu_setup(pcie_port);
-@@ -1035,6 +1074,10 @@ pcie_rc_initialize(int 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;
}
if (i >= IFX_PCIE_PHY_LOOP_CNT) {
printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
-@@ -1045,17 +1088,74 @@ pcie_rc_initialize(int pcie_port)
+@@ -1045,17 +1079,73 @@ pcie_rc_initialize(int pcie_port)
return 0;
}
-
+
+ ltq_pcie_phy = devm_phy_get(&pdev->dev, "pcie");
-+ if (IS_ERR(ltq_pcie_phy)) {
-+ dev_err(&pdev->dev, "failed to get the PCIe PHY\n");
-+ return PTR_ERR(ltq_pcie_phy);
-+ }
++ 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)) {
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",
-@@ -1067,6 +1167,7 @@ static int __init ifx_pcie_bios_init(voi
+@@ -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 +1184,30 @@ static int __init ifx_pcie_bios_init(voi
+@@ -1083,6 +1185,30 @@ static int __init ifx_pcie_bios_init(voi
return 0;
}
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 {
--- /dev/null
+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;
--- /dev/null
+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 = <ð0>;
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
+ };
+ };
+
--- /dev/null
+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;
--- /dev/null
+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;
+ }
+
--- /dev/null
+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;
--- /dev/null
+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,
--- /dev/null
+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);
--- /dev/null
+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;
+
--- /dev/null
+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;
--- /dev/null
+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;
+ }
--- /dev/null
+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;
+ }
+
--- /dev/null
+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,
--- /dev/null
+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;
--- /dev/null
+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;
+ }
+
--- /dev/null
+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
--- /dev/null
+From f038380835033e376d89c72516f087254792bbad Mon Sep 17 00:00:00 2001
+From: Martin Schiller <ms@dev.tdt.de>
+Date: Mon, 6 May 2024 09:41:42 +0200
+Subject: [PATCH] MIPS: pci: lantiq: restore reset gpio polarity
+
+Commit 90c2d2eb7ab5 ("MIPS: pci: lantiq: switch to using gpiod API") not
+only switched to the gpiod API, but also inverted / changed the polarity
+of the GPIO.
+
+According to the PCI specification, the RST# pin is an active-low
+signal. However, most of the device trees that have been widely used for
+a long time (mainly in the openWrt project) define this GPIO as
+active-high and the old driver code inverted the signal internally.
+
+Apparently there are actually boards where the reset gpio must be
+operated inverted. For this reason, we cannot use the GPIOD_OUT_LOW/HIGH
+flag for initialization. Instead, we must explicitly set the gpio to
+value 1 in order to take into account any "GPIO_ACTIVE_LOW" flag that
+may have been set.
+
+In order to remain compatible with all these existing device trees, we
+should therefore keep the logic as it was before the commit.
+
+Fixes: 90c2d2eb7ab5 ("MIPS: pci: lantiq: switch to using gpiod API")
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+---
+ arch/mips/pci/pci-lantiq.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/mips/pci/pci-lantiq.c
++++ b/arch/mips/pci/pci-lantiq.c
+@@ -124,14 +124,14 @@ static int ltq_pci_startup(struct platfo
+ clk_disable(clk_external);
+
+ /* setup reset gpio used by pci */
+- reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset",
+- GPIOD_OUT_LOW);
++ reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_ASIS);
+ error = PTR_ERR_OR_ZERO(reset_gpio);
+ if (error) {
+ dev_err(&pdev->dev, "failed to request gpio: %d\n", error);
+ return error;
+ }
+ gpiod_set_consumer_name(reset_gpio, "pci_reset");
++ gpiod_direction_output(reset_gpio, 1);
+
+ /* enable auto-switching between PCI and EBU */
+ ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
+@@ -194,10 +194,10 @@ static int ltq_pci_startup(struct platfo
+
+ /* toggle reset pin */
+ if (reset_gpio) {
+- gpiod_set_value_cansleep(reset_gpio, 1);
++ gpiod_set_value_cansleep(reset_gpio, 0);
+ wmb();
+ mdelay(1);
+- gpiod_set_value_cansleep(reset_gpio, 0);
++ gpiod_set_value_cansleep(reset_gpio, 1);
+ }
+ return 0;
+ }
--- /dev/null
+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(<q_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 */
--- /dev/null
+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(¶m, (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, ¶m.value);
++ if (!ret && copy_to_user(&((struct gptu_ioctl_param *) arg)->
++ value, ¶m.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, ¶m.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
--- /dev/null
+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);
--- /dev/null
+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))
--- /dev/null
+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
--- /dev/null
+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),
+- <q_etop_mdio_link, priv->pldata->mii_mode);
++ <q_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 = <q_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 = <q_eth_netdev_ops;
+- dev->ethtool_ops = <q_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(<q_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(<q_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");
--- /dev/null
+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 = <q_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 */
--- /dev/null
+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);
--- /dev/null
+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
--- /dev/null
+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 },
--- /dev/null
+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();
+ }
--- /dev/null
+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;
+ }
+
--- /dev/null
+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(<q_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 {
--- /dev/null
+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)
+ {
--- /dev/null
+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;
+ }
--- /dev/null
+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
--- /dev/null
+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, <q_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" },
+ {},
--- /dev/null
+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,
--- /dev/null
+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
--- /dev/null
+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);
+ }
--- /dev/null
+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)
--- /dev/null
+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)
--- /dev/null
+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;
+ }
--- /dev/null
+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 = <ð0>;
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
+ };
+ };
+
--- /dev/null
+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;
--- /dev/null
+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;
+ }
+
--- /dev/null
+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;
--- /dev/null
+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,
--- /dev/null
+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);
--- /dev/null
+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;
+
--- /dev/null
+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;
--- /dev/null
+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;
+ }
--- /dev/null
+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;
+ }
+
--- /dev/null
+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,
--- /dev/null
+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;
--- /dev/null
+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;
+ }
+
CONFIG_AT803X_PHY=y
CONFIG_BLK_MQ_PCI=y
-CONFIG_CPU_HAS_DIEI=y
CONFIG_CPU_MIPSR2_IRQ_EI=y
CONFIG_CPU_MIPSR2_IRQ_VI=y
CONFIG_CPU_RMAP=y
CONFIG_CRC16=y
-CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_LZO=y
CONFIG_IFX_VPE_EXT=y
CONFIG_INPUT=y
CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_POLLDEV=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_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_SGL_ALLOC=y
CONFIG_SMP=y
CONFIG_SMP_UP=y
-CONFIG_SOC_TYPE_XWAY=y
-CONFIG_SOC_XWAY=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SYNC_R4K=y
CONFIG_SYS_SUPPORTS_SCHED_SMT=y
CONFIG_SYS_SUPPORTS_SMP=y
--- /dev/null
+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
CONFIG_ADM6996_PHY=y
CONFIG_AR8216_PHY=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_AT803X_PHY=y
CONFIG_BLK_MQ_PCI=y
-CONFIG_CPU_HAS_DIEI=y
CONFIG_CPU_MIPSR2_IRQ_EI=y
CONFIG_CPU_MIPSR2_IRQ_VI=y
CONFIG_CPU_RMAP=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_ZSTD=y
CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_FWNODE_MDIO=y
CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GPIO_CDEV=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_EBPF_JIT=y
CONFIG_MIPS_MT=y
CONFIG_MIPS_MT_FPAFF=y
CONFIG_MIPS_MT_SMP=y
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=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_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
CONFIG_REGULATOR=y
CONFIG_SMP=y
CONFIG_SMP_UP=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_TYPE_XWAY=y
-CONFIG_SOC_XWAY=y
CONFIG_SWCONFIG=y
CONFIG_SYNC_R4K=y
CONFIG_SYS_SUPPORTS_SCHED_SMT=y
--- /dev/null
+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
CONFIG_ADM6996_PHY=y
CONFIG_BLK_MQ_PCI=y
-CONFIG_CPU_HAS_DIEI=y
CONFIG_CRC16=y
-CONFIG_CRYPTO_ACOMP2=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_INPUT_POLLDEV=y
# CONFIG_ISDN is not set
CONFIG_LANTIQ_ETOP=y
# CONFIG_LEDS_TRIGGER_TIMER is not set
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_SOC_TYPE_XWAY=y
-CONFIG_SOC_XWAY=y
CONFIG_SWCONFIG=y
CONFIG_USB=y
CONFIG_USB_COMMON=y
--- /dev/null
+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
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2024 Weijie Gao <hackpascal@gmail.com>
+
+include $(TOPDIR)/rules.mk
+
+ARCH:=loongarch64
+BOARD:=loongarch64
+BOARDNAME:=Loongson LoongArch
+FEATURES:=audio display ext4 pcie boot-part rootfs-part rtc usb targz
+SUBTARGETS:=generic
+
+KERNEL_PATCHVER:=6.6
+
+KERNELNAME:=vmlinuz.efi dtbs
+
+include $(INCLUDE_DIR)/target.mk
+
+DEFAULT_PACKAGES += \
+ partx-utils blkid e2fsprogs grub2-efi-loongarch64
+
+$(eval $(call BuildTarget))
--- /dev/null
+GRUB_SERIAL:=$(call qstrip,$(CONFIG_TARGET_SERIAL))
+ifeq ($(GRUB_SERIAL),)
+$(error This platform requires CONFIG_TARGET_SERIAL be set!)
+endif
+
+define Package/base-files/install-target
+ $(SED) "s#@GRUB_SERIAL@#$(GRUB_SERIAL)#" $(1)/etc/inittab
+endef
--- /dev/null
+::sysinit:/etc/init.d/rcS S boot
+::shutdown:/etc/init.d/rcS K shutdown
+@GRUB_SERIAL@::askfirst:/usr/libexec/login.sh
+tty0::askfirst:/usr/libexec/login.sh
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+sanitize_name_loongarch64() {
+ sed -e '
+ y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;
+ s/[^a-z0-9_-]\+/-/g;
+ s/^-//;
+ s/-$//;
+ ' "$@"
+}
+
+do_sysinfo_loongarch64() {
+ local vendor product file
+
+ for file in sys_vendor board_vendor; do
+ vendor="$(cat /sys/devices/virtual/dmi/id/$file 2>/dev/null)"
+ case "$vendor" in
+ empty | \
+ System\ manufacturer | \
+ To\ [bB]e\ [fF]illed\ [bB]y\ O\.E\.M\.)
+ continue
+ ;;
+ esac
+ [ -n "$vendor" ] && break
+ done
+
+ for file in product_name board_name; do
+ product="$(cat /sys/devices/virtual/dmi/id/$file 2>/dev/null)"
+ case "$vendor:$product" in
+ ?*:empty | \
+ ?*:System\ Product\ Name | \
+ ?*:To\ [bB]e\ [fF]illed\ [bB]y\ O\.E\.M\.)
+ continue
+ ;;
+ ?*:?*)
+ break
+ ;;
+ esac
+ done
+
+ [ -d "/sys/firmware/devicetree/base" ] && return
+
+ [ -n "$vendor" -a -n "$product" ] || return
+
+ mkdir -p /tmp/sysinfo
+
+ echo "$vendor $product" > /tmp/sysinfo/model
+
+ sanitize_name_loongarch64 /tmp/sysinfo/model > /tmp/sysinfo/board_name
+}
+
+boot_hook_add preinit_main do_sysinfo_loongarch64
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+
+move_config() {
+ local partdev parttype=ext4
+
+ . /lib/upgrade/common.sh
+
+ if export_bootdevice && export_partdevice partdev 1; then
+ part_magic_fat "/dev/$partdev" && parttype=vfat
+ if mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt; then
+ if [ -f "/mnt/$BACKUP_FILE" ]; then
+ mv -f "/mnt/$BACKUP_FILE" /
+ fi
+ umount /mnt
+ fi
+ fi
+}
+
+boot_hook_add preinit_mount_root move_config
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+RAMFS_COPY_BIN="/usr/sbin/blkid"
+
+platform_check_image() {
+ local board=$(board_name)
+ local diskdev partdev diff
+ [ "$#" -gt 1 ] && return 1
+
+ v "Board is ${board}"
+
+ export_bootdevice && export_partdevice diskdev 0 || {
+ v "platform_check_image: Unable to determine upgrade device"
+ return 1
+ }
+
+ get_partitions "/dev/$diskdev" bootdisk
+
+ v "Extract boot sector from the image"
+ get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
+
+ get_partitions /tmp/image.bs image
+
+ #compare tables
+ diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
+
+ rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
+
+ if [ -n "$diff" ]; then
+ v "Partition layout has changed. Full image will be written."
+ ask_bool 0 "Abort" && exit 1
+ return 0
+ fi
+}
+
+platform_copy_config() {
+ local partdev parttype=ext4
+
+ if export_partdevice partdev 1; then
+ part_magic_fat "/dev/$partdev" && parttype=vfat
+ mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
+ cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
+ umount /mnt
+ else
+ v "ERROR: Unable to find partition to copy config data to"
+ fi
+
+ sleep 5
+}
+
+# To avoid writing over any firmware
+# files (e.g ubootefi.var or firmware/X/ aka EBBR)
+# Copy efi/openwrt and efi/boot from the new image
+# to the existing ESP
+platform_do_upgrade_efi_system_partition() {
+ local image_file=$1
+ local target_partdev=$2
+ local image_efisp_start=$3
+ local image_efisp_size=$4
+
+ v "Updating ESP on ${target_partdev}"
+ NEW_ESP_DIR="/mnt/new_esp_loop"
+ CUR_ESP_DIR="/mnt/cur_esp"
+ mkdir "${NEW_ESP_DIR}"
+ mkdir "${CUR_ESP_DIR}"
+
+ get_image_dd "$image_file" of="/tmp/new_efi_sys_part.img" \
+ skip="$image_efisp_start" count="$image_efisp_size"
+
+ mount -t vfat -o loop -o ro /tmp/new_efi_sys_part.img "${NEW_ESP_DIR}"
+ if [ ! -d "${NEW_ESP_DIR}/efi/boot" ]; then
+ v "ERROR: Image does not contain EFI boot files (/efi/boot)"
+ return 1
+ fi
+
+ mount -t vfat "/dev/$partdev" "${CUR_ESP_DIR}"
+
+ for d in $(find "${NEW_ESP_DIR}/efi/" -mindepth 1 -maxdepth 1 -type d); do
+ v "Copying ${d}"
+ newdir_bname=$(basename "${d}")
+ rm -rf "${CUR_ESP_DIR}/efi/${newdir_bname}"
+ cp -r "${d}" "${CUR_ESP_DIR}/efi"
+ v "rm -rf \"${CUR_ESP_DIR}/efi/${newdir_bname}\""
+ v "cp -r \"${d}\" \"${CUR_ESP_DIR}/efi\""
+ done
+
+ umount "${NEW_ESP_DIR}"
+ umount "${CUR_ESP_DIR}"
+}
+
+platform_do_upgrade() {
+ local board=$(board_name)
+ local diskdev partdev diff
+
+ export_bootdevice && export_partdevice diskdev 0 || {
+ v "platform_do_upgrade: Unable to determine upgrade device"
+ return 1
+ }
+
+ sync
+
+ if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
+ get_partitions "/dev/$diskdev" bootdisk
+
+ v "Extract boot sector from the image"
+ get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
+
+ get_partitions /tmp/image.bs image
+
+ #compare tables
+ diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
+ else
+ diff=1
+ fi
+
+ # Only change the partition table if sysupgrade -p is set,
+ # otherwise doing so could interfere with embedded "single storage"
+ # (e.g SoC boot from SD card) setups, as well as other user
+ # created storage (like uvol)
+ if [ -n "$diff" ] && [ "${UPGRADE_OPT_SAVE_PARTITIONS}" = "0" ]; then
+ # Need to remove partitions before dd, otherwise the partitions
+ # that are added after will have minor numbers offset
+ partx -d - "/dev/$diskdev"
+
+ get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
+
+ # Separate removal and addtion is necessary; otherwise, partition 1
+ # will be missing if it overlaps with the old partition 2
+ partx -a - "/dev/$diskdev"
+
+ return 0
+ fi
+
+ #iterate over each partition from the image and write it to the boot disk
+ while read part start size; do
+ if export_partdevice partdev $part; then
+ v "Writing image to /dev/$partdev..."
+ if [ "$part" = "1" ]; then
+ platform_do_upgrade_efi_system_partition \
+ $1 $partdev $start $size || return 1
+ else
+ v "Normal partition, doing DD"
+ get_image_dd "$1" of="/dev/$partdev" ibs=512 obs=1M skip="$start" \
+ count="$size" conv=fsync
+ fi
+ else
+ v "Unable to find partition $part device, skipped."
+ fi
+ done < /tmp/partmap.image
+
+ local parttype=ext4
+
+ if (blkid > /dev/null) && export_partdevice partdev 1; then
+ part_magic_fat "/dev/$partdev" && parttype=vfat
+ mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
+ if export_partdevice partdev 2; then
+ THIS_PART_BLKID=$(blkid -o value -s PARTUUID "/dev/${partdev}")
+ v "Setting rootfs PARTUUID=${THIS_PART_BLKID}"
+ sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1${THIS_PART_BLKID}/ig" \
+ /mnt/efi/openwrt/grub.cfg
+ fi
+ umount /mnt
+ fi
+ # Provide time for the storage medium to flush before system reset
+ # (despite the sync/umount it appears NVMe etc. do it in the background)
+ sleep 5
+}
--- /dev/null
+# CONFIG_16KB_2LEVEL is not set
+CONFIG_16KB_3LEVEL=y
+# CONFIG_4KB_3LEVEL is not set
+# CONFIG_4KB_4LEVEL is not set
+CONFIG_64BIT=y
+# CONFIG_64KB_2LEVEL is not set
+# CONFIG_64KB_3LEVEL is not set
+CONFIG_AC97_BUS=y
+CONFIG_ACPI=y
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_CONTAINER=y
+CONFIG_ACPI_CPU_FREQ_PSS=y
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_DEBUGGER is not set
+# CONFIG_ACPI_DOCK is not set
+# CONFIG_ACPI_EC_DEBUGFS is not set
+CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_FFH is not set
+CONFIG_ACPI_GENERIC_GSI=y
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_I2C_OPREGION=y
+CONFIG_ACPI_MCFG=y
+# CONFIG_ACPI_PCI_SLOT is not set
+# CONFIG_ACPI_PFRUT is not set
+CONFIG_ACPI_PPTT=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_PROCESSOR_IDLE=y
+CONFIG_ACPI_SLEEP=y
+# CONFIG_ACPI_SPCR_TABLE is not set
+CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y
+CONFIG_ACPI_TABLE_UPGRADE=y
+# CONFIG_ACPI_TAD is not set
+CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_VIDEO=y
+CONFIG_APERTURE_HELPERS=y
+CONFIG_ARCH_DISABLE_KASAN_INLINE=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+# CONFIG_ARCH_IOREMAP is not set
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
+CONFIG_ARCH_MMAP_RND_BITS=12
+CONFIG_ARCH_MMAP_RND_BITS_MAX=18
+CONFIG_ARCH_MMAP_RND_BITS_MIN=12
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_STRICT_ALIGN=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_WANTS_NO_INSTR=y
+# CONFIG_ARCH_WRITECOMBINE is not set
+CONFIG_ASN1=y
+CONFIG_ASSOCIATIVE_ARRAY=y
+CONFIG_ATA=y
+CONFIG_ATA_ACPI=y
+CONFIG_ATA_FORCE=y
+# CONFIG_ATA_SFF is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_AUDIT_GENERIC=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_KTZ8866 is not set
+CONFIG_BLK_CGROUP=y
+CONFIG_BLK_CGROUP_IOCOST=y
+CONFIG_BLK_CGROUP_RWSTAT=y
+CONFIG_BLK_DEBUG_FS=y
+CONFIG_BLK_DEBUG_FS_ZONED=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_NVME=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_THROTTLING=y
+# CONFIG_BLK_DEV_THROTTLING_LOW is not set
+CONFIG_BLK_DEV_ZONED=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BLK_RQ_ALLOC_TIME=y
+CONFIG_BLK_SED_OPAL=y
+CONFIG_BLK_WBT=y
+CONFIG_BLK_WBT_MQ=y
+CONFIG_BLOCK_LEGACY_AUTOLOAD=y
+CONFIG_BOOT_PRINTK_DELAY=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_BUG_ON_DATA_CORRUPTION=y
+CONFIG_CACHESTAT_SYSCALL=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CDROM=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_BPF is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_HUGETLB is not set
+# CONFIG_CGROUP_NET_CLASSID is not set
+# CONFIG_CGROUP_NET_PRIO is not set
+# CONFIG_CGROUP_PIDS is not set
+# CONFIG_CGROUP_RDMA is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_CHECKPOINT_RESTORE=y
+CONFIG_CHR_DEV_SG=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_CMDLINE_BOOTLOADER=y
+CONFIG_COMMON_CLK=y
+# CONFIG_COMMON_CLK_LOONGSON2 is not set
+# CONFIG_COMMON_CLK_SI521XX is not set
+# CONFIG_COMMON_CLK_VC3 is not set
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+# CONFIG_COMPAT_32BIT_TIME is not set
+CONFIG_CONNECTOR=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_CPUSETS=y
+CONFIG_CPU_HAS_FPU=y
+CONFIG_CPU_HAS_LASX=y
+CONFIG_CPU_HAS_LBT=y
+CONFIG_CPU_HAS_LSX=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_ISOLATION=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+CONFIG_CRC64=y
+CONFIG_CRC64_ROCKSOFT=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32_LOONGARCH is not set
+CONFIG_CRYPTO_CRC64_ROCKSOFT=y
+CONFIG_CRYPTO_CRCT10DIF=y
+CONFIG_CRYPTO_HMAC=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_LZO=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RSA=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_DCB=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_COMPRESSED_NONE=y
+# CONFIG_DEBUG_INFO_COMPRESSED_ZLIB is not set
+# CONFIG_DEBUG_INFO_COMPRESSED_ZSTD is not set
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_MISC=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=y
+CONFIG_DEVMEM=y
+CONFIG_DEVTMPFS=y
+# CONFIG_DMAPOOL_TEST is not set
+CONFIG_DMA_CMA=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMI=y
+CONFIG_DMIID=y
+CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
+CONFIG_DMI_SYSFS=y
+CONFIG_DRM=y
+# CONFIG_DRM_ACCEL is not set
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_FBDEV_EMULATION=y
+CONFIG_DRM_FBDEV_OVERALLOC=100
+CONFIG_DRM_KMS_HELPER=y
+CONFIG_DRM_LOAD_EDID_FIRMWARE=y
+CONFIG_DRM_LOONGSON=y
+CONFIG_DRM_PANEL=y
+# CONFIG_DRM_PANEL_AUO_A030JTN01 is not set
+CONFIG_DRM_PANEL_BRIDGE=y
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+# CONFIG_DRM_PANEL_ORISETECH_OTA5601A is not set
+# CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0 is not set
+# CONFIG_DRM_SAMSUNG_DSIM is not set
+CONFIG_DRM_TTM=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_EFI=y
+CONFIG_EFIVAR_FS=m
+# CONFIG_EFI_BOOTLOADER_CONTROL is not set
+# CONFIG_EFI_CAPSULE_LOADER is not set
+# CONFIG_EFI_COCO_SECRET is not set
+CONFIG_EFI_CUSTOM_SSDT_OVERLAYS=y
+# CONFIG_EFI_DISABLE_PCI_DMA is not set
+# CONFIG_EFI_DISABLE_RUNTIME is not set
+CONFIG_EFI_EARLYCON=y
+CONFIG_EFI_ESRT=y
+CONFIG_EFI_GENERIC_STUB=y
+CONFIG_EFI_RUNTIME_WRAPPERS=y
+CONFIG_EFI_STUB=y
+# CONFIG_EFI_TEST is not set
+CONFIG_EFI_ZBOOT=y
+CONFIG_ELF_CORE=y
+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
+CONFIG_FB=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_CORE=y
+CONFIG_FB_DEFERRED_IO=y
+CONFIG_FB_DEVICE=y
+CONFIG_FB_EFI=y
+CONFIG_FB_IOMEM_HELPERS=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_SIMPLE=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_FB_TILEBLITTING=y
+CONFIG_FHANDLE=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FIX_EARLYCON_MEM=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_10x18 is not set
+# CONFIG_FONT_6x10 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+CONFIG_FONT_8x16=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_SUN8x16 is not set
+CONFIG_FONT_SUPPORT=y
+CONFIG_FONT_TER16x32=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+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
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC11_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=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_CSUM=y
+CONFIG_GENERIC_ENTRY=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOREMAP=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_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_MSI_IRQ=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_GLOB=y
+CONFIG_GPIO_ACPI=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_CDEV_V1=y
+# CONFIG_GPIO_DS4520 is not set
+# CONFIG_GPIO_FXL6408 is not set
+# CONFIG_GPIO_LATCH is not set
+# CONFIG_GPIO_LOONGSON_64BIT is not set
+CONFIG_HAMRADIO=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HDMI=y
+CONFIG_HIBERNATE_CALLBACKS=y
+CONFIG_HIBERNATION=y
+CONFIG_HIBERNATION_SNAPSHOT_DEV=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+CONFIG_HID_GENERIC=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
+CONFIG_HWMON=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HZ=250
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_AMD_MP2 is not set
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_LS2X is not set
+CONFIG_INITRAMFS_PRESERVE_MTIME=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INIT_STACK_ALL_ZERO=y
+# CONFIG_INIT_STACK_NONE is not set
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_INPUT_LEDS=y
+# CONFIG_INPUT_MISC is not set
+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_IOMMUFD is not set
+# CONFIG_IOMMU_DEBUGFS is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IO_URING=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_LOONGARCH_CPU=y
+CONFIG_IRQ_POLL=y
+CONFIG_IRQ_WORK=y
+# CONFIG_ISCSI_IBFT is not set
+CONFIG_ISO9660_FS=y
+CONFIG_JBD2=y
+CONFIG_JUMP_LABEL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_SELFTEST is not set
+CONFIG_KCMP=y
+CONFIG_KEYS=y
+CONFIG_KSM=y
+CONFIG_L1_CACHE_SHIFT=6
+# CONFIG_LEDS_AW200XX is not set
+# CONFIG_LEDS_BD2606MVV is not set
+# CONFIG_LEDS_GROUP_MULTICOLOR is not set
+# CONFIG_LEDS_LM3697 is not set
+# CONFIG_LEDS_PCA995X is not set
+CONFIG_LEDS_TRIGGER_AUDIO=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LEDS_TRIGGER_MTD=y
+CONFIG_LEDS_TRIGGER_PANIC=y
+CONFIG_LEGACY_TIOCSTI=y
+CONFIG_LIBFDT=y
+CONFIG_LIST_HARDENED=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LOONGARCH=y
+CONFIG_LOONGARCH_PLATFORM_DEVICES=y
+# CONFIG_LOONGSON2_GUTS is not set
+# CONFIG_LOONGSON2_PM is not set
+# CONFIG_LOONGSON2_THERMAL is not set
+CONFIG_LOONGSON_EIOINTC=y
+CONFIG_LOONGSON_HTVEC=y
+CONFIG_LOONGSON_LAPTOP=y
+CONFIG_LOONGSON_LIOINTC=y
+CONFIG_LOONGSON_PCH_LPC=y
+CONFIG_LOONGSON_PCH_MSI=y
+CONFIG_LOONGSON_PCH_PIC=y
+CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf"
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MACH_LOONGSON64=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x01b6
+CONFIG_MAGIC_SYSRQ_SERIAL=y
+# CONFIG_MAX31827 is not set
+CONFIG_MAX_SKB_FRAGS=17
+# CONFIG_MEMCG is not set
+CONFIG_MEMFD_CREATE=y
+CONFIG_MEMORY=y
+CONFIG_MEMORY_ISOLATION=y
+# CONFIG_MFD_CS42L43_I2C is not set
+# CONFIG_MFD_INTEL_M10_BMC_SPI is not set
+# CONFIG_MFD_MAX5970 is not set
+# CONFIG_MFD_MAX77541 is not set
+# CONFIG_MFD_RK8XX_I2C is not set
+# CONFIG_MFD_RK8XX_SPI is not set
+# CONFIG_MFD_SMPRO is not set
+# CONFIG_MFD_TPS65219 is not set
+# CONFIG_MFD_TPS6594_I2C is not set
+# CONFIG_MFD_TPS6594_SPI is not set
+CONFIG_MIGRATION=y
+CONFIG_MMU_GATHER_MERGE_VMAS=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_RELA=y
+# CONFIG_MODULE_DEBUG is not set
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=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_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_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+CONFIG_MPILIB=y
+CONFIG_MQ_IOSCHED_DEADLINE=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_NET_CLS_CGROUP is not set
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FAILOVER=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NR_CPUS=64
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_NVME_CORE=y
+CONFIG_NVME_HWMON=y
+CONFIG_NVME_MULTIPATH=y
+CONFIG_NVME_VERBOSE_ERRORS=y
+# CONFIG_N_HDLC is not set
+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_OID_REGISTRY=y
+# CONFIG_OVERLAY_FS_DEBUG is not set
+CONFIG_PADATA=y
+CONFIG_PAGE_EXTENSION=y
+CONFIG_PAGE_POISONING=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_PAGE_REPORTING=y
+CONFIG_PAGE_SIZE_16KB=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_PATA_TIMINGS=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_DPC=y
+# CONFIG_PCIE_EDR is not set
+CONFIG_PCIE_PME=y
+CONFIG_PCIE_PTM=y
+CONFIG_PCI_ATS=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+# CONFIG_PCI_DYNAMIC_OF_NODES is not set
+CONFIG_PCI_ECAM=y
+CONFIG_PCI_IOV=y
+CONFIG_PCI_LABEL=y
+CONFIG_PCI_LOONGSON=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_ARCH_FALLBACKS=y
+CONFIG_PCI_REALLOC_ENABLE_AUTO=y
+CONFIG_PCPU_DEV_REFCNT=y
+# CONFIG_PDS_CORE is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_3LEVEL=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_PM=y
+# CONFIG_PMIC_OPREGION is not set
+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_OPP=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_DEBUG=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_PM_STD_PARTITION=""
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_PNP=y
+CONFIG_PNPACPI=y
+# CONFIG_PNP_DEBUG_MESSAGES is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_SUPPLY_HWMON=y
+CONFIG_PPS=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_PREEMPT_VOLUNTARY_BUILD=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_CHILDREN=y
+CONFIG_PROC_EVENTS=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_PTP_1588_CLOCK=y
+# CONFIG_PTP_1588_CLOCK_MOCK is not set
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+# CONFIG_RANDOM_KMALLOC_CACHES is not set
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+# CONFIG_RAVE_SP_CORE is not set
+# CONFIG_RCU_CPU_STALL_CPUTIME is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_RELAY=y
+CONFIG_RELOCATABLE=y
+CONFIG_RESET_ATTACK_MITIGATION=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RSEQ=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_EFI is not set
+CONFIG_RTC_DRV_LOONGSON=y
+CONFIG_RTC_I2C_AND_SPI=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_HOST=y
+# CONFIG_SATA_ZPODD is not set
+CONFIG_SCHEDSTATS=y
+CONFIG_SCHED_AUTOGROUP=y
+# CONFIG_SCHED_CORE is not set
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHED_INFO=y
+CONFIG_SCHED_MM_CID=y
+CONFIG_SCHED_SMT=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SECCOMP=y
+CONFIG_SECCOMP_FILTER=y
+# CONFIG_SENSORS_HS3001 is not set
+# CONFIG_SENSORS_MC34VR500 is not set
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_PCI=y
+# CONFIG_SERIAL_8250_PCI1XXXX is not set
+CONFIG_SERIAL_8250_PCILIB=y
+CONFIG_SERIAL_8250_PERICOM=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_RSA=y
+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_MCTRL_GPIO=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+# CONFIG_SLAB_DEPRECATED is not set
+# CONFIG_SLUB_TINY is not set
+CONFIG_SMP=y
+CONFIG_SND=y
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_COMPRESS_OFFLOAD=y
+CONFIG_SND_CTL_LED=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_HDA=y
+# CONFIG_SND_HDA_CODEC_ANALOG is not set
+# CONFIG_SND_HDA_CODEC_CA0110 is not set
+# CONFIG_SND_HDA_CODEC_CA0132 is not set
+# CONFIG_SND_HDA_CODEC_CIRRUS is not set
+# CONFIG_SND_HDA_CODEC_CMEDIA is not set
+CONFIG_SND_HDA_CODEC_CONEXANT=y
+CONFIG_SND_HDA_CODEC_HDMI=y
+# CONFIG_SND_HDA_CODEC_REALTEK is not set
+# CONFIG_SND_HDA_CODEC_SI3054 is not set
+# CONFIG_SND_HDA_CODEC_SIGMATEL is not set
+# CONFIG_SND_HDA_CODEC_VIA is not set
+CONFIG_SND_HDA_CORE=y
+# CONFIG_SND_HDA_CTL_DEV_ID is not set
+CONFIG_SND_HDA_GENERIC=y
+CONFIG_SND_HDA_GENERIC_LEDS=y
+CONFIG_SND_HDA_HWDEP=y
+# CONFIG_SND_HDA_INPUT_BEEP is not set
+CONFIG_SND_HDA_INTEL=y
+# CONFIG_SND_HDA_PATCH_LOADER is not set
+# CONFIG_SND_HDA_RECONFIG is not set
+# CONFIG_SND_HDA_SCODEC_CS35L41_I2C is not set
+# CONFIG_SND_HDA_SCODEC_CS35L41_SPI is not set
+# CONFIG_SND_HDA_SCODEC_CS35L56_I2C is not set
+# CONFIG_SND_HDA_SCODEC_CS35L56_SPI is not set
+# CONFIG_SND_HDA_SCODEC_TAS2781_I2C is not set
+CONFIG_SND_HWDEP=y
+CONFIG_SND_INTEL_DSP_CONFIG=y
+CONFIG_SND_INTEL_NHLT=y
+CONFIG_SND_INTEL_SOUNDWIRE_ACPI=y
+CONFIG_SND_JACK=y
+CONFIG_SND_JACK_INPUT_DEV=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_TIMER=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_SEQ_DEVICE=y
+CONFIG_SND_SEQ_DUMMY=y
+CONFIG_SND_SEQ_MIDI=y
+CONFIG_SND_SEQ_MIDI_EVENT=y
+CONFIG_SND_SEQ_VIRMIDI=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC_AC97_CODEC=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+CONFIG_SND_SOC_LOONGSON_CARD=y
+CONFIG_SND_SOC_LOONGSON_I2S_PCI=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_VIRMIDI=y
+CONFIG_SND_VMASTER=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_DYNAMIC=y
+CONFIG_SPI_LOONGSON_CORE=y
+CONFIG_SPI_LOONGSON_PCI=y
+CONFIG_SPI_LOONGSON_PLATFORM=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+# CONFIG_SPI_PCI1XXXX is not set
+# CONFIG_SPI_SN_F_OSPI is not set
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT is not set
+# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI is not set
+# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set
+CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE=y
+CONFIG_SQUASHFS_DECOMP_SINGLE=y
+CONFIG_STACKPROTECTOR=y
+CONFIG_STACKPROTECTOR_STRONG=y
+CONFIG_STACKTRACE=y
+CONFIG_STRICT_DEVMEM=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWIOTLB=y
+# CONFIG_SWIOTLB_DYNAMIC is not set
+CONFIG_SYNC_FILE=y
+CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW=y
+CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYSFB=y
+# CONFIG_SYSFB_SIMPLEFB is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_TASK_XACCT=y
+# CONFIG_TEST_DHRY is not set
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_DEFAULT_GOV_BANG_BANG is not set
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_BANG_BANG=y
+CONFIG_THERMAL_GOV_FAIR_SHARE=y
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+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
+# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UCS2_STRING=y
+# CONFIG_UEVENT_HELPER is not set
+# CONFIG_UNWINDER_GUESS is not set
+CONFIG_UNWINDER_PROLOGUE=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_EHCI_PCI=y
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PCI=y
+# CONFIG_USB_OHCI_HCD_PLATFORM is not set
+CONFIG_USB_PCI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_UAS=y
+# CONFIG_USB_UHCI_HCD is not set
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PCI=y
+# CONFIG_USB_XHCI_PLATFORM is not set
+CONFIG_USERFAULTFD=y
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_USE_PERCPU_NUMA_NODE_ID=y
+# CONFIG_VCAP is not set
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+CONFIG_VGA_CONSOLE=y
+CONFIG_VIDEO_CMDLINE=y
+CONFIG_VIDEO_NOMODESET=y
+CONFIG_VIRTIO_VSOCKETS_COMMON=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_VSOCKETS=y
+CONFIG_VSOCKETS_LOOPBACK=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_WPCM450_SOC is not set
+# CONFIG_WQ_CPU_INTENSIVE_REPORT is not set
+CONFIG_XARRAY_MULTI=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+# CONFIG_ZONEFS_FS is not set
+CONFIG_ZONE_DMA32=y
--- /dev/null
+BOARDNAME:=Generic
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2024 Weijie Gao <hackpascal@gmail.com>
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+GRUB2_VARIANT =
+GRUB_TERMINALS =
+GRUB_SERIAL_CONFIG =
+GRUB_TERMINAL_CONFIG =
+GRUB_CONSOLE_CMDLINE =
+
+ifneq ($(CONFIG_GRUB_CONSOLE),)
+ GRUB_CONSOLE_CMDLINE += console=tty0
+ GRUB_TERMINALS += console
+endif
+
+GRUB_SERIAL:=$(call qstrip,$(CONFIG_TARGET_SERIAL))
+
+GRUB_CONSOLE_CMDLINE += console=$(GRUB_SERIAL),$(CONFIG_GRUB_BAUDRATE)n8$(if $(CONFIG_GRUB_FLOWCONTROL),r,)
+GRUB_SERIAL_CONFIG := serial --unit=0 --speed=$(CONFIG_GRUB_BAUDRATE) --word=8 --parity=no --stop=1 --rtscts=$(if $(CONFIG_GRUB_FLOWCONTROL),on,off)
+GRUB_TERMINALS += serial
+
+GRUB_TERMINAL_CONFIG := terminal_input $(GRUB_TERMINALS); terminal_output $(GRUB_TERMINALS)
+
+ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
+ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(IMG_PART_SIGNATURE)-02)
+GPT_ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
+GPT_ROOTPART:=$(if $(GPT_ROOTPART),$(GPT_ROOTPART),PARTUUID=$(shell echo $(IMG_PART_DISKGUID) | sed 's/00$$/02/'))
+
+GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT))
+GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE))
+
+BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS))
+
+define Build/combined
+ $(INSTALL_DIR) $@.boot/
+ $(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/efi/openwrt/
+ $(INSTALL_DIR) $@.boot/efi/boot
+ $(CP) $(STAGING_DIR_IMAGE)/grub2/bootloongarch64.efi $@.boot/efi/boot/
+ KERNELPARTTYPE=ef FAT_TYPE="32" PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" \
+ GUID="$(IMG_PART_DISKGUID)" $(SCRIPT_DIR)/gen_image_generic.sh \
+ $@ \
+ $(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
+ $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
+ 256
+endef
+
+define Build/grub-config
+ rm -fR $@.boot
+ $(INSTALL_DIR) $@.boot/efi/openwrt/
+ sed \
+ -e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
+ -e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
+ -e 's#@ROOTPART@#root=$(ROOTPART) rootwait#g' \
+ -e 's#@GPT_ROOTPART@#root=$(GPT_ROOTPART) rootwait#g' \
+ -e 's#@CMDLINE@#$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE)#g' \
+ -e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
+ -e 's#@TITLE@#$(GRUB_TITLE)#g' \
+ -e 's#@KERNEL_NAME@#$(KERNEL_NAME)#g' \
+ ./grub-$(1).cfg > $@.boot/efi/openwrt/grub.cfg
+endef
+
+define Device/Default
+ KERNEL_INSTALL := 1
+ ARTIFACTS := $$(ARTIFACTS-y)
+ SUPPORTED_DEVICES :=
+endef
+
+define Device/generic
+ DEVICE_VENDOR := Generic
+ DEVICE_MODEL := LoongArch64
+ DEVICE_PACKAGES += kmod-r8169 kmod-drm-amdgpu
+ KERNEL := kernel-bin
+ KERNEL_NAME := vmlinuz.efi
+ IMAGE/rootfs.img := append-rootfs | pad-to $(ROOTFS_PARTSIZE)
+ IMAGE/rootfs.img.gz := append-rootfs | pad-to $(ROOTFS_PARTSIZE) | gzip
+ IMAGE/combined-efi.img := grub-config efi | combined | append-metadata
+ IMAGE/combined-efi.img.gz := grub-config efi | combined | gzip | append-metadata
+ ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y)
+ IMAGES-y := rootfs.img.gz
+ IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img.gz
+ else
+ IMAGES-y := rootfs.img
+ IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img
+ endif
+ IMAGES := $$(IMAGES-y)
+endef
+TARGET_DEVICES += generic
+
+$(eval $(call BuildImage))
--- /dev/null
+@SERIAL_CONFIG@
+@TERMINAL_CONFIG@
+
+set default="0"
+set timeout="@TIMEOUT@"
+
+menuentry "@TITLE@" {
+ search --set=root --label kernel
+ linux /efi/openwrt/@KERNEL_NAME@ @GPT_ROOTPART@ @CMDLINE@ noinitrd
+}
+menuentry "@TITLE@ (failsafe)" {
+ search --set=root --label kernel
+ linux /efi/openwrt/@KERNEL_NAME@ failsafe=true @GPT_ROOTPART@ @CMDLINE@ noinitrd
+}
SUBTARGETS:=mt7622 mt7623 mt7629 filogic
FEATURES:=dt-overlay emmc fpu gpio nand pci pcie rootfs-part separate_ramdisk squashfs usb
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
DEFAULT_PACKAGES += \
;;
bananapi,bpi-r3|\
bananapi,bpi-r3-mini|\
-bananapi,bpi-4)
+bananapi,bpi-r4|\
+bananapi,bpi-r4-poe)
[ -z "$(fw_printenv -n ethaddr 2>/dev/null)" ] &&
fw_setenv ethaddr "$(cat /sys/class/net/eth0/address)"
[ -z "$(fw_printenv -n eth1addr 2>/dev/null)" ] &&
set_preinit_iface() {
case $(board_name) in
- smartrg,sdg-8622|\
- smartrg,sdg-8632)
- ip link set lan up
- ifname=lan
- ;;
+ cudy,m3000-v1|\
+ cudy,tr3000-v1|\
glinet,gl-mt3000)
ip link set eth1 up
ifname=eth1
ip link set eth0 up
ifname=eth0
;;
+ smartrg,sdg-8622|\
+ smartrg,sdg-8632)
+ ip link set lan up
+ ifname=lan
+ ;;
xiaomi,mi-router-ax3000t|\
xiaomi,mi-router-ax3000t-ubootmod|\
xiaomi,mi-router-wr30u-stock|\
#address-cells = <1>;
#size-cells = <0>;
- switch@0 {
+ switch@1f {
compatible = "mediatek,mt7531";
+ reg = <31>;
#interrupt-cells = <1>;
interrupt-controller;
interrupt-parent = <&pio>;
interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
- reg = <0>;
reset-gpios = <&pio 54 GPIO_ACTIVE_HIGH>;
ports {
#address-cells = <1>;
#size-cells = <0>;
- mt7530: switch@0 {
- compatible = "mediatek,mt7530";
+ mt7530: switch@1f {
};
};
};
&mt7530 {
compatible = "mediatek,mt7530";
+ reg = <31>;
#address-cells = <1>;
#size-cells = <0>;
- reg = <0>;
pinctrl-names = "default";
mediatek,mcm;
resets = <ðsys 2>;
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/dts-v1/;
+
+#include "mt7981.dtsi"
+
+/ {
+ model = "Cudy M3000 v1";
+ compatible = "cudy,m3000-v1", "mediatek,mt7981-spim-snand-rfb";
+
+ aliases {
+ ethernet0 = &gmac0;
+ label-mac-device = &gmac0;
+ led-boot = &led_status;
+ led-failsafe = &led_status;
+ led-running = &led_status;
+ led-upgrade = &led_status;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status: internet-white {
+ function = LED_FUNCTION_WAN_ONLINE;
+ color = <LED_COLOR_ID_WHITE>;
+ gpios = <&pio 10 GPIO_ACTIVE_LOW>;
+ };
+
+ internet-red {
+ function = LED_FUNCTION_WAN_ONLINE;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&pio 4 GPIO_ACTIVE_LOW>;
+ };
+
+ wan {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 5 GPIO_ACTIVE_LOW>;
+ };
+
+ lan {
+ function = LED_FUNCTION_LAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 9 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+ð {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+ phy-handle = <&rtl8221b_phy>;
+
+ /* the MAC address assignment using nvmem-cells doesn't work, so it's done through 02_network */
+ };
+
+ 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 0>;
+ };
+};
+
+&mdio_bus {
+ rtl8221b_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <1>;
+
+ reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>;
+
+ interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
+ reset-assert-us = <100000>;
+ reset-deassert-us = <100000>;
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_flash_pins>;
+
+ status = "okay";
+
+ spi_nand: spi_nand@0 {
+ compatible = "spi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+
+ spi-max-frequency = <52000000>;
+ spi-tx-buswidth = <4>;
+ spi-rx-buswidth = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mediatek,nmbm;
+ mediatek,bmt-max-ratio = <1>;
+ mediatek,bmt-max-reserved-blocks = <64>;
+
+ partition@0 {
+ label = "BL2";
+ reg = <0x0000000 0x0100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "u-boot-env";
+ reg = <0x0100000 0x0080000>;
+ };
+
+ factory: partition@180000 {
+ label = "Factory";
+ reg = <0x0180000 0x0200000>;
+ read-only;
+ };
+
+ bdinfo: partition@380000 {
+ label = "bdinfo";
+ reg = <0x0380000 0x0040000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_bdinfo_de00: macaddr@de00 {
+ #nvmem-cell-cells = <1>;
+ compatible = "mac-base";
+ reg = <0xde00 0x6>;
+ };
+ };
+ };
+
+ partition@3c0000 {
+ label = "FIP";
+ reg = <0x03c0000 0x0200000>;
+ };
+
+ partition@5c0000 {
+ label = "ubi";
+ reg = <0x05c0000 0x4000000>;
+ };
+ };
+ };
+};
+
+&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 = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+ };
+
+ conf-pd {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+ };
+ };
+};
+
+&wifi {
+ status = "okay";
+ mediatek,mtd-eeprom = <&factory 0x0>;
+};
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+
+#include "mt7981.dtsi"
+
+/ {
+ model = "Cudy TR3000 v1";
+ compatible = "cudy,tr3000-v1", "mediatek,mt7981-spim-snand-rfb";
+
+ aliases {
+ label-mac-device = &gmac1;
+ led-boot = &led_status;
+ led-failsafe = &led_status;
+ led-running = &led_status;
+ led-upgrade = &led_status;
+ 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>;
+ };
+
+ mode {
+ label = "mode";
+ linux,input-type = <EV_SW>;
+ linux,code = <BTN_0>;
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ debounce-interval = <60>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status: led_0 {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&pio 11 GPIO_ACTIVE_LOW>;
+ };
+
+ led_1 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_WHITE>;
+ gpios = <&pio 10 GPIO_ACTIVE_LOW>;
+ };
+
+ };
+
+ usb_vbus: regulator-usb {
+ compatible = "regulator-fixed";
+
+ regulator-name = "usb-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+
+ gpio = <&pio 9 GPIO_ACTIVE_LOW>;
+ regulator-boot-on;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+ð {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+ phy-handle = <&phy1>;
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_bdinfo_de00 1>;
+ };
+
+ 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 0>;
+ };
+};
+
+&mdio_bus {
+ phy1: phy@1 {
+ reg = <1>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ phy-mode = "2500base-x";
+ reset-gpios = <&pio 39 GPIO_ACTIVE_LOW>;
+ interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
+ reset-assert-us = <100000>;
+ reset-deassert-us = <100000>;
+ realtek,aldps-enable;
+ };
+};
+
+&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";
+ };
+ };
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&xhci {
+ status = "okay";
+ vbus-supply = <&usb_vbus>;
+};
+
+&wifi {
+ status = "okay";
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+};
#size-cells = <0>;
port@1 {
- reg = <4>;
- label = "lan1";
+ reg = <1>;
+ label = "lan4";
phy-handle = <&swphy1>;
};
port@2 {
- reg = <3>;
- label = "lan2";
+ reg = <2>;
+ label = "lan3";
phy-handle = <&swphy2>;
};
port@3 {
- reg = <2>;
- label = "lan3";
+ reg = <3>;
+ label = "lan2";
phy-handle = <&swphy3>;
};
port@4 {
- reg = <1>;
- label = "lan4";
+ reg = <4>;
+ label = "lan1";
phy-handle = <&swphy4>;
};
};
chosen {
+ bootargs-override = "root=/dev/fit0 rootwait";
stdout-path = "serial0:115200n8";
+ rootdisk = <&emmc_rootdisk>;
};
memory@40000000 {
vmmc-supply = <®_3p3v>;
vqmmc-supply = <®_1p8v>;
status = "okay";
+
+ card@0 {
+ compatible = "mmc-card";
+ reg = <0>;
+
+ block {
+ compatible = "block-device";
+ partitions {
+ emmc_rootdisk: block-partition-production {
+ partname = "production";
+ };
+ };
+ };
+ };
};
&pio {
+++ /dev/null
-/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
-
- fragment@0 {
- target = <&gmac1>;
- __overlay__ {
- phy-mode = "2500base-x";
- phy-handle = <&phy5>;
- };
- };
-
- fragment@1 {
- target = <&mdio_bus>;
- __overlay__ {
- reset-gpios = <&pio 14 GPIO_ACTIVE_LOW>;
- reset-delay-us = <600>;
- reset-post-delay-us = <20000>;
-
- phy5: ethernet-phy@5 {
- reg = <5>;
- compatible = "ethernet-phy-ieee802.3-c45";
- phy-mode = "2500base-x";
- };
- };
- };
-};
+++ /dev/null
-/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
-
- fragment@0 {
- target = <&sw_p5>;
- __overlay__ {
- phy-mode = "2500base-x";
- phy-handle = <&phy5>;
- status = "okay";
- };
- };
-
- fragment@1 {
- target = <&mdio_bus>;
- __overlay__ {
- reset-gpios = <&pio 14 GPIO_ACTIVE_LOW>;
- reset-delay-us = <600>;
- reset-post-delay-us = <20000>;
-
- phy5: ethernet-phy@5 {
- reg = <5>;
- compatible = "ethernet-phy-ieee802.3-c45";
- phy-mode = "2500base-x";
- };
- };
- };
-};
+++ /dev/null
-/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
-/dts-v1/;
-/plugin/;
-
-/ {
- compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
-
- fragment@0 {
- target = <&spi0>;
- __overlay__ {
- status = "okay";
- #address-cells = <1>;
- #size-cells = <0>;
-
- spi_nand: spi_nand@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spi-nand";
- reg = <1>;
- spi-max-frequency = <10000000>;
- 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 = <0x00000 0x0100000>;
- read-only;
- };
-
- partition@100000 {
- label = "u-boot-env";
- reg = <0x0100000 0x0080000>;
- };
-
- factory: partition@180000 {
- label = "Factory";
- reg = <0x180000 0x0200000>;
- };
-
- partition@380000 {
- label = "FIP";
- reg = <0x380000 0x0200000>;
- };
-
- partition@580000 {
- label = "ubi";
- reg = <0x580000 0x4000000>;
- };
- };
- };
- };
- };
-
- fragment@1 {
- target = <&wifi>;
- __overlay__ {
- mediatek,mtd-eeprom = <&factory 0x0>;
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-#include "mt7981.dtsi"
-
-/ {
- model = "MediaTek MT7981 RFB";
- compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
-
- aliases {
- serial0 = &uart0;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- memory {
- reg = <0 0x40000000 0 0x20000000>;
- };
-
- 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;
- };
-
- 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_HIGH>;
- };
- };
-};
-
-ð {
- 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 = <&int_gbe_phy>;
- };
-};
-
-&mdio_bus {
- switch: switch@1f {
- compatible = "mediatek,mt7531";
- reg = <31>;
- interrupt-controller;
- #interrupt-cells = <1>;
- interrupt-parent = <&pio>;
- interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
- reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
- };
-};
-
-&crypto {
- status = "okay";
-};
-
-&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 = <MTK_DRIVE_8mA>;
- bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
- };
- conf-pd {
- pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
- drive-strength = <MTK_DRIVE_8mA>;
- bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
- };
- };
-
-};
-
-&spi0 {
- pinctrl-names = "default";
- pinctrl-0 = <&spi0_flash_pins>;
- cs-gpios = <0>, <0>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-};
-
-&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";
- };
-
- sw_p5: port@5 {
- reg = <5>;
- label = "lan5";
- status = "disabled";
- };
-
- port@6 {
- reg = <6>;
- ethernet = <&gmac0>;
- phy-mode = "2500base-x";
-
- fixed-link {
- speed = <2500>;
- full-duplex;
- pause;
- };
- };
- };
-};
-
-&xhci {
- vusb33-supply = <®_3p3v>;
- vbus-supply = <®_5v>;
- status = "okay";
-};
-
-&uart0 {
- status = "okay";
-};
-
-&usb_phy {
- status = "okay";
-};
-
-&watchdog {
- status = "okay";
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (c) 2020 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- * Author: Jianhui Zhao <zhaojh329@gmail.com>
- */
-
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/phy/phy.h>
-#include <dt-bindings/clock/mediatek,mt7981-clk.h>
-#include <dt-bindings/reset/mt7986-resets.h>
-#include <dt-bindings/pinctrl/mt65xx.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/input/linux-event-codes.h>
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/mux/mux.h>
-
-/ {
- compatible = "mediatek,mt7981";
- interrupt-parent = <&gic>;
- #address-cells = <2>;
- #size-cells = <2>;
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- compatible = "arm,cortex-a53";
- reg = <0x0>;
- device_type = "cpu";
- enable-method = "psci";
- };
-
- cpu@1 {
- compatible = "arm,cortex-a53";
- reg = <0x1>;
- device_type = "cpu";
- enable-method = "psci";
- };
- };
-
- ice: ice_debug {
- compatible = "mediatek,mt7981-ice_debug", "mediatek,mt2701-ice_debug";
- clocks = <&infracfg CLK_INFRA_DBG_CK>;
- clock-names = "ice_dbg";
- };
-
- clk40m: oscillator-40m {
- compatible = "fixed-clock";
- clock-frequency = <40000000>;
- clock-output-names = "clkxtal";
- #clock-cells = <0>;
- };
-
- psci {
- compatible = "arm,psci-0.2";
- method = "smc";
- };
-
- fan: pwm-fan {
- compatible = "pwm-fan";
- /* cooling level (0, 1, 2, 3, 4, 5, 6, 7) : (0%/25%/37.5%/50%/62.5%/75%/87.5%/100% duty) */
- cooling-levels = <0 63 95 127 159 191 223 255>;
- #cooling-cells = <2>;
- status = "disabled";
- };
-
- 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;
- };
-
- reserved-memory {
- ranges;
- #address-cells = <2>;
- #size-cells = <2>;
-
- /* 64 KiB reserved for ramoops/pstore */
- ramoops@42ff0000 {
- compatible = "ramoops";
- reg = <0 0x42ff0000 0 0x10000>;
- record-size = <0x1000>;
- };
-
- /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
- secmon_reserved: secmon@43000000 {
- reg = <0 0x43000000 0 0x30000>;
- no-map;
- };
-
- wmcpu_emi: wmcpu-reserved@47c80000 {
- reg = <0 0x47c80000 0 0x100000>;
- no-map;
- };
-
- wo_emi0: wo-emi@47d80000 {
- reg = <0 0x47d80000 0 0x40000>;
- no-map;
- };
-
- wo_data: wo-data@47dc0000 {
- reg = <0 0x47dc0000 0 0x240000>;
- no-map;
- };
- };
-
- soc {
- compatible = "simple-bus";
- ranges;
- #address-cells = <2>;
- #size-cells = <2>;
-
- gic: interrupt-controller@c000000 {
- compatible = "arm,gic-v3";
- reg = <0 0x0c000000 0 0x40000>, /* GICD */
- <0 0x0c080000 0 0x200000>; /* GICR */
- interrupt-parent = <&gic>;
- interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-controller;
- #interrupt-cells = <3>;
- };
-
- consys: consys@10000000 {
- compatible = "mediatek,mt7981-consys";
- reg = <0 0x10000000 0 0x8600000>;
- memory-region = <&wmcpu_emi>;
- };
-
- infracfg: clock-controller@10001000 {
- compatible = "mediatek,mt7981-infracfg", "syscon";
- reg = <0 0x10001000 0 0x1000>;
- #clock-cells = <1>;
- };
-
- wed_pcie: wed_pcie@10003000 {
- compatible = "mediatek,wed_pcie";
- reg = <0 0x10003000 0 0x10>;
- };
-
- topckgen: clock-controller@1001b000 {
- compatible = "mediatek,mt7981-topckgen", "syscon";
- reg = <0 0x1001b000 0 0x1000>;
- #clock-cells = <1>;
- };
-
- watchdog: watchdog@1001c000 {
- compatible = "mediatek,mt7986-wdt",
- "mediatek,mt6589-wdt";
- reg = <0 0x1001c000 0 0x1000>;
- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
- #reset-cells = <1>;
- status = "disabled";
- };
-
- apmixedsys: clock-controller@1001e000 {
- compatible = "mediatek,mt7981-apmixedsys", "syscon";
- reg = <0 0x1001e000 0 0x1000>;
- #clock-cells = <1>;
- };
-
- pwm: pwm@10048000 {
- compatible = "mediatek,mt7981-pwm";
- reg = <0 0x10048000 0 0x1000>;
- clocks = <&infracfg CLK_INFRA_PWM_STA>,
- <&infracfg CLK_INFRA_PWM_HCK>,
- <&infracfg CLK_INFRA_PWM1_CK>,
- <&infracfg CLK_INFRA_PWM2_CK>,
- <&infracfg CLK_INFRA_PWM3_CK>;
- clock-names = "top", "main", "pwm1", "pwm2", "pwm3";
- #pwm-cells = <2>;
- };
-
- sgmiisys0: syscon@10060000 {
- compatible = "mediatek,mt7981-sgmiisys_0", "syscon";
- reg = <0 0x10060000 0 0x1000>;
- mediatek,pnswap;
- #clock-cells = <1>;
- };
-
- sgmiisys1: syscon@10070000 {
- compatible = "mediatek,mt7981-sgmiisys_1", "syscon";
- reg = <0 0x10070000 0 0x1000>;
- #clock-cells = <1>;
- };
-
- crypto: crypto@10320000 {
- compatible = "inside-secure,safexcel-eip97";
- reg = <0 0x10320000 0 0x40000>;
- interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "ring0", "ring1", "ring2", "ring3";
- clocks = <&topckgen CLK_TOP_EIP97B>;
- clock-names = "top_eip97_ck";
- assigned-clocks = <&topckgen CLK_TOP_EIP97B_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_CB_NET1_D5>;
- };
-
- uart0: serial@11002000 {
- compatible = "mediatek,mt6577-uart";
- reg = <0 0x11002000 0 0x400>;
- interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_UART0_SEL>,
- <&infracfg CLK_INFRA_UART0_CK>;
- clock-names = "baud", "bus";
- assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
- <&infracfg CLK_INFRA_UART0_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_CB_CKSQ_40M>,
- <&topckgen CLK_TOP_UART_SEL>;
- pinctrl-0 = <&uart0_pins>;
- pinctrl-names = "default";
- status = "disabled";
- };
-
- uart1: serial@11003000 {
- compatible = "mediatek,mt6577-uart";
- reg = <0 0x11003000 0 0x400>;
- interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_UART1_SEL>,
- <&infracfg CLK_INFRA_UART1_CK>;
- clock-names = "baud", "bus";
- assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
- <&infracfg CLK_INFRA_UART1_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_CB_CKSQ_40M>,
- <&topckgen CLK_TOP_UART_SEL>;
- status = "disabled";
- };
-
- uart2: serial@11004000 {
- compatible = "mediatek,mt6577-uart";
- reg = <0 0x11004000 0 0x400>;
- interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_UART2_SEL>,
- <&infracfg CLK_INFRA_UART2_CK>;
- clock-names = "baud", "bus";
- assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
- <&infracfg CLK_INFRA_UART2_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_CB_CKSQ_40M>,
- <&topckgen CLK_TOP_UART_SEL>;
- status = "disabled";
- };
-
- snand: snfi@11005000 {
- compatible = "mediatek,mt7986-snand";
- reg = <0 0x11005000 0 0x1000>, <0 0x11006000 0 0x1000>;
- reg-names = "nfi", "ecc";
- interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_SPINFI1_CK>,
- <&infracfg CLK_INFRA_NFI1_CK>,
- <&infracfg CLK_INFRA_NFI_HCK_CK>;
- clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
- assigned-clocks = <&topckgen CLK_TOP_SPINFI_SEL>,
- <&topckgen CLK_TOP_NFI1X_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D8>,
- <&topckgen CLK_TOP_CB_M_D8>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c0: i2c@11007000 {
- compatible = "mediatek,mt7981-i2c";
- reg = <0 0x11007000 0 0x1000>,
- <0 0x10217080 0 0x80>;
- interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
- clock-div = <1>;
- clocks = <&infracfg CLK_INFRA_I2C0_CK>,
- <&infracfg CLK_INFRA_AP_DMA_CK>,
- <&infracfg CLK_INFRA_I2C_MCK_CK>,
- <&infracfg CLK_INFRA_I2C_PCK_CK>;
- clock-names = "main", "dma", "arb", "pmic";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi2: spi@11009000 {
- compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
- reg = <0 0x11009000 0 0x100>;
- interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&topckgen CLK_TOP_CB_M_D2>,
- <&topckgen CLK_TOP_SPI_SEL>,
- <&infracfg CLK_INFRA_SPI2_CK>,
- <&infracfg CLK_INFRA_SPI2_HCK_CK>;
- clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi0: spi@1100a000 {
- compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
- reg = <0 0x1100a000 0 0x100>;
- interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&topckgen CLK_TOP_CB_M_D2>,
- <&topckgen CLK_TOP_SPI_SEL>,
- <&infracfg CLK_INFRA_SPI0_CK>,
- <&infracfg CLK_INFRA_SPI0_HCK_CK>;
- clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi1: spi@1100b000 {
- compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
- reg = <0 0x1100b000 0 0x100>;
- interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&topckgen CLK_TOP_CB_M_D2>,
- <&topckgen CLK_TOP_SPIM_MST_SEL>,
- <&infracfg CLK_INFRA_SPI1_CK>,
- <&infracfg CLK_INFRA_SPI1_HCK_CK>;
- clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- thermal: thermal@1100c800 {
- compatible = "mediatek,mt7981-thermal", "mediatek,mt7986-thermal";
- reg = <0 0x1100c800 0 0x800>;
- interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_THERM_CK>,
- <&infracfg CLK_INFRA_ADC_26M_CK>;
- clock-names = "therm", "auxadc";
- nvmem-cells = <&thermal_calibration>;
- nvmem-cell-names = "calibration-data";
- #thermal-sensor-cells = <1>;
- mediatek,auxadc = <&auxadc>;
- mediatek,apmixedsys = <&apmixedsys>;
- };
-
- auxadc: adc@1100d000 {
- compatible = "mediatek,mt7981-auxadc",
- "mediatek,mt7986-auxadc",
- "mediatek,mt7622-auxadc";
- reg = <0 0x1100d000 0 0x1000>;
- clocks = <&infracfg CLK_INFRA_ADC_26M_CK>,
- <&infracfg CLK_INFRA_ADC_FRC_CK>;
- clock-names = "main", "32k";
- #io-channel-cells = <1>;
- };
-
- xhci: usb@11200000 {
- compatible = "mediatek,mt7986-xhci",
- "mediatek,mtk-xhci";
- reg = <0 0x11200000 0 0x2e00>,
- <0 0x11203e00 0 0x0100>;
- reg-names = "mac", "ippc";
- interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>,
- <&infracfg CLK_INFRA_IUSB_CK>,
- <&infracfg CLK_INFRA_IUSB_133_CK>,
- <&infracfg CLK_INFRA_IUSB_66M_CK>,
- <&topckgen CLK_TOP_U2U3_XHCI_SEL>;
- clock-names = "sys_ck",
- "ref_ck",
- "mcu_ck",
- "dma_ck",
- "xhci_ck";
- phys = <&u2port0 PHY_TYPE_USB2>,
- <&u3port0 PHY_TYPE_USB3>;
- vusb33-supply = <®_3p3v>;
- status = "disabled";
- };
-
- afe: audio-controller@11210000 {
- compatible = "mediatek,mt79xx-audio";
- reg = <0 0x11210000 0 0x9000>;
- interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_AUD_BUS_CK>,
- <&infracfg CLK_INFRA_AUD_26M_CK>,
- <&infracfg CLK_INFRA_AUD_L_CK>,
- <&infracfg CLK_INFRA_AUD_AUD_CK>,
- <&infracfg CLK_INFRA_AUD_EG2_CK>,
- <&topckgen CLK_TOP_AUD_SEL>;
- clock-names = "aud_bus_ck",
- "aud_26m_ck",
- "aud_l_ck",
- "aud_aud_ck",
- "aud_eg2_ck",
- "aud_sel";
- assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>,
- <&topckgen CLK_TOP_A1SYS_SEL>,
- <&topckgen CLK_TOP_AUD_L_SEL>,
- <&topckgen CLK_TOP_A_TUNER_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_CB_APLL2_196M>,
- <&topckgen CLK_TOP_APLL2_D4>,
- <&topckgen CLK_TOP_CB_APLL2_196M>,
- <&topckgen CLK_TOP_APLL2_D4>;
- status = "disabled";
- };
-
- mmc0: mmc@11230000 {
- compatible = "mediatek,mt7986-mmc", "mediatek,mt7981-mmc";
- reg = <0 0x11230000 0 0x1000>, <0 0x11c20000 0 0x1000>;
- interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_MSDC_CK>,
- <&infracfg CLK_INFRA_MSDC_HCK_CK>,
- <&infracfg CLK_INFRA_MSDC_66M_CK>,
- <&infracfg CLK_INFRA_MSDC_133M_CK>;
- assigned-clocks = <&topckgen CLK_TOP_EMMC_208M_SEL>,
- <&topckgen CLK_TOP_EMMC_400M_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
- <&topckgen CLK_TOP_CB_NET2_D2>;
- clock-names = "source", "hclk", "axi_cg", "ahb_cg";
- status = "disabled";
- };
-
- pcie: pcie@11280000 {
- compatible = "mediatek,mt7981-pcie",
- "mediatek,mt7986-pcie";
- reg = <0 0x11280000 0 0x4000>;
- reg-names = "pcie-mac";
- ranges = <0x82000000 0 0x20000000
- 0x0 0x20000000 0 0x10000000>;
- device_type = "pci";
- interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
- bus-range = <0x00 0xff>;
- clocks = <&infracfg CLK_INFRA_IPCIE_CK>,
- <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
- <&infracfg CLK_INFRA_IPCIER_CK>,
- <&infracfg CLK_INFRA_IPCIEB_CK>;
- phys = <&u3port0 PHY_TYPE_PCIE>;
- phy-names = "pcie-phy";
- interrupt-map-mask = <0 0 0 7>;
- interrupt-map = <0 0 0 1 &pcie_intc 0>,
- <0 0 0 2 &pcie_intc 1>,
- <0 0 0 3 &pcie_intc 2>,
- <0 0 0 4 &pcie_intc 3>;
- #interrupt-cells = <1>;
- #address-cells = <3>;
- #size-cells = <2>;
- status = "disabled";
-
- pcie_intc: interrupt-controller {
- interrupt-controller;
- #interrupt-cells = <1>;
- #address-cells = <0>;
- };
- };
-
- pio: pinctrl@11d00000 {
- compatible = "mediatek,mt7981-pinctrl";
- reg = <0 0x11d00000 0 0x1000>,
- <0 0x11c00000 0 0x1000>,
- <0 0x11c10000 0 0x1000>,
- <0 0x11d20000 0 0x1000>,
- <0 0x11e00000 0 0x1000>,
- <0 0x11e20000 0 0x1000>,
- <0 0x11f00000 0 0x1000>,
- <0 0x11f10000 0 0x1000>,
- <0 0x1000b000 0 0x1000>;
- reg-names = "gpio", "iocfg_rt", "iocfg_rm",
- "iocfg_rb", "iocfg_lb", "iocfg_bl",
- "iocfg_tm", "iocfg_tl", "eint";
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&pio 0 0 56>;
- interrupt-controller;
- interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-parent = <&gic>;
- #interrupt-cells = <2>;
-
- mdio_pins: mdc-mdio-pins {
- mux {
- function = "eth";
- groups = "smi_mdc_mdio";
- };
- };
-
- uart0_pins: uart0-pins {
- mux {
- function = "uart";
- groups = "uart0";
- };
- };
-
- wifi_dbdc_pins: wifi-dbdc-pins {
- mux {
- function = "eth";
- groups = "wf0_mode1";
- };
-
- conf {
- pins = "WF_HB1", "WF_HB2", "WF_HB3", "WF_HB4",
- "WF_HB0", "WF_HB0_B", "WF_HB5", "WF_HB6",
- "WF_HB7", "WF_HB8", "WF_HB9", "WF_HB10",
- "WF_TOP_CLK", "WF_TOP_DATA", "WF_XO_REQ",
- "WF_CBA_RESETB", "WF_DIG_RESETB";
- drive-strength = <4>;
- };
- };
-
- gbe_led0_pins: gbe-led0-pins {
- mux {
- function = "led";
- groups = "gbe_led0";
- };
- };
-
- gbe_led1_pins: gbe-led1-pins {
- mux {
- function = "led";
- groups = "gbe_led1";
- };
- };
- };
-
- topmisc: topmisc@11d10000 {
- compatible = "mediatek,mt7981-topmisc", "syscon";
- reg = <0 0x11d10000 0 0x10000>;
- #clock-cells = <1>;
- };
-
- usb_phy: usb-phy@11e10000 {
- compatible = "mediatek,mt7981",
- "mediatek,generic-tphy-v2";
- ranges = <0 0 0x11e10000 0x1700>;
- #address-cells = <1>;
- #size-cells = <1>;
- status = "disabled";
-
- u2port0: usb-phy@0 {
- reg = <0x0 0x700>;
- clocks = <&topckgen CLK_TOP_USB_FRMCNT_SEL>;
- clock-names = "ref";
- #phy-cells = <1>;
- };
-
- u3port0: usb-phy@700 {
- reg = <0x700 0x900>;
- clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>;
- clock-names = "ref";
- #phy-cells = <1>;
- mediatek,syscon-type = <&topmisc 0x218 0>;
- status = "okay";
- };
- };
-
- efuse: efuse@11f20000 {
- compatible = "mediatek,mt7981-efuse",
- "mediatek,efuse";
- reg = <0 0x11f20000 0 0x1000>;
- #address-cells = <1>;
- #size-cells = <1>;
- status = "okay";
-
- thermal_calibration: thermal-calib@274 {
- reg = <0x274 0xc>;
- };
-
- phy_calibration: phy-calib@8dc {
- reg = <0x8dc 0x10>;
- };
-
- comb_rx_imp_p0: usb3-rx-imp@8c8 {
- reg = <0x8c8 1>;
- bits = <0 5>;
- };
-
- comb_tx_imp_p0: usb3-tx-imp@8c8 {
- reg = <0x8c8 2>;
- bits = <5 5>;
- };
-
- comb_intr_p0: usb3-intr@8c9 {
- reg = <0x8c9 1>;
- bits = <2 6>;
- };
- };
-
- ethsys: clock-controller@15000000 {
- compatible = "mediatek,mt7981-ethsys",
- "syscon";
- reg = <0 0x15000000 0 0x1000>;
- #clock-cells = <1>;
- #reset-cells = <1>;
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
- wed: wed@15010000 {
- compatible = "mediatek,mt7981-wed",
- "mediatek,mt7986-wed",
- "syscon";
- reg = <0 0x15010000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
- memory-region = <&wo_emi0>, <&wo_data>;
- memory-region-names = "wo-emi", "wo-data";
- mediatek,wo-ccif = <&wo_ccif0>;
- mediatek,wo-ilm = <&wo_ilm0>;
- mediatek,wo-dlm = <&wo_dlm0>;
- mediatek,wo-cpuboot = <&wo_cpuboot>;
- };
-
- eth: ethernet@15100000 {
- compatible = "mediatek,mt7981-eth";
- reg = <0 0x15100000 0 0x80000>;
- interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <ðsys CLK_ETH_FE_EN>,
- <ðsys CLK_ETH_GP2_EN>,
- <ðsys CLK_ETH_GP1_EN>,
- <ðsys CLK_ETH_WOCPU0_EN>,
- <&sgmiisys0 CLK_SGM0_TX_EN>,
- <&sgmiisys0 CLK_SGM0_RX_EN>,
- <&sgmiisys0 CLK_SGM0_CK0_EN>,
- <&sgmiisys0 CLK_SGM0_CDR_CK0_EN>,
- <&sgmiisys1 CLK_SGM1_TX_EN>,
- <&sgmiisys1 CLK_SGM1_RX_EN>,
- <&sgmiisys1 CLK_SGM1_CK1_EN>,
- <&sgmiisys1 CLK_SGM1_CDR_CK1_EN>,
- <&topckgen CLK_TOP_SGM_REG>,
- <&topckgen CLK_TOP_NETSYS_SEL>,
- <&topckgen CLK_TOP_NETSYS_500M_SEL>;
- clock-names = "fe", "gp2", "gp1", "wocpu0",
- "sgmii_tx250m", "sgmii_rx250m",
- "sgmii_cdr_ref", "sgmii_cdr_fb",
- "sgmii2_tx250m", "sgmii2_rx250m",
- "sgmii2_cdr_ref", "sgmii2_cdr_fb",
- "sgmii_ck", "netsys0", "netsys1";
- assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
- <&topckgen CLK_TOP_SGM_325M_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_CB_NET2_800M>,
- <&topckgen CLK_TOP_CB_SGM_325M>;
- mediatek,ethsys = <ðsys>;
- mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
- mediatek,infracfg = <&topmisc>;
- mediatek,wed = <&wed>;
- #reset-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-
- mdio_bus: mdio-bus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- int_gbe_phy: ethernet-phy@0 {
- compatible = "ethernet-phy-ieee802.3-c22";
- reg = <0>;
- phy-mode = "gmii";
- phy-is-integrated;
- nvmem-cells = <&phy_calibration>;
- nvmem-cell-names = "phy-cal-data";
-
- leds {
- #address-cells = <1>;
- #size-cells = <0>;
-
- int_gbe_phy_led0: int-gbe-phy-led0@0 {
- reg = <0>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
-
- int_gbe_phy_led1: int-gbe-phy-led1@1 {
- reg = <1>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
- };
- };
- };
- };
-
- wdma: wdma@15104800 {
- compatible = "mediatek,wed-wdma";
- reg = <0 0x15104800 0 0x400>,
- <0 0x15104c00 0 0x400>;
- };
-
- wo_cpuboot: syscon@15194000 {
- compatible = "mediatek,mt7986-wo-cpuboot", "syscon";
- reg = <0 0x15194000 0 0x1000>;
- };
-
- ap2woccif: ap2woccif@151a5000 {
- compatible = "mediatek,ap2woccif";
- reg = <0 0x151a5000 0 0x1000>,
- <0 0x151ad000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- wo_ccif0: syscon@151a5000 {
- compatible = "mediatek,mt7986-wo-ccif", "syscon";
- reg = <0 0x151a5000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- wo_ilm0: syscon@151e0000 {
- compatible = "mediatek,mt7986-wo-ilm", "syscon";
- reg = <0 0x151e0000 0 0x8000>;
- };
-
- wo_dlm0: syscon@151e8000 {
- compatible = "mediatek,mt7986-wo-dlm", "syscon";
- reg = <0 0x151e8000 0 0x2000>;
- };
-
- wifi: wifi@18000000 {
- compatible = "mediatek,mt7981-wmac";
- reg = <0 0x18000000 0 0x1000000>,
- <0 0x10003000 0 0x1000>,
- <0 0x11d10000 0 0x1000>;
- resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>;
- reset-names = "consys";
- pinctrl-0 = <&wifi_dbdc_pins>;
- pinctrl-names = "dbdc";
- clocks = <&topckgen CLK_TOP_NETSYS_MCU_SEL>,
- <&topckgen CLK_TOP_AP2CNN_HOST_SEL>;
- clock-names = "mcu", "ap2conn";
- interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
- memory-region = <&wmcpu_emi>;
- status = "disabled";
- };
- };
-
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <1000>;
- polling-delay = <1000>;
- thermal-sensors = <&thermal 0>;
-
- trips {
- cpu_trip_active_highest: active-highest {
- temperature = <70000>;
- hysteresis = <2000>;
- type = "active";
- };
-
- cpu_trip_active_high: active-high {
- temperature = <60000>;
- hysteresis = <2000>;
- type = "active";
- };
-
- cpu_trip_active_med: active-med {
- temperature = <50000>;
- hysteresis = <2000>;
- type = "active";
- };
-
- cpu_trip_active_low: active-low {
- temperature = <45000>;
- hysteresis = <2000>;
- type = "active";
- };
-
- cpu_trip_active_lowest: active-lowest {
- temperature = <40000>;
- hysteresis = <2000>;
- type = "active";
- };
- };
-
- cooling-maps {
- cpu-active-highest {
- /* active: set fan to cooling level 7 */
- cooling-device = <&fan 7 7>;
- trip = <&cpu_trip_active_highest>;
- };
-
- cpu-active-high {
- /* active: set fan to cooling level 5 */
- cooling-device = <&fan 5 5>;
- trip = <&cpu_trip_active_high>;
- };
-
- cpu-active-med {
- /* active: set fan to cooling level 3 */
- cooling-device = <&fan 3 3>;
- trip = <&cpu_trip_active_med>;
- };
-
- cpu-active-low {
- /* active: set fan to cooling level 2 */
- cooling-device = <&fan 2 2>;
- trip = <&cpu_trip_active_low>;
- };
-
- cpu-active-lowest {
- /* active: set fan to cooling level 1 */
- cooling-device = <&fan 1 1>;
- trip = <&cpu_trip_active_lowest>;
- };
- };
- };
- };
-
- timer {
- compatible = "arm,armv8-timer";
- interrupt-parent = <&gic>;
- clock-frequency = <13000000>;
- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
-
- };
-
- trng {
- compatible = "mediatek,mt7981-rng";
- };
-};
+++ /dev/null
-/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
-
-#include "mt7986a-rfb.dtsi"
-
-/ {
- compatible = "mediatek,mt7986a-rfb-snand";
-};
-
-&spi0 {
- status = "okay";
-
- spi_nand: spi_nand@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "spi-nand";
- reg = <1>;
- spi-max-frequency = <10000000>;
- 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 = <0x00000 0x0100000>;
- read-only;
- };
- partition@100000 {
- label = "u-boot-env";
- reg = <0x0100000 0x0080000>;
- };
- factory: partition@180000 {
- label = "Factory";
- reg = <0x180000 0x0200000>;
- };
- partition@380000 {
- label = "FIP";
- reg = <0x380000 0x0200000>;
- };
- partition@580000 {
- label = "ubi";
- reg = <0x580000 0x4000000>;
- };
- };
- };
-};
-
-&wifi {
- mediatek,mtd-eeprom = <&factory 0>;
-};
+++ /dev/null
-/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
-
-#include "mt7986a-rfb.dtsi"
-
-/ {
- compatible = "mediatek,mt7986a-rfb-snor";
-};
-
-&spi0 {
- status = "okay";
-
- spi_nor: spi_nor@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "jedec,spi-nor";
- 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@00000 {
- label = "BL2";
- reg = <0x00000 0x0040000>;
- };
- partition@40000 {
- label = "u-boot-env";
- reg = <0x40000 0x0010000>;
- };
- factory: partition@50000 {
- label = "Factory";
- reg = <0x50000 0x00B0000>;
- };
- partition@100000 {
- label = "FIP";
- reg = <0x100000 0x0080000>;
- };
- partition@180000 {
- label = "firmware";
- reg = <0x180000 0xE00000>;
- };
- };
- };
-};
-
-&wifi {
- mediatek,mtd-eeprom = <&factory 0>;
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2021 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-#include "mt7986a.dtsi"
-
-/ {
- model = "MediaTek MT7986a RFB";
- compatible = "mediatek,mt7986a-rfb";
-
- aliases {
- serial0 = &uart0;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- memory {
- reg = <0 0x40000000 0 0x40000000>;
- };
-
- reg_1p8v: regulator-1p8v {
- compatible = "regulator-fixed";
- regulator-name = "fixed-1.8V";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- 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;
- };
-};
-
-ð {
- 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 = "2500base-x";
- };
-
- mdio: mdio-bus {
- #address-cells = <1>;
- #size-cells = <0>;
- };
-};
-
-&wifi {
- status = "okay";
- pinctrl-names = "default", "dbdc";
- pinctrl-0 = <&wf_2g_5g_pins>;
- pinctrl-1 = <&wf_dbdc_pins>;
-};
-
-&mdio {
- phy5: phy@5 {
- compatible = "ethernet-phy-id67c9.de0a";
- reg = <5>;
-
- reset-gpios = <&pio 6 1>;
- reset-deassert-us = <20000>;
- };
-
- phy6: phy@6 {
- compatible = "ethernet-phy-id67c9.de0a";
- reg = <6>;
- };
-
- switch: switch@1f {
- compatible = "mediatek,mt7531";
- reg = <31>;
- reset-gpios = <&pio 5 0>;
- };
-};
-
-&crypto {
- status = "okay";
-};
-
-&mmc0 {
- pinctrl-names = "default", "state_uhs";
- pinctrl-0 = <&mmc0_pins_default>;
- pinctrl-1 = <&mmc0_pins_uhs>;
- bus-width = <8>;
- max-frequency = <200000000>;
- cap-mmc-highspeed;
- mmc-hs200-1_8v;
- mmc-hs400-1_8v;
- hs400-ds-delay = <0x14014>;
- vmmc-supply = <®_3p3v>;
- vqmmc-supply = <®_1p8v>;
- non-removable;
- no-sd;
- no-sdio;
- status = "okay";
-};
-
-&pcie {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie_pins>;
- status = "okay";
-};
-
-&pcie_phy {
- status = "okay";
-};
-
-&pio {
- mmc0_pins_default: mmc0-pins {
- mux {
- function = "emmc";
- groups = "emmc_51";
- };
- conf-cmd-dat {
- pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
- "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
- "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
- input-enable;
- drive-strength = <4>;
- mediatek,pull-up-adv = <1>; /* pull-up 10K */
- };
- conf-clk {
- pins = "EMMC_CK";
- drive-strength = <6>;
- mediatek,pull-down-adv = <2>; /* pull-down 50K */
- };
- conf-ds {
- pins = "EMMC_DSL";
- mediatek,pull-down-adv = <2>; /* pull-down 50K */
- };
- conf-rst {
- pins = "EMMC_RSTB";
- drive-strength = <4>;
- mediatek,pull-up-adv = <1>; /* pull-up 10K */
- };
- };
-
- mmc0_pins_uhs: mmc0-uhs-pins {
- mux {
- function = "emmc";
- groups = "emmc_51";
- };
- conf-cmd-dat {
- pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
- "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
- "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
- input-enable;
- drive-strength = <4>;
- mediatek,pull-up-adv = <1>; /* pull-up 10K */
- };
- conf-clk {
- pins = "EMMC_CK";
- drive-strength = <6>;
- mediatek,pull-down-adv = <2>; /* pull-down 50K */
- };
- conf-ds {
- pins = "EMMC_DSL";
- mediatek,pull-down-adv = <2>; /* pull-down 50K */
- };
- conf-rst {
- pins = "EMMC_RSTB";
- drive-strength = <4>;
- mediatek,pull-up-adv = <1>; /* pull-up 10K */
- };
- };
-
- pcie_pins: pcie-pins {
- mux {
- function = "pcie";
- groups = "pcie_clk", "pcie_wake", "pcie_pereset";
- };
- };
-
- spic_pins_g2: spic-pins-29-to-32 {
- mux {
- function = "spi";
- groups = "spi1_2";
- };
- };
-
- 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 */
- };
- };
-
- uart1_pins: uart1-pins {
- mux {
- function = "uart";
- groups = "uart1";
- };
- };
-
- uart2_pins: uart2-pins {
- mux {
- function = "uart";
- groups = "uart2";
- };
- };
-
- 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>;
- };
- };
-
- wf_dbdc_pins: wf_dbdc-pins {
- mux {
- function = "wifi";
- groups = "wf_dbdc";
- };
- 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>;
- cs-gpios = <0>, <0>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
-};
-
-&spi1 {
- pinctrl-names = "default";
- pinctrl-0 = <&spic_pins_g2>;
- status = "okay";
-
- proslic_spi: proslic_spi@0 {
- compatible = "silabs,proslic_spi";
- reg = <0>;
- spi-max-frequency = <10000000>;
- spi-cpha = <1>;
- spi-cpol = <1>;
- channel_count = <1>;
- debug_level = <4>; /* 1 = TRC, 2 = DBG, 4 = ERR */
- reset_gpio = <&pio 7 0>;
- ig,enable-spi = <1>; /* 1: Enable, 0: Disable */
- };
-};
-
-&gmac1 {
- phy-mode = "2500base-x";
- phy-connection-type = "2500base-x";
- phy-handle = <&phy6>;
-};
-
-&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@4 {
- reg = <4>;
- label = "wan";
- };
-
- port@5 {
- reg = <5>;
- label = "lan6";
-
- phy-mode = "2500base-x";
- phy-handle = <&phy5>;
- };
-
- port@6 {
- reg = <6>;
- ethernet = <&gmac0>;
- phy-mode = "2500base-x";
-
- fixed-link {
- speed = <2500>;
- full-duplex;
- pause;
- };
- };
- };
-};
-
-&ssusb {
- vusb33-supply = <®_3p3v>;
- vbus-supply = <®_5v>;
- status = "okay";
-};
-
-&uart0 {
- status = "okay";
-};
-
-&uart1 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart1_pins>;
- status = "okay";
-};
-
-&uart2 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart2_pins>;
- status = "okay";
-};
-
-&usb_phy {
- status = "okay";
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2021 MediaTek Inc.
- * Author: Frank Wunderlich <frank-w@public-files.de>
- */
-
-/dts-v1/;
-/plugin/;
-
-/ {
- compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
-
- fragment@0 {
- target-path = "/soc/mmc@11230000";
- __overlay__ {
- pinctrl-names = "default", "state_uhs";
- pinctrl-0 = <&mmc0_pins_emmc_51>;
- pinctrl-1 = <&mmc0_pins_emmc_51>;
- bus-width = <8>;
- max-frequency = <200000000>;
- cap-mmc-highspeed;
- mmc-hs200-1_8v;
- mmc-hs400-1_8v;
- hs400-ds-delay = <0x12814>;
- vqmmc-supply = <®_1p8v>;
- vmmc-supply = <®_3p3v>;
- non-removable;
- no-sd;
- no-sdio;
- status = "okay";
- #address-cells = <1>;
- #size-cells = <0>;
-
- card@0 {
- compatible = "mmc-card";
- reg = <0>;
-
- block {
- compatible = "block-device";
- partitions {
- block-partition-env {
- partname = "ubootenv";
- nvmem-layout {
- compatible = "u-boot,env-layout";
- };
- };
- emmc_rootfs: block-partition-production {
- partname = "production";
- };
- };
- };
- };
- };
- };
-
- fragment@2 {
- target-path = "/chosen";
- __overlay__ {
- rootdisk-emmc = <&emmc_rootfs>;
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2023
- * Author: Daniel Golle <daniel@makrotopia.org>
- */
-
-/dts-v1/;
-/plugin/;
-
-/ {
- compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&pcf8563>;
- __overlay__ {
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2023 MediaTek Inc.
- * Author: Frank Wunderlich <frank-w@public-files.de>
- */
-
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
-
- fragment@1 {
- target-path = "/soc/mmc@11230000";
- __overlay__ {
- pinctrl-names = "default", "state_uhs";
- pinctrl-0 = <&mmc0_pins_sdcard>;
- pinctrl-1 = <&mmc0_pins_sdcard>;
- cd-gpios = <&pio 12 GPIO_ACTIVE_LOW>;
- bus-width = <4>;
- max-frequency = <52000000>;
- cap-sd-highspeed;
- vmmc-supply = <®_3p3v>;
- vqmmc-supply = <®_3p3v>;
- no-mmc;
- status = "okay";
- #address-cells = <1>;
- #size-cells = <0>;
-
- card@0 {
- compatible = "mmc-card";
- reg = <0>;
-
- block {
- compatible = "block-device";
- partitions {
- block-partition-env {
- partname = "ubootenv";
- nvmem-layout {
- compatible = "u-boot,env-layout";
- };
- };
- sd_rootfs: block-partition-production {
- partname = "production";
- };
- };
- };
- };
- };
- };
-
- fragment@2 {
- target-path = "/chosen";
- __overlay__ {
- rootdisk-sd = <&sd_rootfs>;
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
-
- fragment@0 {
- target-path = "/";
- __overlay__ {
- wifi_12v: regulator-wifi-12v {
- compatible = "regulator-fixed";
- regulator-name = "wifi";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- gpio = <&pio 4 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- regulator-always-on;
- };
- };
- };
-
- fragment@1 {
- target = <&i2c_wifi>;
- __overlay__ {
- // 5G WIFI MAC Address EEPROM
- wifi_eeprom@51 {
- compatible = "atmel,24c02";
- reg = <0x51>;
- address-bits = <8>;
- page-size = <8>;
- size = <256>;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_5g: macaddr@0 {
- reg = <0x0 0x6>;
- };
- };
- };
-
- // 6G WIFI MAC Address EEPROM
- wifi_eeprom@52 {
- compatible = "atmel,24c02";
- reg = <0x52>;
- address-bits = <8>;
- page-size = <8>;
- size = <256>;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_6g: macaddr@0 {
- reg = <0x0 0x6>;
- };
- };
- };
- };
- };
-
- fragment@2 {
- target = <&pcie0>;
- __overlay__ {
- pcie@0,0 {
- reg = <0x0000 0 0 0 0>;
-
- wifi@0,0 {
- compatible = "mediatek,mt76";
- reg = <0x0000 0 0 0 0>;
- nvmem-cell-names = "mac-address";
- nvmem-cells = <&macaddr_5g>;
- };
- };
- };
- };
-
- fragment@3 {
- target = <&pcie1>;
- __overlay__ {
- pcie@0,0 {
- reg = <0x0000 0 0 0 0>;
-
- wifi@0,0 {
- compatible = "mediatek,mt76";
- reg = <0x0000 0 0 0 0>;
- nvmem-cell-names = "mac-address";
- nvmem-cells = <&macaddr_6g>;
- };
- };
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-#include "mt7988a.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
-
-/ {
- model = "Bananapi BPI-R4";
- compatible = "bananapi,bpi-r4",
- "mediatek,mt7988a";
-
- aliases {
- ethernet0 = &gmac0;
- ethernet1 = &gmac1;
- serial0 = &uart0;
- led-boot = &led_green;
- led-failsafe = &led_green;
- led-running = &led_green;
- led-upgrade = &led_green;
- };
-
- chosen {
- stdout-path = &uart0;
- bootargs = "console=ttyS0,115200n1 loglevel=8 pci=pcie_bus_perf ubi.block=0,fit root=/dev/fit0 rootwait";
- rootdisk-spim-nand = <&ubi_rootfs>;
- };
-
- memory {
- reg = <0x00 0x40000000 0x00 0x10000000>;
- };
-
- /* SFP1 cage (WAN) */
- sfp1: sfp1 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp1>;
- los-gpios = <&pio 54 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>;
- tx-disable-gpios = <&pio 70 GPIO_ACTIVE_HIGH>;
- tx-fault-gpios = <&pio 69 GPIO_ACTIVE_HIGH>;
- rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>;
- maximum-power-milliwatt = <3000>;
- };
-
- /* SFP2 cage (LAN) */
- sfp2: sfp2 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp2>;
- los-gpios = <&pio 2 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&pio 83 GPIO_ACTIVE_LOW>;
- tx-disable-gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
- tx-fault-gpios = <&pio 1 GPIO_ACTIVE_HIGH>;
- rate-select0-gpios = <&pio 3 GPIO_ACTIVE_LOW>;
- maximum-power-milliwatt = <3000>;
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- wps {
- label = "WPS";
- linux,code = <KEY_RESTART>;
- gpios = <&pio 14 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
-
- led_green: led-green {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&pio 79 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
-
- led_blue: led-blue {
- function = LED_FUNCTION_WPS;
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&pio 63 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
- };
-};
-
-ð {
- status = "okay";
-};
-
-&gmac0 {
- status = "okay";
-};
-
-&gmac1 {
- sfp = <&sfp2>;
- managed = "in-band-status";
- phy-mode = "usxgmii";
- status = "okay";
-};
-
-&gmac2 {
- sfp = <&sfp1>;
- managed = "in-band-status";
- phy-mode = "usxgmii";
- status = "okay";
-};
-
-&switch {
- status = "okay";
-};
-
-&gsw_phy0 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe0_led0_pins>;
-};
-
-&gsw_port0 {
- label = "wan";
-};
-
-&gsw_phy0_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&gsw_phy1 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe1_led0_pins>;
-};
-
-&gsw_phy1_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&gsw_phy2 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe2_led0_pins>;
-};
-
-&gsw_phy2_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&gsw_phy3 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe3_led0_pins>;
-};
-
-&gsw_phy3_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&cpu0 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cpu1 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cpu2 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cpu3 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cci {
- proc-supply = <&rt5190_buck3>;
-};
-
-&i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins>;
- status = "okay";
-
- rt5190a_64: rt5190a@64 {
- compatible = "richtek,rt5190a";
- reg = <0x64>;
- vin2-supply = <&rt5190_buck1>;
- vin3-supply = <&rt5190_buck1>;
- vin4-supply = <&rt5190_buck1>;
-
- regulators {
- rt5190_buck1: buck1 {
- regulator-name = "rt5190a-buck1";
- regulator-min-microvolt = <5090000>;
- regulator-max-microvolt = <5090000>;
- regulator-allowed-modes =
- <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
- regulator-boot-on;
- regulator-always-on;
- };
- buck2 {
- regulator-name = "vcore";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1400000>;
- regulator-boot-on;
- regulator-always-on;
- };
- rt5190_buck3: buck3 {
- regulator-name = "vproc";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1400000>;
- regulator-boot-on;
- };
- buck4 {
- regulator-name = "rt5190a-buck4";
- regulator-min-microvolt = <850000>;
- regulator-max-microvolt = <850000>;
- regulator-allowed-modes =
- <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
- regulator-boot-on;
- regulator-always-on;
- };
- ldo {
- regulator-name = "rt5190a-ldo";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- regulator-boot-on;
- regulator-always-on;
- };
- };
- };
-};
-
-&i2c2 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c2_1_pins>;
- status = "okay";
-
- pca9545: i2c-switch@70 {
- reg = <0x70>;
- compatible = "nxp,pca9545";
- reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- i2c_rtc: i2c@0 { //eeprom,rtc,ngff
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
-
- eeprom@50 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- address-bits = <8>;
- page-size = <8>;
- size = <256>;
- };
-
- eeprom@57 {
- compatible = "atmel,24c02";
- reg = <0x57>;
- address-bits = <8>;
- page-size = <8>;
- size = <256>;
- };
-
- pcf8563: rtc@51 {
- compatible = "nxp,pcf8563";
- reg = <0x51>;
- status = "disabled";
- };
- };
-
- i2c_sfp1: i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- };
-
- i2c_sfp2: i2c@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- };
-
- i2c_wifi: i2c@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
- };
- };
-};
-
-/* mPCIe SIM2 */
-&pcie0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie0_pins>;
- status = "okay";
-};
-
-/* mPCIe SIM3 */
-&pcie1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie1_pins>;
- status = "okay";
-};
-
-/* M.2 key-B SIM1 */
-&pcie2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie2_pins>;
- status = "okay";
-};
-
-/* M.2 key-M SSD */
-&pcie3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie3_pins>;
- status = "okay";
-};
-
-&ssusb1 {
- status = "okay";
-};
-
-&tphy {
- status = "okay";
-};
-
-&spi0 {
- pinctrl-names = "default";
- pinctrl-0 = <&spi0_flash_pins>;
- status = "okay";
-
- spi_nand: spi_nand@0 {
- compatible = "spi-nand";
- reg = <0>;
- spi-max-frequency = <52000000>;
- spi-tx-buswidth = <4>;
- spi-rx-buswidth = <4>;
- };
-};
-
-&spi_nand {
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "bl2";
- reg = <0x0 0x200000>;
- read-only;
- };
-
- partition@200000 {
- label = "ubi";
- reg = <0x200000 0x7e00000>;
- compatible = "linux,ubi";
-
- volumes {
- ubi-volume-ubootenv {
- volname = "ubootenv";
- nvmem-layout {
- compatible = "u-boot,env-redundant-bool-layout";
- };
- };
-
- ubi-volume-ubootenv2 {
- volname = "ubootenv2";
- nvmem-layout {
- compatible = "u-boot,env-redundant-bool-layout";
- };
- };
-
- ubi_rootfs: ubi-volume-fit {
- volname = "fit";
- };
- };
- };
- };
-};
-
-&uart0 {
- status = "okay";
-};
-
-&uart1 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&uart1_2_lite_pins>;
-};
-
-&uart2 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&uart2_3_pins>;
-};
-
-&watchdog {
- status = "okay";
-};
-
-&xphy {
- status = "okay";
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2021 MediaTek Inc.
- * Author: Frank Wunderlich <frank-w@public-files.de>
- */
-
-/dts-v1/;
-/plugin/;
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&mmc0>;
- __overlay__ {
- pinctrl-names = "default", "state_uhs";
- pinctrl-0 = <&mmc0_pins_emmc_51>;
- pinctrl-1 = <&mmc0_pins_emmc_51>;
- bus-width = <8>;
- max-frequency = <200000000>;
- cap-mmc-highspeed;
- mmc-hs200-1_8v;
- mmc-hs400-1_8v;
- hs400-ds-delay = <0x12814>;
- vqmmc-supply = <®_1p8v>;
- vmmc-supply = <®_3p3v>;
- non-removable;
- no-sd;
- no-sdio;
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&mdio_bus>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* external Aquantia AQR113C */
- phy0: ethernet-phy@0 {
- reg = <0>;
- compatible = "ethernet-phy-ieee802.3-c45";
- reset-gpios = <&pio 72 GPIO_ACTIVE_LOW>;
- reset-assert-us = <100000>;
- reset-deassert-us = <221000>;
- };
- };
- };
-
- fragment@1 {
- target = <&gmac1>;
- __overlay__ {
- phy-mode = "usxgmii";
- phy-connection-type = "usxgmii";
- phy = <&phy0>;
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&gmac1>;
- __overlay__ {
- phy-mode = "internal";
- phy-connection-type = "internal";
- phy = <&int_2p5g_phy>;
- status = "okay";
- };
- };
-
- fragment@1 {
- target = <&int_2p5g_phy>;
- __overlay__ {
- pinctrl-names = "i2p5gbe-led";
- pinctrl-0 = <&i2p5gbe_led0_pins>;
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&mdio_bus>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* external Maxlinear GPY211C */
- phy13: ethernet-phy@13 {
- reg = <13>;
- compatible = "ethernet-phy-ieee802.3-c45";
- phy-mode = "2500base-x";
- };
- };
- };
-
- fragment@1 {
- target = <&gmac1>;
- __overlay__ {
- phy-mode = "2500base-x";
- phy-connection-type = "2500base-x";
- phy = <&phy13>;
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&i2c2>;
- __overlay__ {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c2_0_pins>;
- status = "okay";
- };
- };
-
- fragment@1 {
- target-path = "/";
- __overlay__ {
- sfp_esp1: sfp@1 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c2>;
- mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>;
- los-gpios = <&pio 81 GPIO_ACTIVE_HIGH>;
- tx-disable-gpios = <&pio 36 GPIO_ACTIVE_HIGH>;
- maximum-power-milliwatt = <3000>;
- };
- };
- };
-
- fragment@2 {
- target = <&gmac1>;
- __overlay__ {
- phy-mode = "10gbase-r";
- managed = "in-band-status";
- sfp = <&sfp_esp1>;
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&mdio_bus>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* external Aquantia AQR113C */
- phy8: ethernet-phy@8 {
- reg = <8>;
- compatible = "ethernet-phy-ieee802.3-c45";
- reset-gpios = <&pio 71 GPIO_ACTIVE_LOW>;
- reset-assert-us = <100000>;
- reset-deassert-us = <221000>;
- };
- };
- };
-
- fragment@1 {
- target = <&gmac2>;
- __overlay__ {
- phy-mode = "usxgmii";
- phy-connection-type = "usxgmii";
- phy = <&phy8>;
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&mdio_bus>;
- __overlay__ {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* external Maxlinear GPY211C */
- phy5: ethernet-phy@5 {
- reg = <5>;
- compatible = "ethernet-phy-ieee802.3-c45";
- phy-mode = "2500base-x";
- };
- };
- };
-
- fragment@1 {
- target = <&gmac2>;
- __overlay__ {
- phy-mode = "2500base-x";
- phy-connection-type = "2500base-x";
- phy = <&phy5>;
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&i2c1>;
- __overlay__ {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c1_sfp_pins>;
- status = "okay";
- };
- };
-
- fragment@1 {
- target-path = "/";
- __overlay__ {
- sfp_esp0: sfp@0 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c1>;
- mod-def0-gpios = <&pio 35 GPIO_ACTIVE_LOW>;
- los-gpios = <&pio 33 GPIO_ACTIVE_HIGH>;
- tx-disable-gpios = <&pio 29 GPIO_ACTIVE_HIGH>;
- maximum-power-milliwatt = <3000>;
- };
- };
- };
-
- fragment@2 {
- target = <&gmac2>;
- __overlay__ {
- phy-mode = "10gbase-r";
- managed = "in-band-status";
- sfp = <&sfp_esp0>;
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2023 MediaTek Inc.
- * Author: Frank Wunderlich <frank-w@public-files.de>
- */
-
-/dts-v1/;
-/plugin/;
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@1 {
- target-path = <&mmc0>;
- __overlay__ {
- pinctrl-names = "default", "state_uhs";
- pinctrl-0 = <&mmc0_pins_sdcard>;
- pinctrl-1 = <&mmc0_pins_sdcard>;
- cd-gpios = <&pio 69 GPIO_ACTIVE_LOW>;
- bus-width = <4>;
- max-frequency = <52000000>;
- cap-sd-highspeed;
- vmmc-supply = <®_3p3v>;
- vqmmc-supply = <®_3p3v>;
- no-mmc;
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&snand>;
- __overlay__ {
- status = "okay";
-
- flash@0 {
- compatible = "spi-nand";
- reg = <0>;
- spi-max-frequency = <52000000>;
- 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>;
- };
-
- partition@180000 {
- label = "Factory";
- reg = <0x180000 0x0400000>;
- };
-
- partition@580000 {
- label = "FIP";
- reg = <0x580000 0x0200000>;
- };
-
- partition@780000 {
- label = "ubi";
- reg = <0x780000 0x7080000>;
- };
- };
- };
- };
- };
-
- fragment@1 {
- target = <&bch>;
- __overlay__ {
- status = "okay";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&spi0>;
- __overlay__ {
- pinctrl-names = "default";
- pinctrl-0 = <&spi0_flash_pins>;
- status = "okay";
-
- flash@0 {
- compatible = "spi-nand";
- reg = <0>;
- spi-max-frequency = <52000000>;
- 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>;
- };
-
- partition@180000 {
- label = "Factory";
- reg = <0x180000 0x0400000>;
- };
-
- partition@580000 {
- label = "FIP";
- reg = <0x580000 0x0200000>;
- };
-
- partition@780000 {
- label = "ubi";
- reg = <0x780000 0x7080000>;
- };
- };
- };
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-/plugin/;
-
-/ {
- compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
-
- fragment@0 {
- target = <&spi2>;
- __overlay__ {
- pinctrl-names = "default";
- pinctrl-0 = <&spi2_flash_pins>;
- status = "okay";
-
- flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "jedec,spi-nor";
- spi-cal-enable;
- spi-cal-mode = "read-data";
- spi-cal-datalen = <7>;
- spi-cal-data = /bits/ 8 <
- 0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
- spi-cal-addrlen = <1>;
- spi-cal-addr = /bits/ 32 <0x0>;
- reg = <0>;
- spi-max-frequency = <52000000>;
- spi-tx-bus-width = <4>;
- spi-rx-bus-width = <4>;
-
- partition@00000 {
- label = "BL2";
- reg = <0x00000 0x0040000>;
- };
- partition@40000 {
- label = "u-boot-env";
- reg = <0x40000 0x0010000>;
- };
- partition@50000 {
- label = "Factory";
- reg = <0x50000 0x0200000>;
- };
- partition@250000 {
- label = "FIP";
- reg = <0x250000 0x0080000>;
- };
- partition@2D0000 {
- label = "firmware";
- reg = <0x2D0000 0x1D30000>;
- };
- };
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2022 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-/dts-v1/;
-#include "mt7988a.dtsi"
-#include <dt-bindings/pinctrl/mt65xx.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
-
-/ {
- model = "MediaTek MT7988A Reference Board";
- compatible = "mediatek,mt7988a-rfb",
- "mediatek,mt7988a";
-
- chosen {
- bootargs = "console=ttyS0,115200n1 loglevel=8 \
- earlycon=uart8250,mmio32,0x11000000 \
- pci=pcie_bus_perf";
- };
-
- memory {
- reg = <0 0x40000000 0 0x40000000>;
- };
-};
-
-ð {
- pinctrl-0 = <&mdio0_pins>;
- pinctrl-names = "default";
-};
-
-&gmac0 {
- status = "okay";
-};
-
-&cpu0 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cpu1 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cpu2 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cpu3 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cci {
- proc-supply = <&rt5190_buck3>;
-};
-
-ð {
- status = "okay";
-};
-
-&switch {
- status = "okay";
-};
-
-&gsw_phy0 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe0_led0_pins>;
-};
-
-&gsw_phy0_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&gsw_phy1 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe1_led0_pins>;
-};
-
-&gsw_phy1_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&gsw_phy2 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe2_led0_pins>;
-};
-
-&gsw_phy2_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&gsw_phy3 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe3_led0_pins>;
-};
-
-&gsw_phy3_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins>;
- status = "okay";
-
- rt5190a_64: rt5190a@64 {
- compatible = "richtek,rt5190a";
- reg = <0x64>;
- /*interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;*/
- vin2-supply = <&rt5190_buck1>;
- vin3-supply = <&rt5190_buck1>;
- vin4-supply = <&rt5190_buck1>;
-
- regulators {
- rt5190_buck1: buck1 {
- regulator-name = "rt5190a-buck1";
- regulator-min-microvolt = <5090000>;
- regulator-max-microvolt = <5090000>;
- regulator-allowed-modes =
- <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
- regulator-boot-on;
- regulator-always-on;
- };
- buck2 {
- regulator-name = "vcore";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1400000>;
- regulator-boot-on;
- regulator-always-on;
- };
- rt5190_buck3: buck3 {
- regulator-name = "vproc";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1400000>;
- regulator-boot-on;
- };
- buck4 {
- regulator-name = "rt5190a-buck4";
- regulator-min-microvolt = <850000>;
- regulator-max-microvolt = <850000>;
- regulator-allowed-modes =
- <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
- regulator-boot-on;
- regulator-always-on;
- };
- ldo {
- regulator-name = "rt5190a-ldo";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- regulator-boot-on;
- regulator-always-on;
- };
- };
- };
-};
-
-&pcie0 {
- status = "okay";
-};
-
-&pcie1 {
- status = "okay";
-};
-
-&pcie2 {
- status = "disabled";
-};
-
-&pcie3 {
- status = "okay";
-};
-
-&ssusb0 {
- status = "okay";
-};
-
-&ssusb1 {
- status = "okay";
-};
-
-&tphy {
- status = "okay";
-};
-
-&uart0 {
- status = "okay";
-};
-
-&watchdog {
- status = "okay";
-};
-
-&xphy {
- status = "okay";
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2023 MediaTek Inc.
- * Author: Sam.Shih <sam.shih@mediatek.com>
- */
-
-#include <dt-bindings/clock/mediatek,mt7988-clk.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/phy/phy.h>
-#include <dt-bindings/pinctrl/mt65xx.h>
-#include <dt-bindings/reset/mediatek,mt7988-resets.h>
-#include <dt-bindings/thermal/thermal.h>
-
-/* TOPRGU resets */
-#define MT7988_TOPRGU_SGMII0_GRST 1
-#define MT7988_TOPRGU_SGMII1_GRST 2
-#define MT7988_TOPRGU_XFI0_GRST 12
-#define MT7988_TOPRGU_XFI1_GRST 13
-#define MT7988_TOPRGU_XFI_PEXTP0_GRST 14
-#define MT7988_TOPRGU_XFI_PEXTP1_GRST 15
-#define MT7988_TOPRGU_XFI_PLL_GRST 16
-
-/ {
- compatible = "mediatek,mt7988a";
- interrupt-parent = <&gic>;
- #address-cells = <2>;
- #size-cells = <2>;
-
- cci: cci {
- compatible = "mediatek,mt7988-cci",
- "mediatek,mt8183-cci";
- clocks = <&mcusys CLK_MCU_BUS_DIV_SEL>,
- <&topckgen CLK_TOP_XTAL>;
- clock-names = "cci", "intermediate";
- operating-points-v2 = <&cci_opp>;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu0: cpu@0 {
- compatible = "arm,cortex-a73";
- reg = <0x0>;
- device_type = "cpu";
- enable-method = "psci";
- clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
- <&topckgen CLK_TOP_XTAL>;
- clock-names = "cpu", "intermediate";
- operating-points-v2 = <&cluster0_opp>;
- mediatek,cci = <&cci>;
- };
-
- cpu1: cpu@1 {
- compatible = "arm,cortex-a73";
- reg = <0x1>;
- device_type = "cpu";
- enable-method = "psci";
- clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
- <&topckgen CLK_TOP_XTAL>;
- clock-names = "cpu", "intermediate";
- operating-points-v2 = <&cluster0_opp>;
- mediatek,cci = <&cci>;
- };
-
- cpu2: cpu@2 {
- compatible = "arm,cortex-a73";
- reg = <0x2>;
- device_type = "cpu";
- enable-method = "psci";
- clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
- <&topckgen CLK_TOP_XTAL>;
- clock-names = "cpu", "intermediate";
- operating-points-v2 = <&cluster0_opp>;
- mediatek,cci = <&cci>;
- };
-
- cpu3: cpu@3 {
- compatible = "arm,cortex-a73";
- reg = <0x3>;
- device_type = "cpu";
- enable-method = "psci";
- clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
- <&topckgen CLK_TOP_XTAL>;
- clock-names = "cpu", "intermediate";
- operating-points-v2 = <&cluster0_opp>;
- mediatek,cci = <&cci>;
- };
-
- cluster0_opp: opp_table0 {
- compatible = "operating-points-v2";
- opp-shared;
-
- opp00 {
- opp-hz = /bits/ 64 <800000000>;
- opp-microvolt = <850000>;
- };
-
- opp01 {
- opp-hz = /bits/ 64 <1100000000>;
- opp-microvolt = <850000>;
- };
-
- opp02 {
- opp-hz = /bits/ 64 <1500000000>;
- opp-microvolt = <850000>;
- };
-
- opp03 {
- opp-hz = /bits/ 64 <1800000000>;
- opp-microvolt = <900000>;
- };
- };
- };
-
- cci_opp: opp_table_cci {
- compatible = "operating-points-v2";
- opp-shared;
-
- opp00 {
- opp-hz = /bits/ 64 <480000000>;
- opp-microvolt = <850000>;
- };
-
- opp01 {
- opp-hz = /bits/ 64 <660000000>;
- opp-microvolt = <850000>;
- };
-
- opp02 {
- opp-hz = /bits/ 64 <900000000>;
- opp-microvolt = <850000>;
- };
-
- opp03 {
- opp-hz = /bits/ 64 <1080000000>;
- opp-microvolt = <900000>;
- };
- };
-
- clk40m: oscillator@0 {
- compatible = "fixed-clock";
- clock-frequency = <40000000>;
- #clock-cells = <0>;
- clock-output-names = "clkxtal";
- };
-
- fan: pwm-fan {
- compatible = "pwm-fan";
- /* cooling level (0, 1, 2) : (0% duty, 50% duty, 100% duty) */
- cooling-levels = <0 128 255>;
- #cooling-cells = <2>;
- #thermal-sensor-cells = <1>;
- status = "disabled";
- };
-
- pmu {
- compatible = "arm,cortex-a73-pmu";
- interrupt-parent = <&gic>;
- interrupt = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
- };
-
- psci {
- compatible = "arm,psci-0.2";
- method = "smc";
- };
-
- reg_1p8v: regulator-1p8v {
- compatible = "regulator-fixed";
- regulator-name = "fixed-1.8V";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- 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;
- };
-
- reserved-memory {
- ranges;
- #address-cells = <2>;
- #size-cells = <2>;
-
- /* 320 KiB reserved for ARM Trusted Firmware (BL31 and BL32) */
- secmon_reserved: secmon@43000000 {
- reg = <0 0x43000000 0 0x50000>;
- no-map;
- };
- };
-
- soc {
- compatible = "simple-bus";
- ranges;
- #address-cells = <2>;
- #size-cells = <2>;
-
- gic: interrupt-controller@c000000 {
- compatible = "arm,gic-v3";
- reg = <0 0x0c000000 0 0x40000>, /* GICD */
- <0 0x0c080000 0 0x200000>, /* GICR */
- <0 0x0c400000 0 0x2000>, /* GICC */
- <0 0x0c410000 0 0x1000>, /* GICH */
- <0 0x0c420000 0 0x2000>; /* GICV */
- interrupt-parent = <&gic>;
- interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-controller;
- #interrupt-cells = <3>;
- };
-
- phyfw: phy-firmware@f000000 {
- compatible = "mediatek,2p5gphy-fw";
- reg = <0 0x0f100000 0 0x20000>,
- <0 0x0f0f0018 0 0x20>;
- };
-
- infracfg: infracfg@10001000 {
- compatible = "mediatek,mt7988-infracfg", "syscon";
- reg = <0 0x10001000 0 0x1000>;
- #clock-cells = <1>;
- #reset-cells = <1>;
- };
-
- topckgen: topckgen@1001b000 {
- compatible = "mediatek,mt7988-topckgen", "syscon";
- reg = <0 0x1001b000 0 0x1000>;
- #clock-cells = <1>;
- };
-
- watchdog: watchdog@1001c000 {
- compatible = "mediatek,mt7988-wdt",
- "mediatek,mt6589-wdt",
- "syscon";
- reg = <0 0x1001c000 0 0x1000>;
- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
- #reset-cells = <1>;
- };
-
- apmixedsys: apmixedsys@1001e000 {
- compatible = "mediatek,mt7988-apmixedsys";
- reg = <0 0x1001e000 0 0x1000>;
- #clock-cells = <1>;
- };
-
- pio: pinctrl@1001f000 {
- compatible = "mediatek,mt7988-pinctrl", "syscon";
- reg = <0 0x1001f000 0 0x1000>,
- <0 0x11c10000 0 0x1000>,
- <0 0x11d00000 0 0x1000>,
- <0 0x11d20000 0 0x1000>,
- <0 0x11e00000 0 0x1000>,
- <0 0x11f00000 0 0x1000>,
- <0 0x1000b000 0 0x1000>;
- reg-names = "gpio_base", "iocfg_tr_base",
- "iocfg_br_base", "iocfg_rb_base",
- "iocfg_lb_base", "iocfg_tl_base", "eint";
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&pio 0 0 84>;
- interrupt-controller;
- interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-parent = <&gic>;
- #interrupt-cells = <2>;
-
- mdio0_pins: mdio0-pins {
- mux {
- function = "eth";
- groups = "mdc_mdio0";
- };
-
- conf {
- groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
- };
- };
-
- i2c0_pins: i2c0-pins-g0 {
- mux {
- function = "i2c";
- groups = "i2c0_1";
- };
- };
-
- i2c1_pins: i2c1-pins-g0 {
- mux {
- function = "i2c";
- groups = "i2c1_0";
- };
- };
-
- i2c1_sfp_pins: i2c1-sfp-pins-g0 {
- mux {
- function = "i2c";
- groups = "i2c1_sfp";
- };
- };
-
- i2c2_pins: i2c2-pins {
- mux {
- function = "i2c";
- groups = "i2c2";
- };
- };
-
- i2c2_0_pins: i2c2-pins-g0 {
- mux {
- function = "i2c";
- groups = "i2c2_0";
- };
- };
-
- i2c2_1_pins: i2c2-pins-g1 {
- mux {
- function = "i2c";
- groups = "i2c2_1";
- };
- };
-
- gbe0_led0_pins: gbe0-led0-pins {
- mux {
- function = "led";
- groups = "gbe0_led0";
- };
- };
-
- gbe1_led0_pins: gbe1-led0-pins {
- mux {
- function = "led";
- groups = "gbe1_led0";
- };
- };
-
- gbe2_led0_pins: gbe2-led0-pins {
- mux {
- function = "led";
- groups = "gbe2_led0";
- };
- };
-
- gbe3_led0_pins: gbe3-led0-pins {
- mux {
- function = "led";
- groups = "gbe3_led0";
- };
- };
-
- gbe0_led1_pins: gbe0-led1-pins {
- mux {
- function = "led";
- groups = "gbe0_led1";
- };
- };
-
- gbe1_led1_pins: gbe1-led1-pins {
- mux {
- function = "led";
- groups = "gbe1_led1";
- };
- };
-
- gbe2_led1_pins: gbe2-led1-pins {
- mux {
- function = "led";
- groups = "gbe2_led1";
- };
- };
-
- gbe3_led1_pins: gbe3-led1-pins {
- mux {
- function = "led";
- groups = "gbe3_led1";
- };
- };
-
- i2p5gbe_led0_pins: 2p5gbe-led0-pins {
- mux {
- function = "led";
- groups = "2p5gbe_led0";
- };
- };
-
- i2p5gbe_led1_pins: 2p5gbe-led1-pins {
- mux {
- function = "led";
- groups = "2p5gbe_led1";
- };
- };
-
- mmc0_pins_emmc_45: mmc0-pins-emmc-45 {
- mux {
- function = "flash";
- groups = "emmc_45";
- };
- };
-
- mmc0_pins_emmc_51: mmc0-pins-emmc-51 {
- mux {
- function = "flash";
- groups = "emmc_51";
- };
- };
-
- mmc0_pins_sdcard: mmc0-pins-sdcard {
- mux {
- function = "flash";
- groups = "sdcard";
- };
- };
-
- uart0_pins: uart0-pins {
- mux {
- function = "uart";
- groups = "uart0";
- };
- };
-
- uart1_0_pins: uart1-0-pins {
- mux {
- function = "uart";
- groups = "uart1_0";
- };
- };
-
- uart1_1_pins: uart1-1-pins {
- mux {
- function = "uart";
- groups = "uart1_1";
- };
- };
-
- uart1_2_pins: uart1-2-pins {
- mux {
- function = "uart";
- groups = "uart1_2";
- };
- };
-
- uart1_2_lite_pins: uart1-2-lite-pins {
- mux {
- function = "uart";
- groups = "uart1_2_lite";
- };
- };
-
- uart2_pins: uart2-pins {
- mux {
- function = "uart";
- groups = "uart2";
- };
- };
-
- uart2_0_pins: uart2-0-pins {
- mux {
- function = "uart";
- groups = "uart2_0";
- };
- };
-
- uart2_1_pins: uart2-1-pins {
- mux {
- function = "uart";
- groups = "uart2_1";
- };
- };
-
- uart2_2_pins: uart2-2-pins {
- mux {
- function = "uart";
- groups = "uart2_2";
- };
- };
-
- uart2_3_pins: uart2-3-pins {
- mux {
- function = "uart";
- groups = "uart2_3";
- };
- };
-
- snfi_pins: snfi-pins {
- mux {
- function = "flash";
- groups = "snfi";
- };
- };
-
- spi0_pins: spi0-pins {
- mux {
- function = "spi";
- groups = "spi0";
- };
- };
-
- spi0_flash_pins: spi0-flash-pins {
- mux {
- function = "spi";
- groups = "spi0", "spi0_wp_hold";
- };
- };
-
- spi1_pins: spi1-pins {
- mux {
- function = "spi";
- groups = "spi1";
- };
- };
-
- spi2_pins: spi2-pins {
- mux {
- function = "spi";
- groups = "spi2";
- };
- };
-
- spi2_flash_pins: spi2-flash-pins {
- mux {
- function = "spi";
- groups = "spi2", "spi2_wp_hold";
- };
- };
-
- pcie0_pins: pcie0-pins {
- mux {
- function = "pcie";
- groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
- "pcie_wake_n0_0";
- };
- };
-
- pcie1_pins: pcie1-pins {
- mux {
- function = "pcie";
- groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
- "pcie_wake_n1_0";
- };
- };
-
- pcie2_pins: pcie2-pins {
- mux {
- function = "pcie";
- groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
- "pcie_wake_n2_0";
- };
- };
-
- pcie3_pins: pcie3-pins {
- mux {
- function = "pcie";
- groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
- "pcie_wake_n3_0";
- };
- };
- };
-
- pwm: pwm@10048000 {
- compatible = "mediatek,mt7988-pwm";
- reg = <0 0x10048000 0 0x1000>;
- #pwm-cells = <2>;
- clocks = <&infracfg CLK_INFRA_66M_PWM_BCK>,
- <&infracfg CLK_INFRA_66M_PWM_HCK>,
- <&infracfg CLK_INFRA_66M_PWM_CK1>,
- <&infracfg CLK_INFRA_66M_PWM_CK2>,
- <&infracfg CLK_INFRA_66M_PWM_CK3>,
- <&infracfg CLK_INFRA_66M_PWM_CK4>,
- <&infracfg CLK_INFRA_66M_PWM_CK5>,
- <&infracfg CLK_INFRA_66M_PWM_CK6>,
- <&infracfg CLK_INFRA_66M_PWM_CK7>,
- <&infracfg CLK_INFRA_66M_PWM_CK8>;
- clock-names = "top", "main", "pwm1", "pwm2", "pwm3",
- "pwm4","pwm5","pwm6","pwm7","pwm8";
- status = "disabled";
- };
-
- sgmiisys0: syscon@10060000 {
- compatible = "mediatek,mt7988-sgmiisys",
- "mediatek,mt7988-sgmiisys0",
- "syscon",
- "simple-mfd";
- reg = <0 0x10060000 0 0x1000>;
- resets = <&watchdog MT7988_TOPRGU_SGMII0_GRST>;
- #clock-cells = <1>;
-
- sgmiipcs0: pcs {
- compatible = "mediatek,mt7988-sgmii";
- clocks = <&topckgen CLK_TOP_SGM_0_SEL>,
- <&sgmiisys0 CLK_SGM0_TX_EN>,
- <&sgmiisys0 CLK_SGM0_RX_EN>;
- clock-names = "sgmii_sel", "sgmii_tx", "sgmii_rx";
- };
- };
-
- sgmiisys1: syscon@10070000 {
- compatible = "mediatek,mt7988-sgmiisys",
- "mediatek,mt7988-sgmiisys1",
- "syscon",
- "simple-mfd";
- reg = <0 0x10070000 0 0x1000>;
- resets = <&watchdog MT7988_TOPRGU_SGMII1_GRST>;
- #clock-cells = <1>;
-
- sgmiipcs1: pcs {
- compatible = "mediatek,mt7988-sgmii";
- clocks = <&topckgen CLK_TOP_SGM_1_SEL>,
- <&sgmiisys1 CLK_SGM1_TX_EN>,
- <&sgmiisys1 CLK_SGM1_RX_EN>;
- clock-names = "sgmii_sel", "sgmii_tx", "sgmii_rx";
- };
- };
-
- usxgmiisys0: pcs@10080000 {
- compatible = "mediatek,mt7988-usxgmiisys";
- reg = <0 0x10080000 0 0x1000>;
- resets = <&watchdog MT7988_TOPRGU_XFI0_GRST>;
- clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>;
- };
-
- usxgmiisys1: pcs@10081000 {
- compatible = "mediatek,mt7988-usxgmiisys";
- reg = <0 0x10081000 0 0x1000>;
- resets = <&watchdog MT7988_TOPRGU_XFI1_GRST>;
- clocks = <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>;
- };
-
- mcusys: mcusys@100e0000 {
- compatible = "mediatek,mt7988-mcusys", "syscon";
- reg = <0 0x100e0000 0 0x1000>;
- #clock-cells = <1>;
- };
-
- uart0: serial@11000000 {
- compatible = "mediatek,mt7986-uart",
- "mediatek,mt6577-uart";
- reg = <0 0x11000000 0 0x100>;
- interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
- /*
- * 8250-mtk driver don't control "baud" clock since commit
- * e32a83c70cf9 (kernel v5.7), but both "baud" and "bus" clocks
- * still need to be passed to the driver to prevent probe fail
- */
- clocks = <&topckgen CLK_TOP_UART_SEL>,
- <&infracfg CLK_INFRA_52M_UART0_CK>;
- clock-names = "baud", "bus";
- assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
- <&infracfg CLK_INFRA_MUX_UART0_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
- <&topckgen CLK_TOP_UART_SEL>;
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins>;
- status = "disabled";
- };
-
- uart1: serial@11000100 {
- compatible = "mediatek,mt7986-uart",
- "mediatek,mt6577-uart";
- reg = <0 0x11000100 0 0x100>;
- interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
- /*
- * 8250-mtk driver don't control "baud" clock since commit
- * e32a83c70cf9 (kernel v5.7), but both "baud" and "bus" clocks
- * still need to be passed to the driver to prevent probe fail
- */
- clocks = <&topckgen CLK_TOP_UART_SEL>,
- <&infracfg CLK_INFRA_52M_UART1_CK>;
- clock-names = "baud", "bus";
- assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
- <&infracfg CLK_INFRA_MUX_UART1_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
- <&topckgen CLK_TOP_UART_SEL>;
- status = "disabled";
- };
-
- uart2: serial@11000200 {
- compatible = "mediatek,mt7986-uart",
- "mediatek,mt6577-uart";
- reg = <0 0x11000200 0 0x100>;
- interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
- /*
- * 8250-mtk driver don't control "baud" clock since commit
- * e32a83c70cf9 (kernel v5.7), but both "baud" and "bus" clocks
- * still need to be passed to the driver to prevent probe fail
- */
- clocks = <&topckgen CLK_TOP_UART_SEL>,
- <&infracfg CLK_INFRA_52M_UART2_CK>;
- clock-names = "baud", "bus";
- assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
- <&infracfg CLK_INFRA_MUX_UART2_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
- <&topckgen CLK_TOP_UART_SEL>;
- status = "disabled";
- };
-
- snand: spi@11001000 {
- compatible = "mediatek,mt7986-snand";
- reg = <0 0x11001000 0 0x1000>;
- interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_SPINFI>,
- <&infracfg CLK_INFRA_NFI>;
- clock-names = "pad_clk", "nfi_clk";
- assigned-clocks = <&topckgen CLK_TOP_SPINFI_SEL>,
- <&topckgen CLK_TOP_NFI1X_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_MPLL_D8>,
- <&topckgen CLK_TOP_MPLL_D8>;
- nand-ecc-engine = <&bch>;
- mediatek,quad-spi;
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&snfi_pins>;
- status = "disabled";
- };
-
- bch: ecc@11002000 {
- compatible = "mediatek,mt7686-ecc";
- reg = <0 0x11002000 0 0x1000>;
- interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&topckgen CLK_TOP_NFI1X_SEL>;
- clock-names = "nfiecc_clk";
- status = "disabled";
- };
-
- i2c0: i2c@11003000 {
- compatible = "mediatek,mt7988-i2c",
- "mediatek,mt7981-i2c";
- reg = <0 0x11003000 0 0x1000>,
- <0 0x10217080 0 0x80>;
- interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
- clock-div = <1>;
- clocks = <&infracfg CLK_INFRA_I2C_BCK>,
- <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
- clock-names = "main", "dma";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c1: i2c@11004000 {
- compatible = "mediatek,mt7988-i2c",
- "mediatek,mt7981-i2c";
- reg = <0 0x11004000 0 0x1000>,
- <0 0x10217100 0 0x80>;
- interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
- clock-div = <1>;
- clocks = <&infracfg CLK_INFRA_I2C_BCK>,
- <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
- clock-names = "main", "dma";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c2: i2c@11005000 {
- compatible = "mediatek,mt7988-i2c",
- "mediatek,mt7981-i2c";
- reg = <0 0x11005000 0 0x1000>,
- <0 0x10217180 0 0x80>;
- interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
- clock-div = <1>;
- clocks = <&infracfg CLK_INFRA_I2C_BCK>,
- <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
- clock-names = "main", "dma";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi0: spi@11007000 {
- compatible = "mediatek,ipm-spi-quad", "mediatek,spi-ipm";
- reg = <0 0x11007000 0 0x100>;
- interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&topckgen CLK_TOP_MPLL_D2>,
- <&topckgen CLK_TOP_SPI_SEL>,
- <&infracfg CLK_INFRA_104M_SPI0>,
- <&infracfg CLK_INFRA_66M_SPI0_HCK>;
- clock-names = "parent-clk", "sel-clk", "spi-clk",
- "spi-hclk";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- spi1: spi@11008000 {
- compatible = "mediatek,ipm-spi-single", "mediatek,spi-ipm";
- reg = <0 0x11008000 0 0x100>;
- interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&topckgen CLK_TOP_MPLL_D2>,
- <&topckgen CLK_TOP_SPI_SEL>,
- <&infracfg CLK_INFRA_104M_SPI1>,
- <&infracfg CLK_INFRA_66M_SPI1_HCK>;
- clock-names = "parent-clk", "sel-clk", "spi-clk",
- "spi-hclk";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins>;
- status = "disabled";
- };
-
- spi2: spi@11009000 {
- compatible = "mediatek,ipm-spi-quad", "mediatek,spi-ipm";
- reg = <0 0x11009000 0 0x100>;
- interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&topckgen CLK_TOP_MPLL_D2>,
- <&topckgen CLK_TOP_SPI_SEL>,
- <&infracfg CLK_INFRA_104M_SPI2_BCK>,
- <&infracfg CLK_INFRA_66M_SPI2_HCK>;
- clock-names = "parent-clk", "sel-clk", "spi-clk",
- "spi-hclk";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- lvts: lvts@1100a000 {
- compatible = "mediatek,mt7988-lvts-ap";
- reg = <0 0x1100a000 0 0x1000>;
- clocks = <&infracfg CLK_INFRA_26M_THERM_SYSTEM>;
- clock-names = "lvts_clk";
- interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&infracfg MT7988_INFRA_RST1_THERM_CTRL_SWRST>;
- nvmem-cells = <&lvts_calibration>;
- nvmem-cell-names = "lvts-calib-data-1";
- #thermal-sensor-cells = <1>;
- };
-
- ssusb0: usb@11190000 {
- compatible = "mediatek,mt7988-xhci",
- "mediatek,mtk-xhci";
- reg = <0 0x11190000 0 0x2e00>,
- <0 0x11193e00 0 0x0100>;
- reg-names = "mac", "ippc";
- interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
- phys = <&xphyu2port0 PHY_TYPE_USB2>,
- <&xphyu3port0 PHY_TYPE_USB3>;
- clocks = <&infracfg CLK_INFRA_USB_SYS>,
- <&infracfg CLK_INFRA_USB_XHCI>,
- <&infracfg CLK_INFRA_USB_REF>,
- <&infracfg CLK_INFRA_66M_USB_HCK>,
- <&infracfg CLK_INFRA_133M_USB_HCK>;
- clock-names = "sys_ck",
- "xhci_ck",
- "ref_ck",
- "mcu_ck",
- "dma_ck";
- #address-cells = <2>;
- #size-cells = <2>;
- mediatek,p0_speed_fixup;
- status = "disabled";
- };
-
- ssusb1: usb@11200000 {
- compatible = "mediatek,mt7988-xhci",
- "mediatek,mtk-xhci";
- reg = <0 0x11200000 0 0x2e00>,
- <0 0x11203e00 0 0x0100>;
- reg-names = "mac", "ippc";
- interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
- phys = <&tphyu2port0 PHY_TYPE_USB2>,
- <&tphyu3port0 PHY_TYPE_USB3>;
- clocks = <&infracfg CLK_INFRA_USB_SYS_CK_P1>,
- <&infracfg CLK_INFRA_USB_XHCI_CK_P1>,
- <&infracfg CLK_INFRA_USB_CK_P1>,
- <&infracfg CLK_INFRA_66M_USB_HCK_CK_P1>,
- <&infracfg CLK_INFRA_133M_USB_HCK_CK_P1>;
- clock-names = "sys_ck",
- "xhci_ck",
- "ref_ck",
- "mcu_ck",
- "dma_ck";
- #address-cells = <2>;
- #size-cells = <2>;
- status = "disabled";
- };
-
- afe: audio-controller@11210000 {
- compatible = "mediatek,mt79xx-audio";
- reg = <0 0x11210000 0 0x9000>;
- interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_66M_AUD_SLV_BCK>,
- <&infracfg CLK_INFRA_AUD_26M>,
- <&infracfg CLK_INFRA_AUD_L>,
- <&infracfg CLK_INFRA_AUD_AUD>,
- <&infracfg CLK_INFRA_AUD_EG2>,
- <&topckgen CLK_TOP_AUD_SEL>,
- <&topckgen CLK_TOP_AUD_I2S_M>;
- clock-names = "aud_bus_ck",
- "aud_26m_ck",
- "aud_l_ck",
- "aud_aud_ck",
- "aud_eg2_ck",
- "aud_sel",
- "aud_i2s_m";
- assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>,
- <&topckgen CLK_TOP_A1SYS_SEL>,
- <&topckgen CLK_TOP_AUD_L_SEL>,
- <&topckgen CLK_TOP_A_TUNER_SEL>;
- assigned-clock-parents = <&apmixedsys CLK_APMIXED_APLL2>,
- <&topckgen CLK_TOP_APLL2_D4>,
- <&apmixedsys CLK_APMIXED_APLL2>,
- <&topckgen CLK_TOP_APLL2_D4>;
- status = "disabled";
- };
-
- mmc0: mmc@11230000 {
- compatible = "mediatek,mt7986-mmc",
- "mediatek,mt7981-mmc";
- reg = <0 0x11230000 0 0x1000>,
- <0 0x11D60000 0 0x1000>;
- interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_MSDC400>,
- <&infracfg CLK_INFRA_MSDC2_HCK>,
- <&infracfg CLK_INFRA_66M_MSDC_0_HCK>,
- <&infracfg CLK_INFRA_133M_MSDC_0_HCK>;
- assigned-clocks = <&topckgen CLK_TOP_EMMC_250M_SEL>,
- <&topckgen CLK_TOP_EMMC_400M_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_NET1PLL_D5_D2>,
- <&apmixedsys CLK_APMIXED_MSDCPLL>;
- clock-names = "source",
- "hclk",
- "axi_cg",
- "ahb_cg";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- pcie2: pcie@11280000 {
- compatible = "mediatek,mt7988-pcie",
- "mediatek,mt7986-pcie",
- "mediatek,mt8192-pcie";
- reg = <0 0x11280000 0 0x2000>;
- reg-names = "pcie-mac";
- ranges = <0x81000000 0x00 0x20000000 0x00
- 0x20000000 0x00 0x00200000>,
- <0x82000000 0x00 0x20200000 0x00
- 0x20200000 0x00 0x07e00000>;
- device_type = "pci";
- linux,pci-domain = <3>;
- interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
- bus-range = <0x00 0xff>;
- clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P2>,
- <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P2>,
- <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P2>,
- <&infracfg CLK_INFRA_133M_PCIE_CK_P2>,
- <&topckgen CLK_TOP_PEXTP_P2_SEL>;
- clock-names = "pl_250m", "tl_26m", "peri_26m",
- "top_133m", "pextp_clk";
- pinctrl-names = "default";
- pinctrl-0 = <&pcie2_pins>;
- phys = <&xphyu3port0 PHY_TYPE_PCIE>;
- phy-names = "pcie-phy";
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0x7>;
- interrupt-map = <0 0 0 1 &pcie_intc2 0>,
- <0 0 0 2 &pcie_intc2 1>,
- <0 0 0 3 &pcie_intc2 2>,
- <0 0 0 4 &pcie_intc2 3>;
- #address-cells = <3>;
- #size-cells = <2>;
- status = "disabled";
-
- pcie_intc2: interrupt-controller {
- #address-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-controller;
- };
- };
-
- pcie3: pcie@11290000 {
- compatible = "mediatek,mt7988-pcie",
- "mediatek,mt7986-pcie",
- "mediatek,mt8192-pcie";
- reg = <0 0x11290000 0 0x2000>;
- reg-names = "pcie-mac";
- ranges = <0x81000000 0x00 0x28000000 0x00
- 0x28000000 0x00 0x00200000>,
- <0x82000000 0x00 0x28200000 0x00
- 0x28200000 0x00 0x07e00000>;
- device_type = "pci";
- linux,pci-domain = <2>;
- interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
- bus-range = <0x00 0xff>;
- clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P3>,
- <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P3>,
- <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P3>,
- <&infracfg CLK_INFRA_133M_PCIE_CK_P3>,
- <&topckgen CLK_TOP_PEXTP_P3_SEL>;
- clock-names = "pl_250m", "tl_26m", "peri_26m",
- "top_133m", "pextp_clk";
- pinctrl-names = "default";
- pinctrl-0 = <&pcie3_pins>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0x7>;
- interrupt-map = <0 0 0 1 &pcie_intc3 0>,
- <0 0 0 2 &pcie_intc3 1>,
- <0 0 0 3 &pcie_intc3 2>,
- <0 0 0 4 &pcie_intc3 3>;
- #address-cells = <3>;
- #size-cells = <2>;
- status = "disabled";
-
- pcie_intc3: interrupt-controller {
- #address-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-controller;
- };
- };
-
- pcie0: pcie@11300000 {
- compatible = "mediatek,mt7988-pcie",
- "mediatek,mt7986-pcie",
- "mediatek,mt8192-pcie";
- reg = <0 0x11300000 0 0x2000>;
- reg-names = "pcie-mac";
- ranges = <0x81000000 0x00 0x30000000 0x00
- 0x30000000 0x00 0x00200000>,
- <0x82000000 0x00 0x30200000 0x00
- 0x30200000 0x00 0x07e00000>;
- device_type = "pci";
- linux,pci-domain = <0>;
- interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
- bus-range = <0x00 0xff>;
- clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P0>,
- <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P0>,
- <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P0>,
- <&infracfg CLK_INFRA_133M_PCIE_CK_P0>,
- <&topckgen CLK_TOP_PEXTP_P0_SEL>;
- clock-names = "pl_250m", "tl_26m", "peri_26m",
- "top_133m", "pextp_clk";
- pinctrl-names = "default";
- pinctrl-0 = <&pcie0_pins>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0x7>;
- interrupt-map = <0 0 0 1 &pcie_intc0 0>,
- <0 0 0 2 &pcie_intc0 1>,
- <0 0 0 3 &pcie_intc0 2>,
- <0 0 0 4 &pcie_intc0 3>;
- #address-cells = <3>;
- #size-cells = <2>;
- status = "disabled";
-
- pcie_intc0: interrupt-controller {
- #address-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-controller;
- };
- };
-
- pcie1: pcie@11310000 {
- compatible = "mediatek,mt7988-pcie",
- "mediatek,mt7986-pcie",
- "mediatek,mt8192-pcie";
- reg = <0 0x11310000 0 0x2000>;
- reg-names = "pcie-mac";
- ranges = <0x81000000 0x00 0x38000000 0x00
- 0x38000000 0x00 0x00200000>,
- <0x82000000 0x00 0x38200000 0x00
- 0x38200000 0x00 0x07e00000>;
- device_type = "pci";
- linux,pci-domain = <1>;
- interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
- bus-range = <0x00 0xff>;
- clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P1>,
- <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P1>,
- <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P1>,
- <&infracfg CLK_INFRA_133M_PCIE_CK_P1>,
- <&topckgen CLK_TOP_PEXTP_P1_SEL>;
- clock-names = "pl_250m", "tl_26m", "peri_26m",
- "top_133m", "pextp_clk";
- pinctrl-names = "default";
- pinctrl-0 = <&pcie1_pins>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0x7>;
- interrupt-map = <0 0 0 1 &pcie_intc1 0>,
- <0 0 0 2 &pcie_intc1 1>,
- <0 0 0 3 &pcie_intc1 2>,
- <0 0 0 4 &pcie_intc1 3>;
- #address-cells = <3>;
- #size-cells = <2>;
- status = "disabled";
-
- pcie_intc1: interrupt-controller {
- #address-cells = <0>;
- #interrupt-cells = <1>;
- interrupt-controller;
- };
- };
-
- tphy: tphy@11c50000 {
- compatible = "mediatek,mt7988",
- "mediatek,generic-tphy-v2";
- ranges;
- #address-cells = <2>;
- #size-cells = <2>;
- status = "disabled";
-
- tphyu2port0: usb-phy@11c50000 {
- reg = <0 0x11c50000 0 0x700>;
- clocks = <&infracfg CLK_INFRA_USB_UTMI_CK_P1>;
- clock-names = "ref";
- #phy-cells = <1>;
- };
-
- tphyu3port0: usb-phy@11c50700 {
- reg = <0 0x11c50700 0 0x900>;
- clocks = <&infracfg CLK_INFRA_USB_PIPE_CK_P1>;
- clock-names = "ref";
- #phy-cells = <1>;
- mediatek,usb3-pll-ssc-delta;
- mediatek,usb3-pll-ssc-delta1;
- };
- };
-
- topmisc: topmisc@11d10000 {
- compatible = "mediatek,mt7988-topmisc", "syscon",
- "mediatek,mt7988-power-controller";
- reg = <0 0x11d10000 0 0x10000>;
- #clock-cells = <1>;
- #power-domain-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
-
- xphy: xphy@11e10000 {
- compatible = "mediatek,mt7988",
- "mediatek,xsphy";
- ranges;
- #address-cells = <2>;
- #size-cells = <2>;
- status = "disabled";
-
- xphyu2port0: usb-phy@11e10000 {
- reg = <0 0x11e10000 0 0x400>;
- clocks = <&infracfg CLK_INFRA_USB_UTMI>;
- clock-names = "ref";
- #phy-cells = <1>;
- };
-
- xphyu3port0: usb-phy@11e13000 {
- reg = <0 0x11e13400 0 0x500>;
- clocks = <&infracfg CLK_INFRA_USB_PIPE>;
- clock-names = "ref";
- #phy-cells = <1>;
- mediatek,syscon-type = <&topmisc 0x218 0>;
- };
- };
-
- xfi_tphy0: phy@11f20000 {
- compatible = "mediatek,mt7988-xfi-tphy";
- reg = <0 0x11f20000 0 0x10000>;
- resets = <&watchdog MT7988_TOPRGU_XFI_PEXTP0_GRST>;
- clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>, <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
- clock-names = "xfipll", "topxtal";
- mediatek,usxgmii-performance-errata;
- #phy-cells = <0>;
- };
-
- xfi_tphy1: phy@11f30000 {
- compatible = "mediatek,mt7988-xfi-tphy";
- reg = <0 0x11f30000 0 0x10000>;
- resets = <&watchdog MT7988_TOPRGU_XFI_PEXTP1_GRST>;
- clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>, <&topckgen CLK_TOP_XFI_PHY_1_XTAL_SEL>;
- clock-names = "xfipll", "topxtal";
- #phy-cells = <0>;
- };
-
- xfi_pll: clock-controller@11f40000 {
- compatible = "mediatek,mt7988-xfi-pll";
- reg = <0 0x11f40000 0 0x1000>;
- resets = <&watchdog MT7988_TOPRGU_XFI_PLL_GRST>;
- #clock-cells = <1>;
- };
-
- efuse: efuse@11f50000 {
- compatible = "mediatek,efuse";
- reg = <0 0x11f50000 0 0x1000>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- lvts_calibration: calib@918 {
- reg = <0x918 0x28>;
- };
-
- phy_calibration_p0: calib@940 {
- reg = <0x940 0x10>;
- };
-
- phy_calibration_p1: calib@954 {
- reg = <0x954 0x10>;
- };
-
- phy_calibration_p2: calib@968 {
- reg = <0x968 0x10>;
- };
-
- phy_calibration_p3: calib@97c {
- reg = <0x97c 0x10>;
- };
-
- cpufreq_calibration: calib@278 {
- reg = <0x278 0x1>;
- };
- };
-
- ethsys: syscon@15000000 {
- compatible = "mediatek,mt7988-ethsys", "syscon";
- reg = <0 0x15000000 0 0x1000>;
- #clock-cells = <1>;
- #reset-cells = <1>;
- #address-cells = <1>;
- #size-cells = <1>;
- };
-
- switch: switch@15020000 {
- compatible = "mediatek,mt7988-switch";
- reg = <0 0x15020000 0 0x8000>;
- interrupt-controller;
- #interrupt-cells = <1>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
- resets = <ðwarp MT7988_ETHWARP_RST_SWITCH>;
- #address-cells = <1>;
- #size-cells = <1>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- gsw_port0: port@0 {
- reg = <0>;
- label = "lan0";
- phy-mode = "internal";
- phy-handle = <&gsw_phy0>;
- };
-
- gsw_port1: port@1 {
- reg = <1>;
- label = "lan1";
- phy-mode = "internal";
- phy-handle = <&gsw_phy1>;
- };
-
- gsw_port2: port@2 {
- reg = <2>;
- label = "lan2";
- phy-mode = "internal";
- phy-handle = <&gsw_phy2>;
- };
-
- gsw_port3: port@3 {
- reg = <3>;
- label = "lan3";
- phy-mode = "internal";
- phy-handle = <&gsw_phy3>;
- };
-
- port@6 {
- reg = <6>;
- ethernet = <&gmac0>;
- phy-mode = "internal";
-
- fixed-link {
- speed = <10000>;
- full-duplex;
- pause;
- };
- };
- };
-
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
- mediatek,pio = <&pio>;
-
- gsw_phy0: ethernet-phy@0 {
- compatible = "ethernet-phy-ieee802.3-c22";
- reg = <0>;
- phy-mode = "internal";
- nvmem-cells = <&phy_calibration_p0>;
- nvmem-cell-names = "phy-cal-data";
-
- leds {
- #address-cells = <1>;
- #size-cells = <0>;
-
- gsw_phy0_led0: gsw-phy0-led0@0 {
- reg = <0>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
-
- gsw_phy0_led1: gsw-phy0-led1@1 {
- reg = <1>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
- };
- };
-
- gsw_phy1: ethernet-phy@1 {
- compatible = "ethernet-phy-ieee802.3-c22";
- reg = <1>;
- phy-mode = "internal";
- nvmem-cells = <&phy_calibration_p1>;
- nvmem-cell-names = "phy-cal-data";
-
- leds {
- #address-cells = <1>;
- #size-cells = <0>;
-
- gsw_phy1_led0: gsw-phy1-led0@0 {
- reg = <0>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
-
- gsw_phy1_led1: gsw-phy1-led1@1 {
- reg = <1>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
- };
- };
-
- gsw_phy2: ethernet-phy@2 {
- compatible = "ethernet-phy-ieee802.3-c22";
- reg = <2>;
- phy-mode = "internal";
- nvmem-cells = <&phy_calibration_p2>;
- nvmem-cell-names = "phy-cal-data";
-
- leds {
- #address-cells = <1>;
- #size-cells = <0>;
-
- gsw_phy2_led0: gsw-phy2-led0@0 {
- reg = <0>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
-
- gsw_phy2_led1: gsw-phy2-led1@1 {
- reg = <1>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
- };
- };
-
- gsw_phy3: ethernet-phy@3 {
- compatible = "ethernet-phy-ieee802.3-c22";
- reg = <3>;
- phy-mode = "internal";
- nvmem-cells = <&phy_calibration_p3>;
- nvmem-cell-names = "phy-cal-data";
-
- leds {
- #address-cells = <1>;
- #size-cells = <0>;
-
- gsw_phy3_led0: gsw-phy3-led0@0 {
- reg = <0>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
-
- gsw_phy3_led1: gsw-phy3-led1@1 {
- reg = <1>;
- function = LED_FUNCTION_LAN;
- status = "disabled";
- };
- };
- };
- };
- };
-
- ethwarp: clock-controller@15031000 {
- compatible = "mediatek,mt7988-ethwarp";
- reg = <0 0x15031000 0 0x1000>;
- #clock-cells = <1>;
- #reset-cells = <1>;
- };
-
- eth: ethernet@15100000 {
- compatible = "mediatek,mt7988-eth";
- reg = <0 0x15100000 0 0x80000>,
- <0 0x15400000 0 0x380000>;
- interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <ðsys CLK_ETHDMA_XGP1_EN>,
- <ðsys CLK_ETHDMA_XGP2_EN>,
- <ðsys CLK_ETHDMA_XGP3_EN>,
- <ðsys CLK_ETHDMA_FE_EN>,
- <ðsys CLK_ETHDMA_GP2_EN>,
- <ðsys CLK_ETHDMA_GP1_EN>,
- <ðsys CLK_ETHDMA_GP3_EN>,
- <ðsys CLK_ETHDMA_ESW_EN>,
- <ðsys CLK_ETHDMA_CRYPT0_EN>,
- <ðwarp CLK_ETHWARP_WOCPU2_EN>,
- <ðwarp CLK_ETHWARP_WOCPU1_EN>,
- <ðwarp CLK_ETHWARP_WOCPU0_EN>,
- <&topckgen CLK_TOP_ETH_GMII_SEL>,
- <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
- <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
- <&topckgen CLK_TOP_ETH_SYS_SEL>,
- <&topckgen CLK_TOP_ETH_XGMII_SEL>,
- <&topckgen CLK_TOP_ETH_MII_SEL>,
- <&topckgen CLK_TOP_NETSYS_SEL>,
- <&topckgen CLK_TOP_NETSYS_500M_SEL>,
- <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
- <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
- <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
- <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
- clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
- "gp3", "esw", "crypto",
- "ethwarp_wocpu2", "ethwarp_wocpu1",
- "ethwarp_wocpu0", "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";
- assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
- <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
- <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
- <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
- <&topckgen CLK_TOP_SGM_0_SEL>,
- <&topckgen CLK_TOP_SGM_1_SEL>;
- assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
- <&topckgen CLK_TOP_NET1PLL_D4>,
- <&topckgen CLK_TOP_NET1PLL_D8_D4>,
- <&topckgen CLK_TOP_NET1PLL_D8_D4>,
- <&apmixedsys CLK_APMIXED_SGMPLL>,
- <&apmixedsys CLK_APMIXED_SGMPLL>;
- mediatek,ethsys = <ðsys>;
- mediatek,infracfg = <&topmisc>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- gmac0: mac@0 {
- compatible = "mediatek,eth-mac";
- reg = <0>;
- phy-mode = "internal";
- status = "disabled";
-
- fixed-link {
- speed = <10000>;
- full-duplex;
- pause;
- };
- };
-
- gmac1: mac@1 {
- compatible = "mediatek,eth-mac";
- reg = <1>;
- status = "disabled";
- pcs-handle = <&sgmiipcs1>, <&usxgmiisys1>;
- phys = <&xfi_tphy1>;
- };
-
- gmac2: mac@2 {
- compatible = "mediatek,eth-mac";
- reg = <2>;
- status = "disabled";
- pcs-handle = <&sgmiipcs0>, <&usxgmiisys0>;
- phys = <&xfi_tphy0>;
- };
-
- mdio_bus: mdio-bus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* internal 2.5G PHY */
- int_2p5g_phy: ethernet-phy@15 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <15>;
- phy-mode = "internal";
- };
- };
- };
-
- crypto: crypto@15600000 {
- compatible = "inside-secure,safexcel-eip197b";
- reg = <0 0x15600000 0 0x180000>;
- interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "ring0", "ring1", "ring2", "ring3";
- status = "okay";
- };
- };
-
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <1000>;
- polling-delay = <1000>;
- thermal-sensors = <&lvts 0>;
-
- trips {
- cpu_trip_crit: crit {
- temperature = <125000>;
- hysteresis = <2000>;
- type = "critical";
- };
-
- cpu_trip_hot: hot {
- temperature = <120000>;
- hysteresis = <2000>;
- type = "hot";
- };
-
- cpu_trip_active_high: active-high {
- temperature = <115000>;
- hysteresis = <2000>;
- type = "active";
- };
-
- cpu_trip_active_med: active-med {
- temperature = <85000>;
- hysteresis = <2000>;
- type = "active";
- };
-
- cpu_trip_active_low: active-low {
- temperature = <40000>;
- hysteresis = <2000>;
- type = "active";
- };
- };
-
- cooling-maps {
- cpu-active-high {
- /* active: set fan to cooling level 2 */
- cooling-device = <&fan 3 3>;
- trip = <&cpu_trip_active_high>;
- };
-
- cpu-active-low {
- /* active: set fan to cooling level 1 */
- cooling-device = <&fan 2 2>;
- trip = <&cpu_trip_active_med>;
- };
-
- cpu-passive {
- /* passive: set fan to cooling level 0 */
- cooling-device = <&fan 1 1>;
- trip = <&cpu_trip_active_low>;
- };
- };
- };
- };
-
- timer {
- compatible = "arm,armv8-timer";
- interrupt-parent = <&gic>;
- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
- };
-};
+++ /dev/null
-// 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 */
- 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);
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0
-/*
- * The MT7988 driver based on Linux generic pinctrl binding.
- *
- * Copyright (C) 2020 MediaTek Inc.
- * Author: Sam Shih <sam.shih@mediatek.com>
- */
-
-#include "pinctrl-moore.h"
-
-enum MT7988_PINCTRL_REG_PAGE {
- GPIO_BASE,
- IOCFG_TR_BASE,
- IOCFG_BR_BASE,
- IOCFG_RB_BASE,
- IOCFG_LB_BASE,
- IOCFG_TL_BASE,
-};
-
-#define MT7988_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
-
-#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
- _x_bits) \
- PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
- _x_bits, 32, 0)
-
-#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
- _x_bits) \
- PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
- _x_bits, 32, 1)
-
-static const struct mtk_pin_field_calc mt7988_pin_mode_range[] = {
- PIN_FIELD(0, 83, 0x300, 0x10, 0, 4),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_dir_range[] = {
- PIN_FIELD(0, 83, 0x0, 0x10, 0, 1),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_di_range[] = {
- PIN_FIELD(0, 83, 0x200, 0x10, 0, 1),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_do_range[] = {
- PIN_FIELD(0, 83, 0x100, 0x10, 0, 1),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_ies_range[] = {
- PIN_FIELD_BASE(0, 0, 5, 0x30, 0x10, 13, 1),
- PIN_FIELD_BASE(1, 1, 5, 0x30, 0x10, 14, 1),
- PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 11, 1),
- PIN_FIELD_BASE(3, 3, 5, 0x30, 0x10, 12, 1),
- PIN_FIELD_BASE(4, 4, 5, 0x30, 0x10, 0, 1),
- PIN_FIELD_BASE(5, 5, 5, 0x30, 0x10, 9, 1),
- PIN_FIELD_BASE(6, 6, 5, 0x30, 0x10, 10, 1),
-
- PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 8, 1),
- PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 6, 1),
- PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 5, 1),
- PIN_FIELD_BASE(10, 10, 4, 0x30, 0x10, 3, 1),
-
- PIN_FIELD_BASE(11, 11, 1, 0x40, 0x10, 0, 1),
- PIN_FIELD_BASE(12, 12, 1, 0x40, 0x10, 21, 1),
- PIN_FIELD_BASE(13, 13, 1, 0x40, 0x10, 1, 1),
- PIN_FIELD_BASE(14, 14, 1, 0x40, 0x10, 2, 1),
-
- PIN_FIELD_BASE(15, 15, 5, 0x30, 0x10, 7, 1),
- PIN_FIELD_BASE(16, 16, 5, 0x30, 0x10, 8, 1),
- PIN_FIELD_BASE(17, 17, 5, 0x30, 0x10, 3, 1),
- PIN_FIELD_BASE(18, 18, 5, 0x30, 0x10, 4, 1),
-
- PIN_FIELD_BASE(19, 19, 4, 0x30, 0x10, 7, 1),
- PIN_FIELD_BASE(20, 20, 4, 0x30, 0x10, 4, 1),
-
- PIN_FIELD_BASE(21, 21, 3, 0x50, 0x10, 17, 1),
- PIN_FIELD_BASE(22, 22, 3, 0x50, 0x10, 23, 1),
- PIN_FIELD_BASE(23, 23, 3, 0x50, 0x10, 20, 1),
- PIN_FIELD_BASE(24, 24, 3, 0x50, 0x10, 19, 1),
- PIN_FIELD_BASE(25, 25, 3, 0x50, 0x10, 21, 1),
- PIN_FIELD_BASE(26, 26, 3, 0x50, 0x10, 22, 1),
- PIN_FIELD_BASE(27, 27, 3, 0x50, 0x10, 18, 1),
- PIN_FIELD_BASE(28, 28, 3, 0x50, 0x10, 25, 1),
- PIN_FIELD_BASE(29, 29, 3, 0x50, 0x10, 26, 1),
- PIN_FIELD_BASE(30, 30, 3, 0x50, 0x10, 27, 1),
- PIN_FIELD_BASE(31, 31, 3, 0x50, 0x10, 24, 1),
- PIN_FIELD_BASE(32, 32, 3, 0x50, 0x10, 28, 1),
- PIN_FIELD_BASE(33, 33, 3, 0x60, 0x10, 0, 1),
- PIN_FIELD_BASE(34, 34, 3, 0x50, 0x10, 31, 1),
- PIN_FIELD_BASE(35, 35, 3, 0x50, 0x10, 29, 1),
- PIN_FIELD_BASE(36, 36, 3, 0x50, 0x10, 30, 1),
- PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 1, 1),
- PIN_FIELD_BASE(38, 38, 3, 0x50, 0x10, 11, 1),
- PIN_FIELD_BASE(39, 39, 3, 0x50, 0x10, 10, 1),
- PIN_FIELD_BASE(40, 40, 3, 0x50, 0x10, 0, 1),
- PIN_FIELD_BASE(41, 41, 3, 0x50, 0x10, 1, 1),
- PIN_FIELD_BASE(42, 42, 3, 0x50, 0x10, 9, 1),
- PIN_FIELD_BASE(43, 43, 3, 0x50, 0x10, 8, 1),
- PIN_FIELD_BASE(44, 44, 3, 0x50, 0x10, 7, 1),
- PIN_FIELD_BASE(45, 45, 3, 0x50, 0x10, 6, 1),
- PIN_FIELD_BASE(46, 46, 3, 0x50, 0x10, 5, 1),
- PIN_FIELD_BASE(47, 47, 3, 0x50, 0x10, 4, 1),
- PIN_FIELD_BASE(48, 48, 3, 0x50, 0x10, 3, 1),
- PIN_FIELD_BASE(49, 49, 3, 0x50, 0x10, 2, 1),
- PIN_FIELD_BASE(50, 50, 3, 0x50, 0x10, 15, 1),
- PIN_FIELD_BASE(51, 51, 3, 0x50, 0x10, 12, 1),
- PIN_FIELD_BASE(52, 52, 3, 0x50, 0x10, 13, 1),
- PIN_FIELD_BASE(53, 53, 3, 0x50, 0x10, 14, 1),
- PIN_FIELD_BASE(54, 54, 3, 0x50, 0x10, 16, 1),
-
- PIN_FIELD_BASE(55, 55, 1, 0x40, 0x10, 14, 1),
- PIN_FIELD_BASE(56, 56, 1, 0x40, 0x10, 15, 1),
- PIN_FIELD_BASE(57, 57, 1, 0x40, 0x10, 13, 1),
- PIN_FIELD_BASE(58, 58, 1, 0x40, 0x10, 4, 1),
- PIN_FIELD_BASE(59, 59, 1, 0x40, 0x10, 5, 1),
- PIN_FIELD_BASE(60, 60, 1, 0x40, 0x10, 6, 1),
- PIN_FIELD_BASE(61, 61, 1, 0x40, 0x10, 3, 1),
- PIN_FIELD_BASE(62, 62, 1, 0x40, 0x10, 7, 1),
- PIN_FIELD_BASE(63, 63, 1, 0x40, 0x10, 20, 1),
- PIN_FIELD_BASE(64, 64, 1, 0x40, 0x10, 8, 1),
- PIN_FIELD_BASE(65, 65, 1, 0x40, 0x10, 9, 1),
- PIN_FIELD_BASE(66, 66, 1, 0x40, 0x10, 10, 1),
- PIN_FIELD_BASE(67, 67, 1, 0x40, 0x10, 11, 1),
- PIN_FIELD_BASE(68, 68, 1, 0x40, 0x10, 12, 1),
-
- PIN_FIELD_BASE(69, 69, 5, 0x30, 0x10, 1, 1),
- PIN_FIELD_BASE(70, 70, 5, 0x30, 0x10, 2, 1),
- PIN_FIELD_BASE(71, 71, 5, 0x30, 0x10, 5, 1),
- PIN_FIELD_BASE(72, 72, 5, 0x30, 0x10, 6, 1),
-
- PIN_FIELD_BASE(73, 73, 4, 0x30, 0x10, 10, 1),
- PIN_FIELD_BASE(74, 74, 4, 0x30, 0x10, 1, 1),
- PIN_FIELD_BASE(75, 75, 4, 0x30, 0x10, 11, 1),
- PIN_FIELD_BASE(76, 76, 4, 0x30, 0x10, 9, 1),
- PIN_FIELD_BASE(77, 77, 4, 0x30, 0x10, 2, 1),
- PIN_FIELD_BASE(78, 78, 4, 0x30, 0x10, 0, 1),
- PIN_FIELD_BASE(79, 79, 4, 0x30, 0x10, 12, 1),
-
- PIN_FIELD_BASE(80, 80, 1, 0x40, 0x10, 18, 1),
- PIN_FIELD_BASE(81, 81, 1, 0x40, 0x10, 19, 1),
- PIN_FIELD_BASE(82, 82, 1, 0x40, 0x10, 16, 1),
- PIN_FIELD_BASE(83, 83, 1, 0x40, 0x10, 17, 1),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_smt_range[] = {
- PIN_FIELD_BASE(0, 0, 5, 0xc0, 0x10, 13, 1),
- PIN_FIELD_BASE(1, 1, 5, 0xc0, 0x10, 14, 1),
- PIN_FIELD_BASE(2, 2, 5, 0xc0, 0x10, 11, 1),
- PIN_FIELD_BASE(3, 3, 5, 0xc0, 0x10, 12, 1),
- PIN_FIELD_BASE(4, 4, 5, 0xc0, 0x10, 0, 1),
- PIN_FIELD_BASE(5, 5, 5, 0xc0, 0x10, 9, 1),
- PIN_FIELD_BASE(6, 6, 5, 0xc0, 0x10, 10, 1),
-
- PIN_FIELD_BASE(7, 7, 4, 0xb0, 0x10, 8, 1),
- PIN_FIELD_BASE(8, 8, 4, 0xb0, 0x10, 6, 1),
- PIN_FIELD_BASE(9, 9, 4, 0xb0, 0x10, 5, 1),
- PIN_FIELD_BASE(10, 10, 4, 0xb0, 0x10, 3, 1),
-
- PIN_FIELD_BASE(11, 11, 1, 0xe0, 0x10, 0, 1),
- PIN_FIELD_BASE(12, 12, 1, 0xe0, 0x10, 21, 1),
- PIN_FIELD_BASE(13, 13, 1, 0xe0, 0x10, 1, 1),
- PIN_FIELD_BASE(14, 14, 1, 0xe0, 0x10, 2, 1),
-
- PIN_FIELD_BASE(15, 15, 5, 0xc0, 0x10, 7, 1),
- PIN_FIELD_BASE(16, 16, 5, 0xc0, 0x10, 8, 1),
- PIN_FIELD_BASE(17, 17, 5, 0xc0, 0x10, 3, 1),
- PIN_FIELD_BASE(18, 18, 5, 0xc0, 0x10, 4, 1),
-
- PIN_FIELD_BASE(19, 19, 4, 0xb0, 0x10, 7, 1),
- PIN_FIELD_BASE(20, 20, 4, 0xb0, 0x10, 4, 1),
-
- PIN_FIELD_BASE(21, 21, 3, 0x140, 0x10, 17, 1),
- PIN_FIELD_BASE(22, 22, 3, 0x140, 0x10, 23, 1),
- PIN_FIELD_BASE(23, 23, 3, 0x140, 0x10, 20, 1),
- PIN_FIELD_BASE(24, 24, 3, 0x140, 0x10, 19, 1),
- PIN_FIELD_BASE(25, 25, 3, 0x140, 0x10, 21, 1),
- PIN_FIELD_BASE(26, 26, 3, 0x140, 0x10, 22, 1),
- PIN_FIELD_BASE(27, 27, 3, 0x140, 0x10, 18, 1),
- PIN_FIELD_BASE(28, 28, 3, 0x140, 0x10, 25, 1),
- PIN_FIELD_BASE(29, 29, 3, 0x140, 0x10, 26, 1),
- PIN_FIELD_BASE(30, 30, 3, 0x140, 0x10, 27, 1),
- PIN_FIELD_BASE(31, 31, 3, 0x140, 0x10, 24, 1),
- PIN_FIELD_BASE(32, 32, 3, 0x140, 0x10, 28, 1),
- PIN_FIELD_BASE(33, 33, 3, 0x150, 0x10, 0, 1),
- PIN_FIELD_BASE(34, 34, 3, 0x140, 0x10, 31, 1),
- PIN_FIELD_BASE(35, 35, 3, 0x140, 0x10, 29, 1),
- PIN_FIELD_BASE(36, 36, 3, 0x140, 0x10, 30, 1),
- PIN_FIELD_BASE(37, 37, 3, 0x150, 0x10, 1, 1),
- PIN_FIELD_BASE(38, 38, 3, 0x140, 0x10, 11, 1),
- PIN_FIELD_BASE(39, 39, 3, 0x140, 0x10, 10, 1),
- PIN_FIELD_BASE(40, 40, 3, 0x140, 0x10, 0, 1),
- PIN_FIELD_BASE(41, 41, 3, 0x140, 0x10, 1, 1),
- PIN_FIELD_BASE(42, 42, 3, 0x140, 0x10, 9, 1),
- PIN_FIELD_BASE(43, 43, 3, 0x140, 0x10, 8, 1),
- PIN_FIELD_BASE(44, 44, 3, 0x140, 0x10, 7, 1),
- PIN_FIELD_BASE(45, 45, 3, 0x140, 0x10, 6, 1),
- PIN_FIELD_BASE(46, 46, 3, 0x140, 0x10, 5, 1),
- PIN_FIELD_BASE(47, 47, 3, 0x140, 0x10, 4, 1),
- PIN_FIELD_BASE(48, 48, 3, 0x140, 0x10, 3, 1),
- PIN_FIELD_BASE(49, 49, 3, 0x140, 0x10, 2, 1),
- PIN_FIELD_BASE(50, 50, 3, 0x140, 0x10, 15, 1),
- PIN_FIELD_BASE(51, 51, 3, 0x140, 0x10, 12, 1),
- PIN_FIELD_BASE(52, 52, 3, 0x140, 0x10, 13, 1),
- PIN_FIELD_BASE(53, 53, 3, 0x140, 0x10, 14, 1),
- PIN_FIELD_BASE(54, 54, 3, 0x140, 0x10, 16, 1),
-
- PIN_FIELD_BASE(55, 55, 1, 0xe0, 0x10, 14, 1),
- PIN_FIELD_BASE(56, 56, 1, 0xe0, 0x10, 15, 1),
- PIN_FIELD_BASE(57, 57, 1, 0xe0, 0x10, 13, 1),
- PIN_FIELD_BASE(58, 58, 1, 0xe0, 0x10, 4, 1),
- PIN_FIELD_BASE(59, 59, 1, 0xe0, 0x10, 5, 1),
- PIN_FIELD_BASE(60, 60, 1, 0xe0, 0x10, 6, 1),
- PIN_FIELD_BASE(61, 61, 1, 0xe0, 0x10, 3, 1),
- PIN_FIELD_BASE(62, 62, 1, 0xe0, 0x10, 7, 1),
- PIN_FIELD_BASE(63, 63, 1, 0xe0, 0x10, 20, 1),
- PIN_FIELD_BASE(64, 64, 1, 0xe0, 0x10, 8, 1),
- PIN_FIELD_BASE(65, 65, 1, 0xe0, 0x10, 9, 1),
- PIN_FIELD_BASE(66, 66, 1, 0xe0, 0x10, 10, 1),
- PIN_FIELD_BASE(67, 67, 1, 0xe0, 0x10, 11, 1),
- PIN_FIELD_BASE(68, 68, 1, 0xe0, 0x10, 12, 1),
-
- PIN_FIELD_BASE(69, 69, 5, 0xc0, 0x10, 1, 1),
- PIN_FIELD_BASE(70, 70, 5, 0xc0, 0x10, 2, 1),
- PIN_FIELD_BASE(71, 71, 5, 0xc0, 0x10, 5, 1),
- PIN_FIELD_BASE(72, 72, 5, 0xc0, 0x10, 6, 1),
-
- PIN_FIELD_BASE(73, 73, 4, 0xb0, 0x10, 10, 1),
- PIN_FIELD_BASE(74, 74, 4, 0xb0, 0x10, 1, 1),
- PIN_FIELD_BASE(75, 75, 4, 0xb0, 0x10, 11, 1),
- PIN_FIELD_BASE(76, 76, 4, 0xb0, 0x10, 9, 1),
- PIN_FIELD_BASE(77, 77, 4, 0xb0, 0x10, 2, 1),
- PIN_FIELD_BASE(78, 78, 4, 0xb0, 0x10, 0, 1),
- PIN_FIELD_BASE(79, 79, 4, 0xb0, 0x10, 12, 1),
-
- PIN_FIELD_BASE(80, 80, 1, 0xe0, 0x10, 18, 1),
- PIN_FIELD_BASE(81, 81, 1, 0xe0, 0x10, 19, 1),
- PIN_FIELD_BASE(82, 82, 1, 0xe0, 0x10, 16, 1),
- PIN_FIELD_BASE(83, 83, 1, 0xe0, 0x10, 17, 1),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_pu_range[] = {
- PIN_FIELD_BASE(7, 7, 4, 0x60, 0x10, 5, 1),
- PIN_FIELD_BASE(8, 8, 4, 0x60, 0x10, 4, 1),
- PIN_FIELD_BASE(9, 9, 4, 0x60, 0x10, 3, 1),
- PIN_FIELD_BASE(10, 10, 4, 0x60, 0x10, 2, 1),
-
- PIN_FIELD_BASE(13, 13, 1, 0x70, 0x10, 0, 1),
- PIN_FIELD_BASE(14, 14, 1, 0x70, 0x10, 1, 1),
- PIN_FIELD_BASE(63, 63, 1, 0x70, 0x10, 2, 1),
-
- PIN_FIELD_BASE(75, 75, 4, 0x60, 0x10, 7, 1),
- PIN_FIELD_BASE(76, 76, 4, 0x60, 0x10, 6, 1),
- PIN_FIELD_BASE(77, 77, 4, 0x60, 0x10, 1, 1),
- PIN_FIELD_BASE(78, 78, 4, 0x60, 0x10, 0, 1),
- PIN_FIELD_BASE(79, 79, 4, 0x60, 0x10, 8, 1),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_pd_range[] = {
- PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 5, 1),
- PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
- PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 3, 1),
- PIN_FIELD_BASE(10, 10, 4, 0x40, 0x10, 2, 1),
-
- PIN_FIELD_BASE(13, 13, 1, 0x50, 0x10, 0, 1),
- PIN_FIELD_BASE(14, 14, 1, 0x50, 0x10, 1, 1),
-
- PIN_FIELD_BASE(15, 15, 5, 0x40, 0x10, 4, 1),
- PIN_FIELD_BASE(16, 16, 5, 0x40, 0x10, 5, 1),
- PIN_FIELD_BASE(17, 17, 5, 0x40, 0x10, 0, 1),
- PIN_FIELD_BASE(18, 18, 5, 0x40, 0x10, 1, 1),
-
- PIN_FIELD_BASE(63, 63, 1, 0x50, 0x10, 2, 1),
- PIN_FIELD_BASE(71, 71, 5, 0x40, 0x10, 2, 1),
- PIN_FIELD_BASE(72, 72, 5, 0x40, 0x10, 3, 1),
-
- PIN_FIELD_BASE(75, 75, 4, 0x40, 0x10, 7, 1),
- PIN_FIELD_BASE(76, 76, 4, 0x40, 0x10, 6, 1),
- PIN_FIELD_BASE(77, 77, 4, 0x40, 0x10, 1, 1),
- PIN_FIELD_BASE(78, 78, 4, 0x40, 0x10, 0, 1),
- PIN_FIELD_BASE(79, 79, 4, 0x40, 0x10, 8, 1),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_drv_range[] = {
- PIN_FIELD_BASE(0, 0, 5, 0x00, 0x10, 21, 3),
- PIN_FIELD_BASE(1, 1, 5, 0x00, 0x10, 24, 3),
- PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 15, 3),
- PIN_FIELD_BASE(3, 3, 5, 0x00, 0x10, 18, 3),
- PIN_FIELD_BASE(4, 4, 5, 0x00, 0x10, 0, 3),
- PIN_FIELD_BASE(5, 5, 5, 0x00, 0x10, 9, 3),
- PIN_FIELD_BASE(6, 6, 5, 0x00, 0x10, 12, 3),
-
- PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 24, 3),
- PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 28, 3),
- PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 15, 3),
- PIN_FIELD_BASE(10, 10, 4, 0x00, 0x10, 9, 3),
-
- PIN_FIELD_BASE(11, 11, 1, 0x00, 0x10, 0, 3),
- PIN_FIELD_BASE(12, 12, 1, 0x20, 0x10, 3, 3),
- PIN_FIELD_BASE(13, 13, 1, 0x00, 0x10, 3, 3),
- PIN_FIELD_BASE(14, 14, 1, 0x00, 0x10, 6, 3),
-
- PIN_FIELD_BASE(19, 19, 4, 0x00, 0x10, 21, 3),
- PIN_FIELD_BASE(20, 20, 4, 0x00, 0x10, 12, 3),
-
- PIN_FIELD_BASE(21, 21, 3, 0x10, 0x10, 21, 3),
- PIN_FIELD_BASE(22, 22, 3, 0x20, 0x10, 9, 3),
- PIN_FIELD_BASE(23, 23, 3, 0x20, 0x10, 0, 3),
- PIN_FIELD_BASE(24, 24, 3, 0x10, 0x10, 27, 3),
- PIN_FIELD_BASE(25, 25, 3, 0x20, 0x10, 3, 3),
- PIN_FIELD_BASE(26, 26, 3, 0x20, 0x10, 6, 3),
- PIN_FIELD_BASE(27, 27, 3, 0x10, 0x10, 24, 3),
- PIN_FIELD_BASE(28, 28, 3, 0x20, 0x10, 15, 3),
- PIN_FIELD_BASE(29, 29, 3, 0x20, 0x10, 18, 3),
- PIN_FIELD_BASE(30, 30, 3, 0x20, 0x10, 21, 3),
- PIN_FIELD_BASE(31, 31, 3, 0x20, 0x10, 12, 3),
- PIN_FIELD_BASE(32, 32, 3, 0x20, 0x10, 24, 3),
- PIN_FIELD_BASE(33, 33, 3, 0x30, 0x10, 6, 3),
- PIN_FIELD_BASE(34, 34, 3, 0x30, 0x10, 3, 3),
- PIN_FIELD_BASE(35, 35, 3, 0x20, 0x10, 27, 3),
- PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 0, 3),
- PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 9, 3),
- PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 3, 3),
- PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 0, 3),
- PIN_FIELD_BASE(40, 40, 3, 0x00, 0x10, 0, 3),
- PIN_FIELD_BASE(41, 41, 3, 0x00, 0x10, 3, 3),
- PIN_FIELD_BASE(42, 42, 3, 0x00, 0x10, 27, 3),
- PIN_FIELD_BASE(43, 43, 3, 0x00, 0x10, 24, 3),
- PIN_FIELD_BASE(44, 44, 3, 0x00, 0x10, 21, 3),
- PIN_FIELD_BASE(45, 45, 3, 0x00, 0x10, 18, 3),
- PIN_FIELD_BASE(46, 46, 3, 0x00, 0x10, 15, 3),
- PIN_FIELD_BASE(47, 47, 3, 0x00, 0x10, 12, 3),
- PIN_FIELD_BASE(48, 48, 3, 0x00, 0x10, 9, 3),
- PIN_FIELD_BASE(49, 49, 3, 0x00, 0x10, 6, 3),
- PIN_FIELD_BASE(50, 50, 3, 0x10, 0x10, 15, 3),
- PIN_FIELD_BASE(51, 51, 3, 0x10, 0x10, 6, 3),
- PIN_FIELD_BASE(52, 52, 3, 0x10, 0x10, 9, 3),
- PIN_FIELD_BASE(53, 53, 3, 0x10, 0x10, 12, 3),
- PIN_FIELD_BASE(54, 54, 3, 0x10, 0x10, 18, 3),
-
- PIN_FIELD_BASE(55, 55, 1, 0x10, 0x10, 12, 3),
- PIN_FIELD_BASE(56, 56, 1, 0x10, 0x10, 15, 3),
- PIN_FIELD_BASE(57, 57, 1, 0x10, 0x10, 9, 3),
- PIN_FIELD_BASE(58, 58, 1, 0x00, 0x10, 12, 3),
- PIN_FIELD_BASE(59, 59, 1, 0x00, 0x10, 15, 3),
- PIN_FIELD_BASE(60, 60, 1, 0x00, 0x10, 18, 3),
- PIN_FIELD_BASE(61, 61, 1, 0x00, 0x10, 9, 3),
- PIN_FIELD_BASE(62, 62, 1, 0x00, 0x10, 21, 3),
- PIN_FIELD_BASE(63, 63, 1, 0x20, 0x10, 0, 3),
- PIN_FIELD_BASE(64, 64, 1, 0x00, 0x10, 24, 3),
- PIN_FIELD_BASE(65, 65, 1, 0x00, 0x10, 27, 3),
- PIN_FIELD_BASE(66, 66, 1, 0x10, 0x10, 0, 3),
- PIN_FIELD_BASE(67, 67, 1, 0x10, 0x10, 3, 3),
- PIN_FIELD_BASE(68, 68, 1, 0x10, 0x10, 6, 3),
-
- PIN_FIELD_BASE(69, 69, 5, 0x00, 0x10, 3, 3),
- PIN_FIELD_BASE(70, 70, 5, 0x00, 0x10, 6, 3),
-
- PIN_FIELD_BASE(73, 73, 4, 0x10, 0x10, 0, 3),
- PIN_FIELD_BASE(74, 74, 4, 0x00, 0x10, 3, 3),
- PIN_FIELD_BASE(75, 75, 4, 0x10, 0x10, 3, 3),
- PIN_FIELD_BASE(76, 76, 4, 0x00, 0x10, 27, 3),
- PIN_FIELD_BASE(77, 77, 4, 0x00, 0x10, 6, 3),
- PIN_FIELD_BASE(78, 78, 4, 0x00, 0x10, 0, 3),
- PIN_FIELD_BASE(79, 79, 4, 0x10, 0x10, 6, 3),
-
- PIN_FIELD_BASE(80, 80, 1, 0x10, 0x10, 24, 3),
- PIN_FIELD_BASE(81, 81, 1, 0x10, 0x10, 27, 3),
- PIN_FIELD_BASE(82, 82, 1, 0x10, 0x10, 18, 3),
- PIN_FIELD_BASE(83, 83, 1, 0x10, 0x10, 21, 3),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_pupd_range[] = {
- PIN_FIELD_BASE(0, 0, 5, 0x50, 0x10, 7, 1),
- PIN_FIELD_BASE(1, 1, 5, 0x50, 0x10, 8, 1),
- PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 5, 1),
- PIN_FIELD_BASE(3, 3, 5, 0x50, 0x10, 6, 1),
- PIN_FIELD_BASE(4, 4, 5, 0x50, 0x10, 0, 1),
- PIN_FIELD_BASE(5, 5, 5, 0x50, 0x10, 3, 1),
- PIN_FIELD_BASE(6, 6, 5, 0x50, 0x10, 4, 1),
-
- PIN_FIELD_BASE(11, 11, 1, 0x60, 0x10, 0, 1),
- PIN_FIELD_BASE(12, 12, 1, 0x60, 0x10, 18, 1),
-
- PIN_FIELD_BASE(19, 19, 4, 0x50, 0x10, 2, 1),
- PIN_FIELD_BASE(20, 20, 4, 0x50, 0x10, 1, 1),
-
- PIN_FIELD_BASE(21, 21, 3, 0x70, 0x10, 17, 1),
- PIN_FIELD_BASE(22, 22, 3, 0x70, 0x10, 23, 1),
- PIN_FIELD_BASE(23, 23, 3, 0x70, 0x10, 20, 1),
- PIN_FIELD_BASE(24, 24, 3, 0x70, 0x10, 19, 1),
- PIN_FIELD_BASE(25, 25, 3, 0x70, 0x10, 21, 1),
- PIN_FIELD_BASE(26, 26, 3, 0x70, 0x10, 22, 1),
- PIN_FIELD_BASE(27, 27, 3, 0x70, 0x10, 18, 1),
- PIN_FIELD_BASE(28, 28, 3, 0x70, 0x10, 25, 1),
- PIN_FIELD_BASE(29, 29, 3, 0x70, 0x10, 26, 1),
- PIN_FIELD_BASE(30, 30, 3, 0x70, 0x10, 27, 1),
- PIN_FIELD_BASE(31, 31, 3, 0x70, 0x10, 24, 1),
- PIN_FIELD_BASE(32, 32, 3, 0x70, 0x10, 28, 1),
- PIN_FIELD_BASE(33, 33, 3, 0x80, 0x10, 0, 1),
- PIN_FIELD_BASE(34, 34, 3, 0x70, 0x10, 31, 1),
- PIN_FIELD_BASE(35, 35, 3, 0x70, 0x10, 29, 1),
- PIN_FIELD_BASE(36, 36, 3, 0x70, 0x10, 30, 1),
- PIN_FIELD_BASE(37, 37, 3, 0x80, 0x10, 1, 1),
- PIN_FIELD_BASE(38, 38, 3, 0x70, 0x10, 11, 1),
- PIN_FIELD_BASE(39, 39, 3, 0x70, 0x10, 10, 1),
- PIN_FIELD_BASE(40, 40, 3, 0x70, 0x10, 0, 1),
- PIN_FIELD_BASE(41, 41, 3, 0x70, 0x10, 1, 1),
- PIN_FIELD_BASE(42, 42, 3, 0x70, 0x10, 9, 1),
- PIN_FIELD_BASE(43, 43, 3, 0x70, 0x10, 8, 1),
- PIN_FIELD_BASE(44, 44, 3, 0x70, 0x10, 7, 1),
- PIN_FIELD_BASE(45, 45, 3, 0x70, 0x10, 6, 1),
- PIN_FIELD_BASE(46, 46, 3, 0x70, 0x10, 5, 1),
- PIN_FIELD_BASE(47, 47, 3, 0x70, 0x10, 4, 1),
- PIN_FIELD_BASE(48, 48, 3, 0x70, 0x10, 3, 1),
- PIN_FIELD_BASE(49, 49, 3, 0x70, 0x10, 2, 1),
- PIN_FIELD_BASE(50, 50, 3, 0x70, 0x10, 15, 1),
- PIN_FIELD_BASE(51, 51, 3, 0x70, 0x10, 12, 1),
- PIN_FIELD_BASE(52, 52, 3, 0x70, 0x10, 13, 1),
- PIN_FIELD_BASE(53, 53, 3, 0x70, 0x10, 14, 1),
- PIN_FIELD_BASE(54, 54, 3, 0x70, 0x10, 16, 1),
-
- PIN_FIELD_BASE(55, 55, 1, 0x60, 0x10, 12, 1),
- PIN_FIELD_BASE(56, 56, 1, 0x60, 0x10, 13, 1),
- PIN_FIELD_BASE(57, 57, 1, 0x60, 0x10, 11, 1),
- PIN_FIELD_BASE(58, 58, 1, 0x60, 0x10, 2, 1),
- PIN_FIELD_BASE(59, 59, 1, 0x60, 0x10, 3, 1),
- PIN_FIELD_BASE(60, 60, 1, 0x60, 0x10, 4, 1),
- PIN_FIELD_BASE(61, 61, 1, 0x60, 0x10, 1, 1),
- PIN_FIELD_BASE(62, 62, 1, 0x60, 0x10, 5, 1),
- PIN_FIELD_BASE(64, 64, 1, 0x60, 0x10, 6, 1),
- PIN_FIELD_BASE(65, 65, 1, 0x60, 0x10, 7, 1),
- PIN_FIELD_BASE(66, 66, 1, 0x60, 0x10, 8, 1),
- PIN_FIELD_BASE(67, 67, 1, 0x60, 0x10, 9, 1),
- PIN_FIELD_BASE(68, 68, 1, 0x60, 0x10, 10, 1),
-
- PIN_FIELD_BASE(69, 69, 5, 0x50, 0x10, 1, 1),
- PIN_FIELD_BASE(70, 70, 5, 0x50, 0x10, 2, 1),
-
- PIN_FIELD_BASE(73, 73, 4, 0x50, 0x10, 3, 1),
- PIN_FIELD_BASE(74, 74, 4, 0x50, 0x10, 0, 1),
-
- PIN_FIELD_BASE(80, 80, 1, 0x60, 0x10, 16, 1),
- PIN_FIELD_BASE(81, 81, 1, 0x60, 0x10, 17, 1),
- PIN_FIELD_BASE(82, 82, 1, 0x60, 0x10, 14, 1),
- PIN_FIELD_BASE(83, 83, 1, 0x60, 0x10, 15, 1),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_r0_range[] = {
- PIN_FIELD_BASE(0, 0, 5, 0x60, 0x10, 7, 1),
- PIN_FIELD_BASE(1, 1, 5, 0x60, 0x10, 8, 1),
- PIN_FIELD_BASE(2, 2, 5, 0x60, 0x10, 5, 1),
- PIN_FIELD_BASE(3, 3, 5, 0x60, 0x10, 6, 1),
- PIN_FIELD_BASE(4, 4, 5, 0x60, 0x10, 0, 1),
- PIN_FIELD_BASE(5, 5, 5, 0x60, 0x10, 3, 1),
- PIN_FIELD_BASE(6, 6, 5, 0x60, 0x10, 4, 1),
-
- PIN_FIELD_BASE(11, 11, 1, 0x80, 0x10, 0, 1),
- PIN_FIELD_BASE(12, 12, 1, 0x80, 0x10, 18, 1),
-
- PIN_FIELD_BASE(19, 19, 4, 0x70, 0x10, 2, 1),
- PIN_FIELD_BASE(20, 20, 4, 0x70, 0x10, 1, 1),
-
- PIN_FIELD_BASE(21, 21, 3, 0x90, 0x10, 17, 1),
- PIN_FIELD_BASE(22, 22, 3, 0x90, 0x10, 23, 1),
- PIN_FIELD_BASE(23, 23, 3, 0x90, 0x10, 20, 1),
- PIN_FIELD_BASE(24, 24, 3, 0x90, 0x10, 19, 1),
- PIN_FIELD_BASE(25, 25, 3, 0x90, 0x10, 21, 1),
- PIN_FIELD_BASE(26, 26, 3, 0x90, 0x10, 22, 1),
- PIN_FIELD_BASE(27, 27, 3, 0x90, 0x10, 18, 1),
- PIN_FIELD_BASE(28, 28, 3, 0x90, 0x10, 25, 1),
- PIN_FIELD_BASE(29, 29, 3, 0x90, 0x10, 26, 1),
- PIN_FIELD_BASE(30, 30, 3, 0x90, 0x10, 27, 1),
- PIN_FIELD_BASE(31, 31, 3, 0x90, 0x10, 24, 1),
- PIN_FIELD_BASE(32, 32, 3, 0x90, 0x10, 28, 1),
- PIN_FIELD_BASE(33, 33, 3, 0xa0, 0x10, 0, 1),
- PIN_FIELD_BASE(34, 34, 3, 0x90, 0x10, 31, 1),
- PIN_FIELD_BASE(35, 35, 3, 0x90, 0x10, 29, 1),
- PIN_FIELD_BASE(36, 36, 3, 0x90, 0x10, 30, 1),
- PIN_FIELD_BASE(37, 37, 3, 0xa0, 0x10, 1, 1),
- PIN_FIELD_BASE(38, 38, 3, 0x90, 0x10, 11, 1),
- PIN_FIELD_BASE(39, 39, 3, 0x90, 0x10, 10, 1),
- PIN_FIELD_BASE(40, 40, 3, 0x90, 0x10, 0, 1),
- PIN_FIELD_BASE(41, 41, 3, 0x90, 0x10, 1, 1),
- PIN_FIELD_BASE(42, 42, 3, 0x90, 0x10, 9, 1),
- PIN_FIELD_BASE(43, 43, 3, 0x90, 0x10, 8, 1),
- PIN_FIELD_BASE(44, 44, 3, 0x90, 0x10, 7, 1),
- PIN_FIELD_BASE(45, 45, 3, 0x90, 0x10, 6, 1),
- PIN_FIELD_BASE(46, 46, 3, 0x90, 0x10, 5, 1),
- PIN_FIELD_BASE(47, 47, 3, 0x90, 0x10, 4, 1),
- PIN_FIELD_BASE(48, 48, 3, 0x90, 0x10, 3, 1),
- PIN_FIELD_BASE(49, 49, 3, 0x90, 0x10, 2, 1),
- PIN_FIELD_BASE(50, 50, 3, 0x90, 0x10, 15, 1),
- PIN_FIELD_BASE(51, 51, 3, 0x90, 0x10, 12, 1),
- PIN_FIELD_BASE(52, 52, 3, 0x90, 0x10, 13, 1),
- PIN_FIELD_BASE(53, 53, 3, 0x90, 0x10, 14, 1),
- PIN_FIELD_BASE(54, 54, 3, 0x90, 0x10, 16, 1),
-
- PIN_FIELD_BASE(55, 55, 1, 0x80, 0x10, 12, 1),
- PIN_FIELD_BASE(56, 56, 1, 0x80, 0x10, 13, 1),
- PIN_FIELD_BASE(57, 57, 1, 0x80, 0x10, 11, 1),
- PIN_FIELD_BASE(58, 58, 1, 0x80, 0x10, 2, 1),
- PIN_FIELD_BASE(59, 59, 1, 0x80, 0x10, 3, 1),
- PIN_FIELD_BASE(60, 60, 1, 0x80, 0x10, 4, 1),
- PIN_FIELD_BASE(61, 61, 1, 0x80, 0x10, 1, 1),
- PIN_FIELD_BASE(62, 62, 1, 0x80, 0x10, 5, 1),
- PIN_FIELD_BASE(64, 64, 1, 0x80, 0x10, 6, 1),
- PIN_FIELD_BASE(65, 65, 1, 0x80, 0x10, 7, 1),
- PIN_FIELD_BASE(66, 66, 1, 0x80, 0x10, 8, 1),
- PIN_FIELD_BASE(67, 67, 1, 0x80, 0x10, 9, 1),
- PIN_FIELD_BASE(68, 68, 1, 0x80, 0x10, 10, 1),
-
- PIN_FIELD_BASE(69, 69, 5, 0x60, 0x10, 1, 1),
- PIN_FIELD_BASE(70, 70, 5, 0x60, 0x10, 2, 1),
-
- PIN_FIELD_BASE(73, 73, 4, 0x70, 0x10, 3, 1),
- PIN_FIELD_BASE(74, 74, 4, 0x70, 0x10, 0, 1),
-
- PIN_FIELD_BASE(80, 80, 1, 0x80, 0x10, 16, 1),
- PIN_FIELD_BASE(81, 81, 1, 0x80, 0x10, 17, 1),
- PIN_FIELD_BASE(82, 82, 1, 0x80, 0x10, 14, 1),
- PIN_FIELD_BASE(83, 83, 1, 0x80, 0x10, 15, 1),
-};
-
-static const struct mtk_pin_field_calc mt7988_pin_r1_range[] = {
- PIN_FIELD_BASE(0, 0, 5, 0x70, 0x10, 7, 1),
- PIN_FIELD_BASE(1, 1, 5, 0x70, 0x10, 8, 1),
- PIN_FIELD_BASE(2, 2, 5, 0x70, 0x10, 5, 1),
- PIN_FIELD_BASE(3, 3, 5, 0x70, 0x10, 6, 1),
- PIN_FIELD_BASE(4, 4, 5, 0x70, 0x10, 0, 1),
- PIN_FIELD_BASE(5, 5, 5, 0x70, 0x10, 3, 1),
- PIN_FIELD_BASE(6, 6, 5, 0x70, 0x10, 4, 1),
-
- PIN_FIELD_BASE(11, 11, 1, 0x90, 0x10, 0, 1),
- PIN_FIELD_BASE(12, 12, 1, 0x90, 0x10, 18, 1),
-
- PIN_FIELD_BASE(19, 19, 4, 0x80, 0x10, 2, 1),
- PIN_FIELD_BASE(20, 20, 4, 0x80, 0x10, 1, 1),
-
- PIN_FIELD_BASE(21, 21, 3, 0xb0, 0x10, 17, 1),
- PIN_FIELD_BASE(22, 22, 3, 0xb0, 0x10, 23, 1),
- PIN_FIELD_BASE(23, 23, 3, 0xb0, 0x10, 20, 1),
- PIN_FIELD_BASE(24, 24, 3, 0xb0, 0x10, 19, 1),
- PIN_FIELD_BASE(25, 25, 3, 0xb0, 0x10, 21, 1),
- PIN_FIELD_BASE(26, 26, 3, 0xb0, 0x10, 22, 1),
- PIN_FIELD_BASE(27, 27, 3, 0xb0, 0x10, 18, 1),
- PIN_FIELD_BASE(28, 28, 3, 0xb0, 0x10, 25, 1),
- PIN_FIELD_BASE(29, 29, 3, 0xb0, 0x10, 26, 1),
- PIN_FIELD_BASE(30, 30, 3, 0xb0, 0x10, 27, 1),
- PIN_FIELD_BASE(31, 31, 3, 0xb0, 0x10, 24, 1),
- PIN_FIELD_BASE(32, 32, 3, 0xb0, 0x10, 28, 1),
- PIN_FIELD_BASE(33, 33, 3, 0xc0, 0x10, 0, 1),
- PIN_FIELD_BASE(34, 34, 3, 0xb0, 0x10, 31, 1),
- PIN_FIELD_BASE(35, 35, 3, 0xb0, 0x10, 29, 1),
- PIN_FIELD_BASE(36, 36, 3, 0xb0, 0x10, 30, 1),
- PIN_FIELD_BASE(37, 37, 3, 0xc0, 0x10, 1, 1),
- PIN_FIELD_BASE(38, 38, 3, 0xb0, 0x10, 11, 1),
- PIN_FIELD_BASE(39, 39, 3, 0xb0, 0x10, 10, 1),
- PIN_FIELD_BASE(40, 40, 3, 0xb0, 0x10, 0, 1),
- PIN_FIELD_BASE(41, 41, 3, 0xb0, 0x10, 1, 1),
- PIN_FIELD_BASE(42, 42, 3, 0xb0, 0x10, 9, 1),
- PIN_FIELD_BASE(43, 43, 3, 0xb0, 0x10, 8, 1),
- PIN_FIELD_BASE(44, 44, 3, 0xb0, 0x10, 7, 1),
- PIN_FIELD_BASE(45, 45, 3, 0xb0, 0x10, 6, 1),
- PIN_FIELD_BASE(46, 46, 3, 0xb0, 0x10, 5, 1),
- PIN_FIELD_BASE(47, 47, 3, 0xb0, 0x10, 4, 1),
- PIN_FIELD_BASE(48, 48, 3, 0xb0, 0x10, 3, 1),
- PIN_FIELD_BASE(49, 49, 3, 0xb0, 0x10, 2, 1),
- PIN_FIELD_BASE(50, 50, 3, 0xb0, 0x10, 15, 1),
- PIN_FIELD_BASE(51, 51, 3, 0xb0, 0x10, 12, 1),
- PIN_FIELD_BASE(52, 52, 3, 0xb0, 0x10, 13, 1),
- PIN_FIELD_BASE(53, 53, 3, 0xb0, 0x10, 14, 1),
- PIN_FIELD_BASE(54, 54, 3, 0xb0, 0x10, 16, 1),
-
- PIN_FIELD_BASE(55, 55, 1, 0x90, 0x10, 12, 1),
- PIN_FIELD_BASE(56, 56, 1, 0x90, 0x10, 13, 1),
- PIN_FIELD_BASE(57, 57, 1, 0x90, 0x10, 11, 1),
- PIN_FIELD_BASE(58, 58, 1, 0x90, 0x10, 2, 1),
- PIN_FIELD_BASE(59, 59, 1, 0x90, 0x10, 3, 1),
- PIN_FIELD_BASE(60, 60, 1, 0x90, 0x10, 4, 1),
- PIN_FIELD_BASE(61, 61, 1, 0x90, 0x10, 1, 1),
- PIN_FIELD_BASE(62, 62, 1, 0x90, 0x10, 5, 1),
- PIN_FIELD_BASE(64, 64, 1, 0x90, 0x10, 6, 1),
- PIN_FIELD_BASE(65, 65, 1, 0x90, 0x10, 7, 1),
- PIN_FIELD_BASE(66, 66, 1, 0x90, 0x10, 8, 1),
- PIN_FIELD_BASE(67, 67, 1, 0x90, 0x10, 9, 1),
- PIN_FIELD_BASE(68, 68, 1, 0x90, 0x10, 10, 1),
-
- PIN_FIELD_BASE(69, 69, 5, 0x70, 0x10, 1, 1),
- PIN_FIELD_BASE(70, 70, 5, 0x70, 0x10, 2, 1),
-
- PIN_FIELD_BASE(73, 73, 4, 0x80, 0x10, 3, 1),
- PIN_FIELD_BASE(74, 74, 4, 0x80, 0x10, 0, 1),
-
- PIN_FIELD_BASE(80, 80, 1, 0x90, 0x10, 16, 1),
- PIN_FIELD_BASE(81, 81, 1, 0x90, 0x10, 17, 1),
- PIN_FIELD_BASE(82, 82, 1, 0x90, 0x10, 14, 1),
- PIN_FIELD_BASE(83, 83, 1, 0x90, 0x10, 15, 1),
-};
-
-static const unsigned int mt7988_pull_type[] = {
- MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
- MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
- MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
- MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PU_PD_TYPE, /*7*/
- MTK_PULL_PU_PD_TYPE, /*8*/ MTK_PULL_PU_PD_TYPE, /*9*/
- MTK_PULL_PU_PD_TYPE, /*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
- MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PU_PD_TYPE, /*13*/
- MTK_PULL_PU_PD_TYPE, /*14*/ MTK_PULL_PD_TYPE, /*15*/
- MTK_PULL_PD_TYPE, /*16*/ MTK_PULL_PD_TYPE, /*17*/
- MTK_PULL_PD_TYPE, /*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
- MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
- MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
- MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
- MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
- MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
- MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
- MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
- MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
- MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
- MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
- MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
- MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
- MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
- MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
- MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
- MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
- MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
- MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
- MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
- MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
- MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
- MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PU_PD_TYPE, /*63*/
- MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
- MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
- MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PUPD_R1R0_TYPE,/*69*/
- MTK_PULL_PUPD_R1R0_TYPE,/*70*/ MTK_PULL_PD_TYPE, /*71*/
- MTK_PULL_PD_TYPE, /*72*/ MTK_PULL_PUPD_R1R0_TYPE,/*73*/
- MTK_PULL_PUPD_R1R0_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE, /*75*/
- MTK_PULL_PU_PD_TYPE, /*76*/ MTK_PULL_PU_PD_TYPE, /*77*/
- MTK_PULL_PU_PD_TYPE, /*78*/ MTK_PULL_PU_PD_TYPE, /*79*/
- MTK_PULL_PUPD_R1R0_TYPE,/*80*/ MTK_PULL_PUPD_R1R0_TYPE,/*81*/
- MTK_PULL_PUPD_R1R0_TYPE,/*82*/ MTK_PULL_PUPD_R1R0_TYPE,/*83*/
-};
-
-static const struct mtk_pin_reg_calc mt7988_reg_cals[] = {
- [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7988_pin_mode_range),
- [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7988_pin_dir_range),
- [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7988_pin_di_range),
- [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7988_pin_do_range),
- [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7988_pin_smt_range),
- [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7988_pin_ies_range),
- [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7988_pin_pu_range),
- [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7988_pin_pd_range),
- [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7988_pin_drv_range),
- [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7988_pin_pupd_range),
- [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7988_pin_r0_range),
- [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7988_pin_r1_range),
-};
-
-static const struct mtk_pin_desc mt7988_pins[] = {
- MT7988_PIN(0, "UART2_RXD"),
- MT7988_PIN(1, "UART2_TXD"),
- MT7988_PIN(2, "UART2_CTS"),
- MT7988_PIN(3, "UART2_RTS"),
- MT7988_PIN(4, "GPIO_A"),
- MT7988_PIN(5, "SMI_0_MDC"),
- MT7988_PIN(6, "SMI_0_MDIO"),
- MT7988_PIN(7, "PCIE30_2L_0_WAKE_N"),
- MT7988_PIN(8, "PCIE30_2L_0_CLKREQ_N"),
- MT7988_PIN(9, "PCIE30_1L_1_WAKE_N"),
- MT7988_PIN(10, "PCIE30_1L_1_CLKREQ_N"),
- MT7988_PIN(11, "GPIO_P"),
- MT7988_PIN(12, "WATCHDOG"),
- MT7988_PIN(13, "GPIO_RESET"),
- MT7988_PIN(14, "GPIO_WPS"),
- MT7988_PIN(15, "PMIC_I2C_SCL"),
- MT7988_PIN(16, "PMIC_I2C_SDA"),
- MT7988_PIN(17, "I2C_1_SCL"),
- MT7988_PIN(18, "I2C_1_SDA"),
- MT7988_PIN(19, "PCIE30_2L_0_PRESET_N"),
- MT7988_PIN(20, "PCIE30_1L_1_PRESET_N"),
- MT7988_PIN(21, "PWMD1"),
- MT7988_PIN(22, "SPI0_WP"),
- MT7988_PIN(23, "SPI0_HOLD"),
- MT7988_PIN(24, "SPI0_CSB"),
- MT7988_PIN(25, "SPI0_MISO"),
- MT7988_PIN(26, "SPI0_MOSI"),
- MT7988_PIN(27, "SPI0_CLK"),
- MT7988_PIN(28, "SPI1_CSB"),
- MT7988_PIN(29, "SPI1_MISO"),
- MT7988_PIN(30, "SPI1_MOSI"),
- MT7988_PIN(31, "SPI1_CLK"),
- MT7988_PIN(32, "SPI2_CLK"),
- MT7988_PIN(33, "SPI2_MOSI"),
- MT7988_PIN(34, "SPI2_MISO"),
- MT7988_PIN(35, "SPI2_CSB"),
- MT7988_PIN(36, "SPI2_HOLD"),
- MT7988_PIN(37, "SPI2_WP"),
- MT7988_PIN(38, "EMMC_RSTB"),
- MT7988_PIN(39, "EMMC_DSL"),
- MT7988_PIN(40, "EMMC_CK"),
- MT7988_PIN(41, "EMMC_CMD"),
- MT7988_PIN(42, "EMMC_DATA_7"),
- MT7988_PIN(43, "EMMC_DATA_6"),
- MT7988_PIN(44, "EMMC_DATA_5"),
- MT7988_PIN(45, "EMMC_DATA_4"),
- MT7988_PIN(46, "EMMC_DATA_3"),
- MT7988_PIN(47, "EMMC_DATA_2"),
- MT7988_PIN(48, "EMMC_DATA_1"),
- MT7988_PIN(49, "EMMC_DATA_0"),
- MT7988_PIN(50, "PCM_FS_I2S_LRCK"),
- MT7988_PIN(51, "PCM_CLK_I2S_BCLK"),
- MT7988_PIN(52, "PCM_DRX_I2S_DIN"),
- MT7988_PIN(53, "PCM_DTX_I2S_DOUT"),
- MT7988_PIN(54, "PCM_MCK_I2S_MCLK"),
- MT7988_PIN(55, "UART0_RXD"),
- MT7988_PIN(56, "UART0_TXD"),
- MT7988_PIN(57, "PWMD0"),
- MT7988_PIN(58, "JTAG_JTDI"),
- MT7988_PIN(59, "JTAG_JTDO"),
- MT7988_PIN(60, "JTAG_JTMS"),
- MT7988_PIN(61, "JTAG_JTCLK"),
- MT7988_PIN(62, "JTAG_JTRST_N"),
- MT7988_PIN(63, "USB_DRV_VBUS_P1"),
- MT7988_PIN(64, "LED_A"),
- MT7988_PIN(65, "LED_B"),
- MT7988_PIN(66, "LED_C"),
- MT7988_PIN(67, "LED_D"),
- MT7988_PIN(68, "LED_E"),
- MT7988_PIN(69, "GPIO_B"),
- MT7988_PIN(70, "GPIO_C"),
- MT7988_PIN(71, "I2C_2_SCL"),
- MT7988_PIN(72, "I2C_2_SDA"),
- MT7988_PIN(73, "PCIE30_2L_1_PRESET_N"),
- MT7988_PIN(74, "PCIE30_1L_0_PRESET_N"),
- MT7988_PIN(75, "PCIE30_2L_1_WAKE_N"),
- MT7988_PIN(76, "PCIE30_2L_1_CLKREQ_N"),
- MT7988_PIN(77, "PCIE30_1L_0_WAKE_N"),
- MT7988_PIN(78, "PCIE30_1L_0_CLKREQ_N"),
- MT7988_PIN(79, "USB_DRV_VBUS_P0"),
- MT7988_PIN(80, "UART1_RXD"),
- MT7988_PIN(81, "UART1_TXD"),
- MT7988_PIN(82, "UART1_CTS"),
- MT7988_PIN(83, "UART1_RTS"),
-};
-
-/* jtag */
-static int mt7988_tops_jtag0_0_pins[] = { 0, 1, 2, 3, 4 };
-static int mt7988_tops_jtag0_0_funcs[] = { 2, 2, 2, 2, 2 };
-
-static int mt7988_wo0_jtag_pins[] = { 50, 51, 52, 53, 54 };
-static int mt7988_wo0_jtag_funcs[] = { 3, 3, 3, 3, 3 };
-
-static int mt7988_wo1_jtag_pins[] = { 50, 51, 52, 53, 54 };
-static int mt7988_wo1_jtag_funcs[] = { 4, 4, 4, 4, 4 };
-
-static int mt7988_wo2_jtag_pins[] = { 50, 51, 52, 53, 54 };
-static int mt7988_wo2_jtag_funcs[] = { 5, 5, 5, 5, 5 };
-
-static int mt7988_jtag_pins[] = { 58, 59, 60, 61, 62 };
-static int mt7988_jtag_funcs[] = { 1, 1, 1, 1, 1 };
-
-static int mt7988_tops_jtag0_1_pins[] = { 58, 59, 60, 61, 62 };
-static int mt7988_tops_jtag0_1_funcs[] = { 4, 4, 4, 4, 4 };
-
-/* int_usxgmii */
-static int mt7988_int_usxgmii_pins[] = { 2, 3 };
-static int mt7988_int_usxgmii_funcs[] = { 3, 3 };
-
-/* pwm */
-static int mt7988_pwm0_pins[] = { 57 };
-static int mt7988_pwm0_funcs[] = { 1 };
-
-static int mt7988_pwm1_pins[] = { 21 };
-static int mt7988_pwm1_funcs[] = { 1 };
-
-static int mt7988_pwm2_pins[] = { 80 };
-static int mt7988_pwm2_funcs[] = { 2 };
-
-static int mt7988_pwm3_pins[] = { 81 };
-static int mt7988_pwm3_funcs[] = { 2 };
-
-static int mt7988_pwm4_pins[] = { 82 };
-static int mt7988_pwm4_funcs[] = { 2 };
-
-static int mt7988_pwm5_pins[] = { 83 };
-static int mt7988_pwm5_funcs[] = { 2 };
-
-static int mt7988_pwm6_pins[] = { 69 };
-static int mt7988_pwm6_funcs[] = { 3 };
-
-static int mt7988_pwm7_pins[] = { 70 };
-static int mt7988_pwm7_funcs[] = { 3 };
-
-/* dfd */
-static int mt7988_dfd_pins[] = { 0, 1, 2, 3, 4 };
-static int mt7988_dfd_funcs[] = { 4, 4, 4, 4, 4 };
-
-/* i2c */
-static int mt7988_xfi_phy0_i2c0_pins[] = { 0, 1 };
-static int mt7988_xfi_phy0_i2c0_funcs[] = { 5, 5 };
-
-static int mt7988_xfi_phy1_i2c0_pins[] = { 0, 1 };
-static int mt7988_xfi_phy1_i2c0_funcs[] = { 6, 6 };
-
-static int mt7988_xfi_phy_pll_i2c0_pins[] = { 3, 4 };
-static int mt7988_xfi_phy_pll_i2c0_funcs[] = { 5, 5 };
-
-static int mt7988_xfi_phy_pll_i2c1_pins[] = { 3, 4 };
-static int mt7988_xfi_phy_pll_i2c1_funcs[] = { 6, 6 };
-
-static int mt7988_i2c0_0_pins[] = { 5, 6 };
-static int mt7988_i2c0_0_funcs[] = { 2, 2 };
-
-static int mt7988_i2c1_sfp_pins[] = { 5, 6 };
-static int mt7988_i2c1_sfp_funcs[] = { 4, 4 };
-
-static int mt7988_xfi_pextp_phy0_i2c_pins[] = { 5, 6 };
-static int mt7988_xfi_pextp_phy0_i2c_funcs[] = { 5, 5 };
-
-static int mt7988_xfi_pextp_phy1_i2c_pins[] = { 5, 6 };
-static int mt7988_xfi_pextp_phy1_i2c_funcs[] = { 6, 6 };
-
-static int mt7988_i2c0_1_pins[] = { 15, 16 };
-static int mt7988_i2c0_1_funcs[] = { 1, 1 };
-
-static int mt7988_u30_phy_i2c0_pins[] = { 15, 16 };
-static int mt7988_u30_phy_i2c0_funcs[] = { 2, 2 };
-
-static int mt7988_u32_phy_i2c0_pins[] = { 15, 16 };
-static int mt7988_u32_phy_i2c0_funcs[] = { 3, 3 };
-
-static int mt7988_xfi_phy0_i2c1_pins[] = { 15, 16 };
-static int mt7988_xfi_phy0_i2c1_funcs[] = { 5, 5 };
-
-static int mt7988_xfi_phy1_i2c1_pins[] = { 15, 16 };
-static int mt7988_xfi_phy1_i2c1_funcs[] = { 6, 6 };
-
-static int mt7988_xfi_phy_pll_i2c2_pins[] = { 15, 16 };
-static int mt7988_xfi_phy_pll_i2c2_funcs[] = { 7, 7 };
-
-static int mt7988_i2c1_0_pins[] = { 17, 18 };
-static int mt7988_i2c1_0_funcs[] = { 1, 1 };
-
-static int mt7988_u30_phy_i2c1_pins[] = { 17, 18 };
-static int mt7988_u30_phy_i2c1_funcs[] = { 2, 2 };
-
-static int mt7988_u32_phy_i2c1_pins[] = { 17, 18 };
-static int mt7988_u32_phy_i2c1_funcs[] = { 3, 3 };
-
-static int mt7988_xfi_phy_pll_i2c3_pins[] = { 17, 18 };
-static int mt7988_xfi_phy_pll_i2c3_funcs[] = { 4, 4 };
-
-static int mt7988_sgmii0_i2c_pins[] = { 17, 18 };
-static int mt7988_sgmii0_i2c_funcs[] = { 5, 5 };
-
-static int mt7988_sgmii1_i2c_pins[] = { 17, 18 };
-static int mt7988_sgmii1_i2c_funcs[] = { 6, 6 };
-
-static int mt7988_i2c1_2_pins[] = { 69, 70 };
-static int mt7988_i2c1_2_funcs[] = { 2, 2 };
-
-static int mt7988_i2c2_0_pins[] = { 69, 70 };
-static int mt7988_i2c2_0_funcs[] = { 4, 4 };
-
-static int mt7988_i2c2_1_pins[] = { 71, 72 };
-static int mt7988_i2c2_1_funcs[] = { 1, 1 };
-
-/* eth */
-static int mt7988_mdc_mdio0_pins[] = { 5, 6 };
-static int mt7988_mdc_mdio0_funcs[] = { 1, 1 };
-
-static int mt7988_2p5g_ext_mdio_pins[] = { 28, 29 };
-static int mt7988_2p5g_ext_mdio_funcs[] = { 6, 6 };
-
-static int mt7988_gbe_ext_mdio_pins[] = { 30, 31 };
-static int mt7988_gbe_ext_mdio_funcs[] = { 6, 6 };
-
-static int mt7988_mdc_mdio1_pins[] = { 69, 70 };
-static int mt7988_mdc_mdio1_funcs[] = { 1, 1 };
-
-/* pcie */
-static int mt7988_pcie_wake_n0_0_pins[] = { 7 };
-static int mt7988_pcie_wake_n0_0_funcs[] = { 1 };
-
-static int mt7988_pcie_clk_req_n0_0_pins[] = { 8 };
-static int mt7988_pcie_clk_req_n0_0_funcs[] = { 1 };
-
-static int mt7988_pcie_wake_n3_0_pins[] = { 9 };
-static int mt7988_pcie_wake_n3_0_funcs[] = { 1 };
-
-static int mt7988_pcie_clk_req_n3_pins[] = { 10 };
-static int mt7988_pcie_clk_req_n3_funcs[] = { 1 };
-
-static int mt7988_pcie_clk_req_n0_1_pins[] = { 10 };
-static int mt7988_pcie_clk_req_n0_1_funcs[] = { 2 };
-
-static int mt7988_pcie_p0_phy_i2c_pins[] = { 7, 8 };
-static int mt7988_pcie_p0_phy_i2c_funcs[] = { 3, 3 };
-
-static int mt7988_pcie_p1_phy_i2c_pins[] = { 7, 8 };
-static int mt7988_pcie_p1_phy_i2c_funcs[] = { 4, 4 };
-
-static int mt7988_pcie_p3_phy_i2c_pins[] = { 9, 10 };
-static int mt7988_pcie_p3_phy_i2c_funcs[] = { 4, 4 };
-
-static int mt7988_pcie_p2_phy_i2c_pins[] = { 7, 8 };
-static int mt7988_pcie_p2_phy_i2c_funcs[] = { 5, 5 };
-
-static int mt7988_ckm_phy_i2c_pins[] = { 9, 10 };
-static int mt7988_ckm_phy_i2c_funcs[] = { 5, 5 };
-
-static int mt7988_pcie_wake_n0_1_pins[] = { 13 };
-static int mt7988_pcie_wake_n0_1_funcs[] = { 2 };
-
-static int mt7988_pcie_wake_n3_1_pins[] = { 14 };
-static int mt7988_pcie_wake_n3_1_funcs[] = { 2 };
-
-static int mt7988_pcie_2l_0_pereset_pins[] = { 19 };
-static int mt7988_pcie_2l_0_pereset_funcs[] = { 1 };
-
-static int mt7988_pcie_1l_1_pereset_pins[] = { 20 };
-static int mt7988_pcie_1l_1_pereset_funcs[] = { 1 };
-
-static int mt7988_pcie_clk_req_n2_1_pins[] = { 63 };
-static int mt7988_pcie_clk_req_n2_1_funcs[] = { 2 };
-
-static int mt7988_pcie_2l_1_pereset_pins[] = { 73 };
-static int mt7988_pcie_2l_1_pereset_funcs[] = { 1 };
-
-static int mt7988_pcie_1l_0_pereset_pins[] = { 74 };
-static int mt7988_pcie_1l_0_pereset_funcs[] = { 1 };
-
-static int mt7988_pcie_wake_n1_0_pins[] = { 75 };
-static int mt7988_pcie_wake_n1_0_funcs[] = { 1 };
-
-static int mt7988_pcie_clk_req_n1_pins[] = { 76 };
-static int mt7988_pcie_clk_req_n1_funcs[] = { 1 };
-
-static int mt7988_pcie_wake_n2_0_pins[] = { 77 };
-static int mt7988_pcie_wake_n2_0_funcs[] = { 1 };
-
-static int mt7988_pcie_clk_req_n2_0_pins[] = { 78 };
-static int mt7988_pcie_clk_req_n2_0_funcs[] = { 1 };
-
-static int mt7988_pcie_wake_n2_1_pins[] = { 79 };
-static int mt7988_pcie_wake_n2_1_funcs[] = { 2 };
-
-/* pmic */
-static int mt7988_pmic_pins[] = { 11 };
-static int mt7988_pmic_funcs[] = { 1 };
-
-/* watchdog */
-static int mt7988_watchdog_pins[] = { 12 };
-static int mt7988_watchdog_funcs[] = { 1 };
-
-/* spi */
-static int mt7988_spi0_wp_hold_pins[] = { 22, 23 };
-static int mt7988_spi0_wp_hold_funcs[] = { 1, 1 };
-
-static int mt7988_spi0_pins[] = { 24, 25, 26, 27 };
-static int mt7988_spi0_funcs[] = { 1, 1, 1, 1 };
-
-static int mt7988_spi1_pins[] = { 28, 29, 30, 31 };
-static int mt7988_spi1_funcs[] = { 1, 1, 1, 1 };
-
-static int mt7988_spi2_pins[] = { 32, 33, 34, 35 };
-static int mt7988_spi2_funcs[] = { 1, 1, 1, 1 };
-
-static int mt7988_spi2_wp_hold_pins[] = { 36, 37 };
-static int mt7988_spi2_wp_hold_funcs[] = { 1, 1 };
-
-/* flash */
-static int mt7988_snfi_pins[] = { 22, 23, 24, 25, 26, 27 };
-static int mt7988_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
-
-static int mt7988_emmc_45_pins[] = {
- 21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
-};
-static int mt7988_emmc_45_funcs[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
-
-static int mt7988_sdcard_pins[] = { 32, 33, 34, 35, 36, 37 };
-static int mt7988_sdcard_funcs[] = { 5, 5, 5, 5, 5, 5 };
-
-static int mt7988_emmc_51_pins[] = { 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 49 };
-static int mt7988_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
-
-/* uart */
-static int mt7988_uart2_pins[] = { 0, 1, 2, 3 };
-static int mt7988_uart2_funcs[] = { 1, 1, 1, 1 };
-
-static int mt7988_tops_uart0_0_pins[] = { 22, 23 };
-static int mt7988_tops_uart0_0_funcs[] = { 3, 3 };
-
-static int mt7988_uart2_0_pins[] = { 28, 29, 30, 31 };
-static int mt7988_uart2_0_funcs[] = { 2, 2, 2, 2 };
-
-static int mt7988_uart1_0_pins[] = { 32, 33, 34, 35 };
-static int mt7988_uart1_0_funcs[] = { 2, 2, 2, 2 };
-
-static int mt7988_uart2_1_pins[] = { 32, 33, 34, 35 };
-static int mt7988_uart2_1_funcs[] = { 3, 3, 3, 3 };
-
-static int mt7988_net_wo0_uart_txd_0_pins[] = { 28 };
-static int mt7988_net_wo0_uart_txd_0_funcs[] = { 3 };
-
-static int mt7988_net_wo1_uart_txd_0_pins[] = { 29 };
-static int mt7988_net_wo1_uart_txd_0_funcs[] = { 3 };
-
-static int mt7988_net_wo2_uart_txd_0_pins[] = { 30 };
-static int mt7988_net_wo2_uart_txd_0_funcs[] = { 3 };
-
-static int mt7988_tops_uart1_0_pins[] = { 28, 29 };
-static int mt7988_tops_uart1_0_funcs[] = { 4, 4 };
-
-static int mt7988_tops_uart0_1_pins[] = { 30, 31 };
-static int mt7988_tops_uart0_1_funcs[] = { 4, 4 };
-
-static int mt7988_tops_uart1_1_pins[] = { 36, 37 };
-static int mt7988_tops_uart1_1_funcs[] = { 3, 3 };
-
-static int mt7988_uart0_pins[] = { 55, 56 };
-static int mt7988_uart0_funcs[] = { 1, 1 };
-
-static int mt7988_tops_uart0_2_pins[] = { 55, 56 };
-static int mt7988_tops_uart0_2_funcs[] = { 2, 2 };
-
-static int mt7988_uart2_2_pins[] = { 50, 51, 52, 53 };
-static int mt7988_uart2_2_funcs[] = { 2, 2, 2, 2 };
-
-static int mt7988_uart1_1_pins[] = { 58, 59, 60, 61 };
-static int mt7988_uart1_1_funcs[] = { 2, 2, 2, 2 };
-
-static int mt7988_uart2_3_pins[] = { 58, 59, 60, 61 };
-static int mt7988_uart2_3_funcs[] = { 3, 3, 3, 3 };
-
-static int mt7988_uart1_2_pins[] = { 80, 81, 82, 83 };
-static int mt7988_uart1_2_funcs[] = { 1, 1, 1, 1 };
-
-static int mt7988_uart1_2_lite_pins[] = { 80, 81 };
-static int mt7988_uart1_2_lite_funcs[] = { 1, 1 };
-
-static int mt7988_tops_uart1_2_pins[] = { 80, 81 };
-static int mt7988_tops_uart1_2_funcs[] = { 4, 4, };
-
-static int mt7988_net_wo0_uart_txd_1_pins[] = { 80 };
-static int mt7988_net_wo0_uart_txd_1_funcs[] = { 3 };
-
-static int mt7988_net_wo1_uart_txd_1_pins[] = { 81 };
-static int mt7988_net_wo1_uart_txd_1_funcs[] = { 3 };
-
-static int mt7988_net_wo2_uart_txd_1_pins[] = { 82 };
-static int mt7988_net_wo2_uart_txd_1_funcs[] = { 3 };
-
-/* udi */
-static int mt7988_udi_pins[] = { 32, 33, 34, 35, 36 };
-static int mt7988_udi_funcs[] = { 4, 4, 4, 4, 4 };
-
-/* i2s */
-static int mt7988_i2s_pins[] = { 50, 51, 52, 53, 54 };
-static int mt7988_i2s_funcs[] = { 1, 1, 1, 1, 1 };
-
-/* pcm */
-static int mt7988_pcm_pins[] = { 50, 51, 52, 53 };
-static int mt7988_pcm_funcs[] = { 1, 1, 1, 1 };
-
-/* led */
-static int mt7988_gbe0_led1_pins[] = { 58 };
-static int mt7988_gbe0_led1_funcs[] = { 6 };
-static int mt7988_gbe1_led1_pins[] = { 59 };
-static int mt7988_gbe1_led1_funcs[] = { 6 };
-static int mt7988_gbe2_led1_pins[] = { 60 };
-static int mt7988_gbe2_led1_funcs[] = { 6 };
-static int mt7988_gbe3_led1_pins[] = { 61 };
-static int mt7988_gbe3_led1_funcs[] = { 6 };
-
-static int mt7988_2p5gbe_led1_pins[] = { 62 };
-static int mt7988_2p5gbe_led1_funcs[] = { 6 };
-
-static int mt7988_gbe0_led0_pins[] = { 64 };
-static int mt7988_gbe0_led0_funcs[] = { 1 };
-static int mt7988_gbe1_led0_pins[] = { 65 };
-static int mt7988_gbe1_led0_funcs[] = { 1 };
-static int mt7988_gbe2_led0_pins[] = { 66 };
-static int mt7988_gbe2_led0_funcs[] = { 1 };
-static int mt7988_gbe3_led0_pins[] = { 67 };
-static int mt7988_gbe3_led0_funcs[] = { 1 };
-
-static int mt7988_2p5gbe_led0_pins[] = { 68 };
-static int mt7988_2p5gbe_led0_funcs[] = { 1 };
-
-/* usb */
-static int mt7988_drv_vbus_p1_pins[] = { 63 };
-static int mt7988_drv_vbus_p1_funcs[] = { 1 };
-
-static int mt7988_drv_vbus_pins[] = { 79 };
-static int mt7988_drv_vbus_funcs[] = { 1 };
-
-static const struct group_desc mt7988_groups[] = {
- /* @GPIO(0,1,2,3): uart2 */
- PINCTRL_PIN_GROUP("uart2", mt7988_uart2),
- /* @GPIO(0,1,2,3,4): tops_jtag0_0 */
- PINCTRL_PIN_GROUP("tops_jtag0_0", mt7988_tops_jtag0_0),
- /* @GPIO(2,3): int_usxgmii */
- PINCTRL_PIN_GROUP("int_usxgmii", mt7988_int_usxgmii),
- /* @GPIO(0,1,2,3,4): dfd */
- PINCTRL_PIN_GROUP("dfd", mt7988_dfd),
- /* @GPIO(0,1): xfi_phy0_i2c0 */
- PINCTRL_PIN_GROUP("xfi_phy0_i2c0", mt7988_xfi_phy0_i2c0),
- /* @GPIO(0,1): xfi_phy1_i2c0 */
- PINCTRL_PIN_GROUP("xfi_phy1_i2c0", mt7988_xfi_phy1_i2c0),
- /* @GPIO(3,4): xfi_phy_pll_i2c0 */
- PINCTRL_PIN_GROUP("xfi_phy_pll_i2c0", mt7988_xfi_phy_pll_i2c0),
- /* @GPIO(3,4): xfi_phy_pll_i2c1 */
- PINCTRL_PIN_GROUP("xfi_phy_pll_i2c1", mt7988_xfi_phy_pll_i2c1),
- /* @GPIO(5,6) i2c0_0 */
- PINCTRL_PIN_GROUP("i2c0_0", mt7988_i2c0_0),
- /* @GPIO(5,6) i2c1_sfp */
- PINCTRL_PIN_GROUP("i2c1_sfp", mt7988_i2c1_sfp),
- /* @GPIO(5,6) xfi_pextp_phy0_i2c */
- PINCTRL_PIN_GROUP("xfi_pextp_phy0_i2c", mt7988_xfi_pextp_phy0_i2c),
- /* @GPIO(5,6) xfi_pextp_phy1_i2c */
- PINCTRL_PIN_GROUP("xfi_pextp_phy1_i2c", mt7988_xfi_pextp_phy1_i2c),
- /* @GPIO(5,6) mdc_mdio0 */
- PINCTRL_PIN_GROUP("mdc_mdio0", mt7988_mdc_mdio0),
- /* @GPIO(7): pcie_wake_n0_0 */
- PINCTRL_PIN_GROUP("pcie_wake_n0_0", mt7988_pcie_wake_n0_0),
- /* @GPIO(8): pcie_clk_req_n0_0 */
- PINCTRL_PIN_GROUP("pcie_clk_req_n0_0", mt7988_pcie_clk_req_n0_0),
- /* @GPIO(9): pcie_wake_n3_0 */
- PINCTRL_PIN_GROUP("pcie_wake_n3_0", mt7988_pcie_wake_n3_0),
- /* @GPIO(10): pcie_clk_req_n3 */
- PINCTRL_PIN_GROUP("pcie_clk_req_n3", mt7988_pcie_clk_req_n3),
- /* @GPIO(10): pcie_clk_req_n0_1 */
- PINCTRL_PIN_GROUP("pcie_clk_req_n0_1", mt7988_pcie_clk_req_n0_1),
- /* @GPIO(7,8) pcie_p0_phy_i2c */
- PINCTRL_PIN_GROUP("pcie_p0_phy_i2c", mt7988_pcie_p0_phy_i2c),
- /* @GPIO(7,8) pcie_p1_phy_i2c */
- PINCTRL_PIN_GROUP("pcie_p1_phy_i2c", mt7988_pcie_p1_phy_i2c),
- /* @GPIO(7,8) pcie_p2_phy_i2c */
- PINCTRL_PIN_GROUP("pcie_p2_phy_i2c", mt7988_pcie_p2_phy_i2c),
- /* @GPIO(9,10) pcie_p3_phy_i2c */
- PINCTRL_PIN_GROUP("pcie_p3_phy_i2c", mt7988_pcie_p3_phy_i2c),
- /* @GPIO(9,10) ckm_phy_i2c */
- PINCTRL_PIN_GROUP("ckm_phy_i2c", mt7988_ckm_phy_i2c),
- /* @GPIO(11): pmic */
- PINCTRL_PIN_GROUP("pcie_pmic", mt7988_pmic),
- /* @GPIO(12): watchdog */
- PINCTRL_PIN_GROUP("watchdog", mt7988_watchdog),
- /* @GPIO(13): pcie_wake_n0_1 */
- PINCTRL_PIN_GROUP("pcie_wake_n0_1", mt7988_pcie_wake_n0_1),
- /* @GPIO(14): pcie_wake_n3_1 */
- PINCTRL_PIN_GROUP("pcie_wake_n3_1", mt7988_pcie_wake_n3_1),
- /* @GPIO(15,16) i2c0_1 */
- PINCTRL_PIN_GROUP("i2c0_1", mt7988_i2c0_1),
- /* @GPIO(15,16) u30_phy_i2c0 */
- PINCTRL_PIN_GROUP("u30_phy_i2c0", mt7988_u30_phy_i2c0),
- /* @GPIO(15,16) u32_phy_i2c0 */
- PINCTRL_PIN_GROUP("u32_phy_i2c0", mt7988_u32_phy_i2c0),
- /* @GPIO(15,16) xfi_phy0_i2c1 */
- PINCTRL_PIN_GROUP("xfi_phy0_i2c1", mt7988_xfi_phy0_i2c1),
- /* @GPIO(15,16) xfi_phy1_i2c1 */
- PINCTRL_PIN_GROUP("xfi_phy1_i2c1", mt7988_xfi_phy1_i2c1),
- /* @GPIO(15,16) xfi_phy_pll_i2c2 */
- PINCTRL_PIN_GROUP("xfi_phy_pll_i2c2", mt7988_xfi_phy_pll_i2c2),
- /* @GPIO(17,18) i2c1_0 */
- PINCTRL_PIN_GROUP("i2c1_0", mt7988_i2c1_0),
- /* @GPIO(17,18) u30_phy_i2c1 */
- PINCTRL_PIN_GROUP("u30_phy_i2c1", mt7988_u30_phy_i2c1),
- /* @GPIO(17,18) u32_phy_i2c1 */
- PINCTRL_PIN_GROUP("u32_phy_i2c1", mt7988_u32_phy_i2c1),
- /* @GPIO(17,18) xfi_phy_pll_i2c3 */
- PINCTRL_PIN_GROUP("xfi_phy_pll_i2c3", mt7988_xfi_phy_pll_i2c3),
- /* @GPIO(17,18) sgmii0_i2c */
- PINCTRL_PIN_GROUP("sgmii0_i2c", mt7988_sgmii0_i2c),
- /* @GPIO(17,18) sgmii1_i2c */
- PINCTRL_PIN_GROUP("sgmii1_i2c", mt7988_sgmii1_i2c),
- /* @GPIO(19): pcie_2l_0_pereset */
- PINCTRL_PIN_GROUP("pcie_2l_0_pereset", mt7988_pcie_2l_0_pereset),
- /* @GPIO(20): pcie_1l_1_pereset */
- PINCTRL_PIN_GROUP("pcie_1l_1_pereset", mt7988_pcie_1l_1_pereset),
- /* @GPIO(21): pwm1 */
- PINCTRL_PIN_GROUP("pwm1", mt7988_pwm1),
- /* @GPIO(22,23) spi0_wp_hold */
- PINCTRL_PIN_GROUP("spi0_wp_hold", mt7988_spi0_wp_hold),
- /* @GPIO(24,25,26,27) spi0 */
- PINCTRL_PIN_GROUP("spi0", mt7988_spi0),
- /* @GPIO(28,29,30,31) spi1 */
- PINCTRL_PIN_GROUP("spi1", mt7988_spi1),
- /* @GPIO(32,33,34,35) spi2 */
- PINCTRL_PIN_GROUP("spi2", mt7988_spi2),
- /* @GPIO(36,37) spi2_wp_hold */
- PINCTRL_PIN_GROUP("spi2_wp_hold", mt7988_spi2_wp_hold),
- /* @GPIO(22,23,24,25,26,27) snfi */
- PINCTRL_PIN_GROUP("snfi", mt7988_snfi),
- /* @GPIO(22,23) tops_uart0_0 */
- PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart0_0),
- /* @GPIO(28,29,30,31) uart2_0 */
- PINCTRL_PIN_GROUP("uart2_0", mt7988_uart2_0),
- /* @GPIO(32,33,34,35) uart1_0 */
- PINCTRL_PIN_GROUP("uart1_0", mt7988_uart1_0),
- /* @GPIO(32,33,34,35) uart2_1 */
- PINCTRL_PIN_GROUP("uart2_1", mt7988_uart2_1),
- /* @GPIO(28) net_wo0_uart_txd_0 */
- PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
- /* @GPIO(29) net_wo1_uart_txd_0 */
- PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
- /* @GPIO(30) net_wo2_uart_txd_0 */
- PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
- /* @GPIO(28,29) tops_uart1_0 */
- PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart1_0),
- /* @GPIO(30,31) tops_uart0_1 */
- PINCTRL_PIN_GROUP("tops_uart0_1", mt7988_tops_uart0_1),
- /* @GPIO(36,37) tops_uart1_1 */
- PINCTRL_PIN_GROUP("tops_uart1_1", mt7988_tops_uart1_1),
- /* @GPIO(32,33,34,35,36) udi */
- PINCTRL_PIN_GROUP("udi", mt7988_udi),
- /* @GPIO(21,28,29,30,31,32,33,34,35,36,37) emmc_45 */
- PINCTRL_PIN_GROUP("emmc_45", mt7988_emmc_45),
- /* @GPIO(32,33,34,35,36,37) sdcard */
- PINCTRL_PIN_GROUP("sdcard", mt7988_sdcard),
- /* @GPIO(38,39,40,41,42,43,44,45,46,47,48,49) emmc_51 */
- PINCTRL_PIN_GROUP("emmc_51", mt7988_emmc_51),
- /* @GPIO(28,29) 2p5g_ext_mdio */
- PINCTRL_PIN_GROUP("2p5g_ext_mdio", mt7988_2p5g_ext_mdio),
- /* @GPIO(30,31) gbe_ext_mdio */
- PINCTRL_PIN_GROUP("gbe_ext_mdio", mt7988_gbe_ext_mdio),
- /* @GPIO(50,51,52,53,54) i2s */
- PINCTRL_PIN_GROUP("i2s", mt7988_i2s),
- /* @GPIO(50,51,52,53) pcm */
- PINCTRL_PIN_GROUP("pcm", mt7988_pcm),
- /* @GPIO(55,56) uart0 */
- PINCTRL_PIN_GROUP("uart0", mt7988_uart0),
- /* @GPIO(55,56) tops_uart0_2 */
- PINCTRL_PIN_GROUP("tops_uart0_2", mt7988_tops_uart0_2),
- /* @GPIO(50,51,52,53) uart2_2 */
- PINCTRL_PIN_GROUP("uart2_2", mt7988_uart2_2),
- /* @GPIO(50,51,52,53,54) wo0_jtag */
- PINCTRL_PIN_GROUP("wo0_jtag", mt7988_wo0_jtag),
- /* @GPIO(50,51,52,53,54) wo1-wo1_jtag */
- PINCTRL_PIN_GROUP("wo1_jtag", mt7988_wo1_jtag),
- /* @GPIO(50,51,52,53,54) wo2_jtag */
- PINCTRL_PIN_GROUP("wo2_jtag", mt7988_wo2_jtag),
- /* @GPIO(57) pwm0 */
- PINCTRL_PIN_GROUP("pwm0", mt7988_pwm0),
- /* @GPIO(58,59,60,61,62) jtag */
- PINCTRL_PIN_GROUP("jtag", mt7988_jtag),
- /* @GPIO(58,59,60,61,62) tops_jtag0_1 */
- PINCTRL_PIN_GROUP("tops_jtag0_1", mt7988_tops_jtag0_1),
- /* @GPIO(58,59,60,61) uart2_3 */
- PINCTRL_PIN_GROUP("uart2_3", mt7988_uart2_3),
- /* @GPIO(58,59,60,61) uart1_1 */
- PINCTRL_PIN_GROUP("uart1_1", mt7988_uart1_1),
- /* @GPIO(58,59,60,61) gbe_led1 */
- PINCTRL_PIN_GROUP("gbe0_led1", mt7988_gbe0_led1),
- PINCTRL_PIN_GROUP("gbe1_led1", mt7988_gbe1_led1),
- PINCTRL_PIN_GROUP("gbe2_led1", mt7988_gbe2_led1),
- PINCTRL_PIN_GROUP("gbe3_led1", mt7988_gbe3_led1),
- /* @GPIO(62) 2p5gbe_led1 */
- PINCTRL_PIN_GROUP("2p5gbe_led1", mt7988_2p5gbe_led1),
- /* @GPIO(64,65,66,67) gbe_led0 */
- PINCTRL_PIN_GROUP("gbe0_led0", mt7988_gbe0_led0),
- PINCTRL_PIN_GROUP("gbe1_led0", mt7988_gbe1_led0),
- PINCTRL_PIN_GROUP("gbe2_led0", mt7988_gbe2_led0),
- PINCTRL_PIN_GROUP("gbe3_led0", mt7988_gbe3_led0),
- /* @GPIO(68) 2p5gbe_led0 */
- PINCTRL_PIN_GROUP("2p5gbe_led0", mt7988_2p5gbe_led0),
- /* @GPIO(63) drv_vbus_p1 */
- PINCTRL_PIN_GROUP("drv_vbus_p1", mt7988_drv_vbus_p1),
- /* @GPIO(63) pcie_clk_req_n2_1 */
- PINCTRL_PIN_GROUP("pcie_clk_req_n2_1", mt7988_pcie_clk_req_n2_1),
- /* @GPIO(69, 70) mdc_mdio1 */
- PINCTRL_PIN_GROUP("mdc_mdio1", mt7988_mdc_mdio1),
- /* @GPIO(69, 70) i2c1_2 */
- PINCTRL_PIN_GROUP("i2c1_2", mt7988_i2c1_2),
- /* @GPIO(69) pwm6 */
- PINCTRL_PIN_GROUP("pwm6", mt7988_pwm6),
- /* @GPIO(70) pwm7 */
- PINCTRL_PIN_GROUP("pwm7", mt7988_pwm7),
- /* @GPIO(69,70) i2c2_0 */
- PINCTRL_PIN_GROUP("i2c2_0", mt7988_i2c2_0),
- /* @GPIO(71,72) i2c2_1 */
- PINCTRL_PIN_GROUP("i2c2_1", mt7988_i2c2_1),
- /* @GPIO(73) pcie_2l_1_pereset */
- PINCTRL_PIN_GROUP("pcie_2l_1_pereset", mt7988_pcie_2l_1_pereset),
- /* @GPIO(74) pcie_1l_0_pereset */
- PINCTRL_PIN_GROUP("pcie_1l_0_pereset", mt7988_pcie_1l_0_pereset),
- /* @GPIO(75) pcie_wake_n1_0 */
- PINCTRL_PIN_GROUP("pcie_wake_n1_0", mt7988_pcie_wake_n1_0),
- /* @GPIO(76) pcie_clk_req_n1 */
- PINCTRL_PIN_GROUP("pcie_clk_req_n1", mt7988_pcie_clk_req_n1),
- /* @GPIO(77) pcie_wake_n2_0 */
- PINCTRL_PIN_GROUP("pcie_wake_n2_0", mt7988_pcie_wake_n2_0),
- /* @GPIO(78) pcie_clk_req_n2_0 */
- PINCTRL_PIN_GROUP("pcie_clk_req_n2_0", mt7988_pcie_clk_req_n2_0),
- /* @GPIO(79) drv_vbus */
- PINCTRL_PIN_GROUP("drv_vbus", mt7988_drv_vbus),
- /* @GPIO(79) pcie_wake_n2_1 */
- PINCTRL_PIN_GROUP("pcie_wake_n2_1", mt7988_pcie_wake_n2_1),
- /* @GPIO(80,81,82,83) uart1_2 */
- PINCTRL_PIN_GROUP("uart1_2", mt7988_uart1_2),
- /* @GPIO(80,81) uart1_2_lite */
- PINCTRL_PIN_GROUP("uart1_2_lite", mt7988_uart1_2_lite),
- /* @GPIO(80) pwm2 */
- PINCTRL_PIN_GROUP("pwm2", mt7988_pwm2),
- /* @GPIO(81) pwm3 */
- PINCTRL_PIN_GROUP("pwm3", mt7988_pwm3),
- /* @GPIO(82) pwm4 */
- PINCTRL_PIN_GROUP("pwm4", mt7988_pwm4),
- /* @GPIO(83) pwm5 */
- PINCTRL_PIN_GROUP("pwm5", mt7988_pwm5),
- /* @GPIO(80) net_wo0_uart_txd_0 */
- PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
- /* @GPIO(81) net_wo1_uart_txd_0 */
- PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
- /* @GPIO(82) net_wo2_uart_txd_0 */
- PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
- /* @GPIO(80,81) tops_uart1_2 */
- PINCTRL_PIN_GROUP("tops_uart1_2", mt7988_tops_uart1_2),
- /* @GPIO(80) net_wo0_uart_txd_1 */
- PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7988_net_wo0_uart_txd_1),
- /* @GPIO(81) net_wo1_uart_txd_1 */
- PINCTRL_PIN_GROUP("net_wo1_uart_txd_1", mt7988_net_wo1_uart_txd_1),
- /* @GPIO(82) net_wo2_uart_txd_1 */
- PINCTRL_PIN_GROUP("net_wo2_uart_txd_1", mt7988_net_wo2_uart_txd_1),
-};
-
-/* Joint those groups owning the same capability in user point of view which
- * allows that people tend to use through the device tree.
- */
-static const char * const mt7988_jtag_groups[] = {
- "tops_jtag0_0", "wo0_jtag", "wo1_jtag",
- "wo2_jtag", "jtag", "tops_jtag0_1",
-};
-static const char * const mt7988_int_usxgmii_groups[] = {
- "int_usxgmii",
-};
-static const char * const mt7988_pwm_groups[] = {
- "pwm0", "pwm1", "pwm2", "pwm3", "pwm4", "pwm5", "pwm6", "pwm7"
-};
-static const char * const mt7988_dfd_groups[] = {
- "dfd",
-};
-static const char * const mt7988_i2c_groups[] = {
- "xfi_phy0_i2c0",
- "xfi_phy1_i2c0",
- "xfi_phy_pll_i2c0",
- "xfi_phy_pll_i2c1",
- "i2c0_0",
- "i2c1_sfp",
- "xfi_pextp_phy0_i2c",
- "xfi_pextp_phy1_i2c",
- "i2c0_1",
- "u30_phy_i2c0",
- "u32_phy_i2c0",
- "xfi_phy0_i2c1",
- "xfi_phy1_i2c1",
- "xfi_phy_pll_i2c2",
- "i2c1_0",
- "u30_phy_i2c1",
- "u32_phy_i2c1",
- "xfi_phy_pll_i2c3",
- "sgmii0_i2c",
- "sgmii1_i2c",
- "i2c1_2",
- "i2c2_0",
- "i2c2_1",
-};
-static const char * const mt7988_ethernet_groups[] = {
- "mdc_mdio0",
- "2p5g_ext_mdio",
- "gbe_ext_mdio",
- "mdc_mdio1",
-};
-static const char * const mt7988_pcie_groups[] = {
- "pcie_wake_n0_0", "pcie_clk_req_n0_0", "pcie_wake_n3_0",
- "pcie_clk_req_n3", "pcie_p0_phy_i2c", "pcie_p1_phy_i2c",
- "pcie_p3_phy_i2c", "pcie_p2_phy_i2c", "ckm_phy_i2c",
- "pcie_wake_n0_1", "pcie_wake_n3_1", "pcie_2l_0_pereset",
- "pcie_1l_1_pereset", "pcie_clk_req_n2_1", "pcie_2l_1_pereset",
- "pcie_1l_0_pereset", "pcie_wake_n1_0", "pcie_clk_req_n1",
- "pcie_wake_n2_0", "pcie_clk_req_n2_0", "pcie_wake_n2_1",
- "pcie_clk_req_n0_1"
-};
-static const char * const mt7988_pmic_groups[] = {
- "pmic",
-};
-static const char * const mt7988_wdt_groups[] = {
- "watchdog",
-};
-static const char * const mt7988_spi_groups[] = {
- "spi0", "spi0_wp_hold", "spi1", "spi2", "spi2_wp_hold",
-};
-static const char * const mt7988_flash_groups[] = { "emmc_45", "sdcard", "snfi",
- "emmc_51" };
-static const char * const mt7988_uart_groups[] = {
- "uart2",
- "tops_uart0_0",
- "uart2_0",
- "uart1_0",
- "uart2_1",
- "net_wo0_uart_txd_0",
- "net_wo1_uart_txd_0",
- "net_wo2_uart_txd_0",
- "tops_uart1_0",
- "ops_uart0_1",
- "ops_uart1_1",
- "uart0",
- "tops_uart0_2",
- "uart1_1",
- "uart2_3",
- "uart1_2",
- "uart1_2_lite",
- "tops_uart1_2",
- "net_wo0_uart_txd_1",
- "net_wo1_uart_txd_1",
- "net_wo2_uart_txd_1",
-};
-static const char * const mt7988_udi_groups[] = {
- "udi",
-};
-static const char * const mt7988_audio_groups[] = {
- "i2s", "pcm",
-};
-static const char * const mt7988_led_groups[] = {
- "gbe0_led1", "gbe1_led1", "gbe2_led1", "gbe3_led1", "2p5gbe_led1",
- "gbe0_led0", "gbe1_led0", "gbe2_led0", "gbe3_led0", "2p5gbe_led0",
- "wf5g_led0", "wf5g_led1",
-};
-static const char * const mt7988_usb_groups[] = {
- "drv_vbus",
- "drv_vbus_p1",
-};
-
-static const struct function_desc mt7988_functions[] = {
- { "audio", mt7988_audio_groups, ARRAY_SIZE(mt7988_audio_groups) },
- { "jtag", mt7988_jtag_groups, ARRAY_SIZE(mt7988_jtag_groups) },
- { "int_usxgmii", mt7988_int_usxgmii_groups,
- ARRAY_SIZE(mt7988_int_usxgmii_groups) },
- { "pwm", mt7988_pwm_groups, ARRAY_SIZE(mt7988_pwm_groups) },
- { "dfd", mt7988_dfd_groups, ARRAY_SIZE(mt7988_dfd_groups) },
- { "i2c", mt7988_i2c_groups, ARRAY_SIZE(mt7988_i2c_groups) },
- { "eth", mt7988_ethernet_groups, ARRAY_SIZE(mt7988_ethernet_groups) },
- { "pcie", mt7988_pcie_groups, ARRAY_SIZE(mt7988_pcie_groups) },
- { "pmic", mt7988_pmic_groups, ARRAY_SIZE(mt7988_pmic_groups) },
- { "watchdog", mt7988_wdt_groups, ARRAY_SIZE(mt7988_wdt_groups) },
- { "spi", mt7988_spi_groups, ARRAY_SIZE(mt7988_spi_groups) },
- { "flash", mt7988_flash_groups, ARRAY_SIZE(mt7988_flash_groups) },
- { "uart", mt7988_uart_groups, ARRAY_SIZE(mt7988_uart_groups) },
- { "udi", mt7988_udi_groups, ARRAY_SIZE(mt7988_udi_groups) },
- { "usb", mt7988_usb_groups, ARRAY_SIZE(mt7988_usb_groups) },
- { "led", mt7988_led_groups, ARRAY_SIZE(mt7988_led_groups) },
-};
-
-static const struct mtk_eint_hw mt7988_eint_hw = {
- .port_mask = 7,
- .ports = 7,
- .ap_num = ARRAY_SIZE(mt7988_pins),
- .db_cnt = 16,
-};
-
-static const char * const mt7988_pinctrl_register_base_names[] = {
- "gpio_base", "iocfg_tr_base", "iocfg_br_base",
- "iocfg_rb_base", "iocfg_lb_base", "iocfg_tl_base",
-};
-
-static struct mtk_pin_soc mt7988_data = {
- .reg_cal = mt7988_reg_cals,
- .pins = mt7988_pins,
- .npins = ARRAY_SIZE(mt7988_pins),
- .grps = mt7988_groups,
- .ngrps = ARRAY_SIZE(mt7988_groups),
- .funcs = mt7988_functions,
- .nfuncs = ARRAY_SIZE(mt7988_functions),
- .eint_hw = &mt7988_eint_hw,
- .gpio_m = 0,
- .ies_present = false,
- .base_names = mt7988_pinctrl_register_base_names,
- .nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
- .bias_disable_set = mtk_pinconf_bias_disable_set,
- .bias_disable_get = mtk_pinconf_bias_disable_get,
- .bias_set = mtk_pinconf_bias_set,
- .bias_get = mtk_pinconf_bias_get,
- .pull_type = mt7988_pull_type,
- .bias_set_combo = mtk_pinconf_bias_set_combo,
- .bias_get_combo = mtk_pinconf_bias_get_combo,
- .drive_set = mtk_pinconf_drive_set_rev1,
- .drive_get = mtk_pinconf_drive_get_rev1,
- .adv_pull_get = mtk_pinconf_adv_pull_get,
- .adv_pull_set = mtk_pinconf_adv_pull_set,
-};
-
-static const struct of_device_id mt7988_pinctrl_of_match[] = {
- {
- .compatible = "mediatek,mt7988-pinctrl",
- },
- {}
-};
-
-static int mt7988_pinctrl_probe(struct platform_device *pdev)
-{
- return mtk_moore_pinctrl_probe(pdev, &mt7988_data);
-}
-
-static struct platform_driver mt7988_pinctrl_driver = {
- .driver = {
- .name = "mt7988-pinctrl",
- .of_match_table = mt7988_pinctrl_of_match,
- },
- .probe = mt7988_pinctrl_probe,
-};
-
-static int __init mt7988_pinctrl_init(void)
-{
- return platform_driver_register(&mt7988_pinctrl_driver);
-}
-arch_initcall(mt7988_pinctrl_init);
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+#include "mt7988a-bananapi-bpi-r4.dtsi"
+
+/ {
+ model = "Bananapi BPI-R4 2.5GE PoE";
+ compatible = "bananapi,bpi-r4-poe",
+ "mediatek,mt7988a";
+};
+
+&gmac1 {
+ phy-mode = "internal";
+ phy-connection-type = "internal";
+ phy = <&int_2p5g_phy>;
+ status = "okay";
+};
+
+&int_2p5g_phy {
+ pinctrl-names = "i2p5gbe-led";
+ pinctrl-0 = <&i2p5gbe_led0_pins>;
+};
* Author: Sam.Shih <sam.shih@mediatek.com>
*/
-/dts-v1/;
-#include "mt7988a.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
+#include "mt7988a-bananapi-bpi-r4.dtsi"
/ {
model = "Bananapi BPI-R4";
compatible = "bananapi,bpi-r4",
"mediatek,mt7988a";
- aliases {
- serial0 = &uart0;
- led-boot = &led_green;
- led-failsafe = &led_green;
- led-running = &led_green;
- led-upgrade = &led_green;
- };
-
- chosen {
- stdout-path = &uart0;
- bootargs = "console=ttyS0,115200n1 loglevel=8 pci=pcie_bus_perf ubi.block=0,fit root=/dev/fit0";
- rootdisk-spim-nand = <&ubi_rootfs>;
- };
-
- memory {
- reg = <0x00 0x40000000 0x00 0x10000000>;
- };
-
- /* SFP1 cage (WAN) */
- sfp1: sfp1 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp1>;
- los-gpios = <&pio 54 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>;
- tx-disable-gpios = <&pio 70 GPIO_ACTIVE_HIGH>;
- tx-fault-gpios = <&pio 69 GPIO_ACTIVE_HIGH>;
- rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>;
- maximum-power-milliwatt = <3000>;
- };
-
/* SFP2 cage (LAN) */
sfp2: sfp2 {
compatible = "sff,sfp";
rate-select0-gpios = <&pio 3 GPIO_ACTIVE_LOW>;
maximum-power-milliwatt = <3000>;
};
-
- gpio-keys {
- compatible = "gpio-keys";
-
- wps {
- label = "WPS";
- linux,code = <KEY_RESTART>;
- gpios = <&pio 14 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
-
- led_green: led-green {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&pio 79 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
-
- led_blue: led-blue {
- function = LED_FUNCTION_WPS;
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&pio 63 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
- };
-};
-
-ð {
- status = "okay";
-};
-
-&gmac0 {
- status = "okay";
};
&gmac1 {
status = "okay";
};
-&gmac2 {
- sfp = <&sfp1>;
- managed = "in-band-status";
- phy-mode = "usxgmii";
- status = "okay";
-};
-
-&switch {
- status = "okay";
-};
-
-&gsw_phy0 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe0_led0_pins>;
-};
-
-&gsw_port0 {
- label = "wan";
-};
-
-&gsw_phy0_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&gsw_phy1 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe1_led0_pins>;
-};
-
-&gsw_phy1_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&gsw_phy2 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe2_led0_pins>;
-};
-
-&gsw_phy2_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&gsw_phy3 {
- pinctrl-names = "gbe-led";
- pinctrl-0 = <&gbe3_led0_pins>;
-};
-
-&gsw_phy3_led0 {
- status = "okay";
- color = <LED_COLOR_ID_GREEN>;
-};
-
-&cpu0 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cpu1 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cpu2 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cpu3 {
- proc-supply = <&rt5190_buck3>;
-};
-
-&cci {
- proc-supply = <&rt5190_buck3>;
-};
-
-&i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins>;
- status = "okay";
-
- rt5190a_64: rt5190a@64 {
- compatible = "richtek,rt5190a";
- reg = <0x64>;
- vin2-supply = <&rt5190_buck1>;
- vin3-supply = <&rt5190_buck1>;
- vin4-supply = <&rt5190_buck1>;
-
- regulators {
- rt5190_buck1: buck1 {
- regulator-name = "rt5190a-buck1";
- regulator-min-microvolt = <5090000>;
- regulator-max-microvolt = <5090000>;
- regulator-allowed-modes =
- <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
- regulator-boot-on;
- regulator-always-on;
- };
- buck2 {
- regulator-name = "vcore";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1400000>;
- regulator-boot-on;
- regulator-always-on;
- };
- rt5190_buck3: buck3 {
- regulator-name = "vproc";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1400000>;
- regulator-boot-on;
- };
- buck4 {
- regulator-name = "rt5190a-buck4";
- regulator-min-microvolt = <850000>;
- regulator-max-microvolt = <850000>;
- regulator-allowed-modes =
- <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
- regulator-boot-on;
- regulator-always-on;
- };
- ldo {
- regulator-name = "rt5190a-ldo";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- regulator-boot-on;
- regulator-always-on;
- };
- };
- };
-};
-
-&i2c2 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c2_1_pins>;
- status = "okay";
-
- pca9545: i2c-switch@70 {
- reg = <0x70>;
- compatible = "nxp,pca9545";
- reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>;
+&pca9545 {
+ i2c_sfp2: i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
-
- i2c_rtc: i2c@0 { //eeprom,rtc,ngff
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
-
- eeprom@50 {
- compatible = "atmel,24c02";
- reg = <0x50>;
- address-bits = <8>;
- page-size = <8>;
- size = <256>;
- };
-
- eeprom@57 {
- compatible = "atmel,24c02";
- reg = <0x57>;
- address-bits = <8>;
- page-size = <8>;
- size = <256>;
- };
-
- pcf8563: rtc@51 {
- compatible = "nxp,pcf8563";
- reg = <0x51>;
- status = "disabled";
- };
- };
-
- i2c_sfp1: i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- };
-
- i2c_sfp2: i2c@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <2>;
- };
-
- i2c_wifi: i2c@3 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
- };
- };
-};
-
-/* mPCIe SIM2 */
-&pcie0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie0_pins>;
- status = "okay";
-};
-
-/* mPCIe SIM3 */
-&pcie1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie1_pins>;
- status = "okay";
-};
-
-/* M.2 key-B SIM1 */
-&pcie2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie2_pins>;
- status = "okay";
-};
-
-/* M.2 key-M SSD */
-&pcie3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie3_pins>;
- status = "okay";
-};
-
-&ssusb1 {
- status = "okay";
-};
-
-&tphy {
- status = "okay";
-};
-
-&spi0 {
- pinctrl-names = "default";
- pinctrl-0 = <&spi0_flash_pins>;
- status = "okay";
-
- spi_nand: spi_nand@0 {
- compatible = "spi-nand";
- reg = <0>;
- spi-max-frequency = <52000000>;
- spi-tx-buswidth = <4>;
- spi-rx-buswidth = <4>;
- };
-};
-
-&spi_nand {
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "bl2";
- reg = <0x0 0x200000>;
- read-only;
- };
-
- partition@200000 {
- label = "ubi";
- reg = <0x200000 0x7e00000>;
- compatible = "linux,ubi";
-
- volumes {
- ubi-volume-ubootenv {
- volname = "ubootenv";
- nvmem-layout {
- compatible = "u-boot,env-redundant-bool-layout";
- };
- };
-
- ubi-volume-ubootenv2 {
- volname = "ubootenv2";
- nvmem-layout {
- compatible = "u-boot,env-redundant-bool-layout";
- };
- };
-
- ubi_rootfs: ubi-volume-fit {
- volname = "fit";
- };
- };
- };
+ reg = <2>;
};
};
-
-&uart0 {
- status = "okay";
-};
-
-&uart1 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&uart1_2_lite_pins>;
-};
-
-&uart2 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&uart2_3_pins>;
-};
-
-&watchdog {
- status = "okay";
-};
-
-&xphy {
- status = "okay";
-};
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7988a.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
+
+/ {
+ model = "Bananapi BPI-R4";
+ compatible = "bananapi,bpi-r4",
+ "mediatek,mt7988a";
+
+ aliases {
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
+ led-boot = &led_green;
+ led-failsafe = &led_green;
+ led-running = &led_green;
+ led-upgrade = &led_green;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = &uart0;
+ bootargs = "console=ttyS0,115200n1 loglevel=8 pci=pcie_bus_perf ubi.block=0,fit root=/dev/fit0 rootwait";
+ rootdisk-spim-nand = <&ubi_rootfs>;
+ };
+
+ memory {
+ reg = <0x00 0x40000000 0x00 0x10000000>;
+ };
+
+ /* SFP1 cage (WAN) */
+ sfp1: sfp1 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c_sfp1>;
+ los-gpios = <&pio 54 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>;
+ tx-disable-gpios = <&pio 70 GPIO_ACTIVE_HIGH>;
+ tx-fault-gpios = <&pio 69 GPIO_ACTIVE_HIGH>;
+ rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>;
+ maximum-power-milliwatt = <3000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ wps {
+ label = "WPS";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 14 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led_green: led-green {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 79 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+
+ led_blue: led-blue {
+ function = LED_FUNCTION_WPS;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&pio 63 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+};
+
+ð {
+ status = "okay";
+};
+
+&gmac0 {
+ status = "okay";
+};
+
+&gmac2 {
+ sfp = <&sfp1>;
+ managed = "in-band-status";
+ phy-mode = "usxgmii";
+ status = "okay";
+};
+
+&switch {
+ status = "okay";
+};
+
+&gsw_phy0 {
+ pinctrl-names = "gbe-led";
+ pinctrl-0 = <&gbe0_led0_pins>;
+};
+
+&gsw_port0 {
+ label = "wan";
+};
+
+&gsw_phy0_led0 {
+ status = "okay";
+ color = <LED_COLOR_ID_GREEN>;
+};
+
+&gsw_phy1 {
+ pinctrl-names = "gbe-led";
+ pinctrl-0 = <&gbe1_led0_pins>;
+};
+
+&gsw_phy1_led0 {
+ status = "okay";
+ color = <LED_COLOR_ID_GREEN>;
+};
+
+&gsw_phy2 {
+ pinctrl-names = "gbe-led";
+ pinctrl-0 = <&gbe2_led0_pins>;
+};
+
+&gsw_phy2_led0 {
+ status = "okay";
+ color = <LED_COLOR_ID_GREEN>;
+};
+
+&gsw_phy3 {
+ pinctrl-names = "gbe-led";
+ pinctrl-0 = <&gbe3_led0_pins>;
+};
+
+&gsw_phy3_led0 {
+ status = "okay";
+ color = <LED_COLOR_ID_GREEN>;
+};
+
+&cpu0 {
+ proc-supply = <&rt5190_buck3>;
+};
+
+&cpu1 {
+ proc-supply = <&rt5190_buck3>;
+};
+
+&cpu2 {
+ proc-supply = <&rt5190_buck3>;
+};
+
+&cpu3 {
+ proc-supply = <&rt5190_buck3>;
+};
+
+&cci {
+ proc-supply = <&rt5190_buck3>;
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+
+ rt5190a_64: rt5190a@64 {
+ compatible = "richtek,rt5190a";
+ reg = <0x64>;
+ vin2-supply = <&rt5190_buck1>;
+ vin3-supply = <&rt5190_buck1>;
+ vin4-supply = <&rt5190_buck1>;
+
+ regulators {
+ rt5190_buck1: buck1 {
+ regulator-name = "rt5190a-buck1";
+ regulator-min-microvolt = <5090000>;
+ regulator-max-microvolt = <5090000>;
+ regulator-allowed-modes =
+ <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ buck2 {
+ regulator-name = "vcore";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ rt5190_buck3: buck3 {
+ regulator-name = "vproc";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ };
+ buck4 {
+ regulator-name = "rt5190a-buck4";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-allowed-modes =
+ <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ ldo {
+ regulator-name = "rt5190a-ldo";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_1_pins>;
+ status = "okay";
+
+ pca9545: i2c-switch@70 {
+ reg = <0x70>;
+ compatible = "nxp,pca9545";
+ reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c_rtc: i2c@0 { //eeprom,rtc,ngff
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ address-bits = <8>;
+ page-size = <8>;
+ size = <256>;
+ };
+
+ eeprom@57 {
+ compatible = "atmel,24c02";
+ reg = <0x57>;
+ address-bits = <8>;
+ page-size = <8>;
+ size = <256>;
+ };
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ status = "disabled";
+ };
+ };
+
+ i2c_sfp1: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ i2c_wifi: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ };
+ };
+};
+
+/* mPCIe SIM2 */
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_pins>;
+ status = "okay";
+};
+
+/* mPCIe SIM3 */
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_pins>;
+ status = "okay";
+};
+
+/* M.2 key-B SIM1 */
+&pcie2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_pins>;
+ status = "okay";
+};
+
+/* M.2 key-M SSD */
+&pcie3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_pins>;
+ status = "okay";
+};
+
+&pwm {
+ status = "okay";
+};
+
+&fan {
+ pwms = <&pwm 0 50000>;
+ status = "okay";
+};
+
+&ssusb1 {
+ status = "okay";
+};
+
+&tphy {
+ status = "okay";
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_flash_pins>;
+ status = "okay";
+
+ spi_nand: spi_nand@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ spi-tx-buswidth = <4>;
+ spi-rx-buswidth = <4>;
+ };
+};
+
+&spi_nand {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bl2";
+ reg = <0x0 0x200000>;
+ read-only;
+ };
+
+ partition@200000 {
+ label = "ubi";
+ reg = <0x200000 0x7e00000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi-volume-ubootenv {
+ volname = "ubootenv";
+ nvmem-layout {
+ compatible = "u-boot,env-redundant-bool-layout";
+ };
+ };
+
+ ubi-volume-ubootenv2 {
+ volname = "ubootenv2";
+ nvmem-layout {
+ compatible = "u-boot,env-redundant-bool-layout";
+ };
+ };
+
+ ubi_rootfs: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_2_lite_pins>;
+};
+
+&uart2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_3_pins>;
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&xphy {
+ status = "okay";
+};
fan: pwm-fan {
compatible = "pwm-fan";
- /* cooling level (0, 1, 2) : (0% duty, 50% duty, 100% duty) */
- cooling-levels = <0 128 255>;
+ /* cooling level (0, 1, 2, 3) : (0% duty, 30% duty, 50% duty, 100% duty) */
+ cooling-levels = <0 80 128 255>;
#cooling-cells = <2>;
#thermal-sensor-cells = <1>;
status = "disabled";
pmu {
compatible = "arm,cortex-a73-pmu";
interrupt-parent = <&gic>;
- interrupt = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
};
psci {
gsw_phy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0>;
+ interrupts = <0>;
phy-mode = "internal";
nvmem-cells = <&phy_calibration_p0>;
nvmem-cell-names = "phy-cal-data";
gsw_phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
+ interrupts = <1>;
phy-mode = "internal";
nvmem-cells = <&phy_calibration_p1>;
nvmem-cell-names = "phy-cal-data";
gsw_phy2: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <2>;
+ interrupts = <2>;
phy-mode = "internal";
nvmem-cells = <&phy_calibration_p2>;
nvmem-cell-names = "phy-cal-data";
gsw_phy3: ethernet-phy@3 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <3>;
+ interrupts = <3>;
phy-mode = "internal";
nvmem-cells = <&phy_calibration_p3>;
nvmem-cell-names = "phy-cal-data";
}
/* 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 |
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
-#include <linux/version.h>
/**
* Driver for SmartRG RGBW LED microcontroller.
static int
-#if LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0)
-srg_led_probe(struct i2c_client *client, const struct i2c_device_id *id)
-#else
srg_led_probe(struct i2c_client *client)
-#endif
{
struct device_node *np = client->dev.of_node, *child;
struct srg_led_ctrl *sysled_ctrl;
srg_led_i2c_write(sysled_ctrl, i, 0);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
static void
-#else
-static int
-#endif
srg_led_remove(struct i2c_client *client)
{
struct srg_led_ctrl *sysled_ctrl = i2c_get_clientdata(client);
srg_led_disable(client);
mutex_destroy(&sysled_ctrl->lock);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5,16,0)
- return 0;
-#endif
}
static const struct i2c_device_id srg_led_id[] = {
ucidef_set_led_netdev "wlan2g" "WLAN2G" "blue:wlan-1" "phy0-ap0"
ucidef_set_led_netdev "wlan5g" "WLAN5G" "blue:wlan-2" "phy1-ap0"
;;
-bananapi,bpi-r4)
+bananapi,bpi-r4|\
+bananapi,bpi-r4-poe)
ucidef_set_led_netdev "wan" "wan" "mt7530-0:00:green:lan" "wan" "link tx rx"
ucidef_set_led_netdev "lan1" "lan1" "mt7530-0:01:green:lan" "lan1" "link tx rx"
ucidef_set_led_netdev "lan2" "lan2" "mt7530-0:02:green:lan" "lan2" "link tx rx"
edgecore,eap111)
ucidef_set_interfaces_lan_wan eth0 eth1
;;
- bananapi,bpi-r4)
+ bananapi,bpi-r4|\
+ bananapi,bpi-r4-poe)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 eth1" "wan eth2"
;;
cmcc,rax3000m|\
comfast,cf-e393ax)
ucidef_set_interfaces_lan_wan "lan1" eth1
;;
- dlink,aquila-pro-ai-m30-a1)
- ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" internet
- ;;
+ cudy,m3000-v1|\
+ cudy,tr3000-v1|\
glinet,gl-mt2500|\
glinet,gl-mt3000|\
glinet,gl-x3000|\
openembed,som7981)
ucidef_set_interfaces_lan_wan eth1 eth0
;;
+ dlink,aquila-pro-ai-m30-a1)
+ ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" internet
+ ;;
glinet,gl-mt6000|\
tplink,tl-xdr4288|\
tplink,tl-xdr6088)
;;
esac
;;
+ cudy,m3000-v1)
+ wan_mac=$(macaddr_add $(cat /sys/class/net/eth1/address) 1)
+ ;;
h3c,magic-nx30-pro)
wan_mac=$(mtd_get_mac_ascii pdt_data_1 ethaddr)
lan_mac=$(macaddr_add "$wan_mac" 1)
[ "$PHYNBR" = "0" ] && macaddr_add $addr 2 > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_add $addr 3 > /sys${DEVPATH}/macaddress
;;
- bananapi,bpi-r4)
+ bananapi,bpi-r4|\
+ bananapi,bpi-r4-poe)
addr=$(cat /sys/class/net/eth0/address)
[ "$PHYNBR" = "0" ] && macaddr_add $addr 2 > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_add $addr 3 > /sys${DEVPATH}/macaddress
addr=$(mtd_get_mac_binary "Factory" 0x8000)
[ "$PHYNBR" = "1" ] && macaddr_add $addr 1 > /sys${DEVPATH}/macaddress
;;
+ cudy,tr3000-v1|\
cudy,re3000-v1)
addr=$(mtd_get_mac_binary bdinfo 0xde00)
[ "$PHYNBR" = "0" ] && echo "$addr" > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_setbit_la $(macaddr_add $addr 1) > /sys${DEVPATH}/macaddress
;;
+ cudy,m3000-v1|\
cudy,wr3000-v1)
addr=$(mtd_get_mac_binary bdinfo 0xde00)
# Originally, phy0 is phy1 mac with LA bit set. However, this would conflict
bananapi,bpi-r3|\
bananapi,bpi-r3-mini|\
bananapi,bpi-r4|\
+ bananapi,bpi-r4-poe|\
+ jdcloud,re-cp-03|\
tplink,tl-xdr4288|\
tplink,tl-xdr6086|\
tplink,tl-xdr6088|\
CI_KERNPART="fit"
nand_do_upgrade "$1"
;;
- jdcloud,re-cp-03)
- CI_KERNPART="production"
- emmc_do_upgrade "$1"
- ;;
mercusys,mr90x-v1)
CI_UBIPART="ubi0"
nand_do_upgrade "$1"
case "$board" in
bananapi,bpi-r3|\
bananapi,bpi-r4|\
+ bananapi,bpi-r4-poe|\
cmcc,rax3000m)
[ "$magic" != "d00dfeed" ] && {
echo "Invalid image type."
;;
bananapi,bpi-r3|\
bananapi,bpi-r3-mini|\
- bananapi,bpi-r4)
+ bananapi,bpi-r4|\
+ bananapi,bpi-r4-poe)
case "$(fitblk_get_bootdev)" in
mmcblk*)
emmc_copy_config
+++ /dev/null
-CONFIG_64BIT=y
-# CONFIG_AHCI_MTK is not set
-CONFIG_AIROHA_EN8801SC_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_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MEDIATEK=y
-CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
-CONFIG_ARCH_MMAP_RND_BITS=18
-CONFIG_ARCH_MMAP_RND_BITS_MAX=24
-CONFIG_ARCH_MMAP_RND_BITS_MIN=18
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
-CONFIG_ARCH_NR_GPIO=0
-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_ERRATUM_843419=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_TAGGED_ADDR_ABI=y
-CONFIG_ARM64_VA_BITS=39
-CONFIG_ARM64_VA_BITS_39=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GIC_V2M=y
-CONFIG_ARM_GIC_V3=y
-CONFIG_ARM_GIC_V3_ITS=y
-CONFIG_ARM_GIC_V3_ITS_PCI=y
-CONFIG_ARM_MEDIATEK_CPUFREQ=y
-CONFIG_ARM_PMU=y
-CONFIG_ARM_PSCI_FW=y
-CONFIG_ATA=y
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_NVMEM=y
-CONFIG_BLK_PM=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=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_CLKSRC_MMIO=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE_OVERRIDE=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_MEDIATEK=y
-# CONFIG_COMMON_CLK_MT2712 is not set
-# CONFIG_COMMON_CLK_MT6779 is not set
-# CONFIG_COMMON_CLK_MT6795 is not set
-# CONFIG_COMMON_CLK_MT6797 is not set
-# CONFIG_COMMON_CLK_MT7622 is not set
-CONFIG_COMMON_CLK_MT7981=y
-CONFIG_COMMON_CLK_MT7981_ETHSYS=y
-CONFIG_COMMON_CLK_MT7986=y
-CONFIG_COMMON_CLK_MT7986_ETHSYS=y
-CONFIG_COMMON_CLK_MT7988=y
-# CONFIG_COMMON_CLK_MT8173 is not set
-# CONFIG_COMMON_CLK_MT8183 is not set
-# CONFIG_COMMON_CLK_MT8186 is not set
-# CONFIG_COMMON_CLK_MT8195 is not set
-# CONFIG_COMMON_CLK_MT8365 is not set
-# CONFIG_COMMON_CLK_MT8516 is not set
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-# CONFIG_COMPAT_32BIT_TIME is not set
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-# CONFIG_CPUFREQ_DT is not set
-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_SCHEDUTIL=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CRC16=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRYPTO_AES_ARM64=y
-CONFIG_CRYPTO_AES_ARM64_CE=y
-CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
-CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
-CONFIG_CRYPTO_CMAC=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ECC=y
-CONFIG_CRYPTO_ECDH=y
-CONFIG_CRYPTO_GHASH_ARM64_CE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_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_SHA256_ARM64=y
-CONFIG_CRYPTO_SHA2_ARM64_CE=y
-CONFIG_CRYPTO_SHA3=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_MISC=y
-CONFIG_DIMLIB=y
-CONFIG_DMADEVICES=y
-CONFIG_DMATEST=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_ENGINE_RAID=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DTC=y
-CONFIG_EDAC_SUPPORT=y
-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
-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_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=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_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IOREMAP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_PINCTRL_GROUPS=y
-CONFIG_GENERIC_PINMUX_FUNCTIONS=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GLOB=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_WATCHDOG=y
-CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=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_MTK=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MT65XX=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_TIME_ACCOUNTING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_JUMP_LABEL=y
-CONFIG_LEDS_SMARTRG_LED=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MAXLINEAR_GPHY=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEDIATEK_2P5G_PHY=y
-CONFIG_MEDIATEK_GE_PHY=y
-CONFIG_MEDIATEK_GE_SOC_PHY=y
-CONFIG_MEDIATEK_WATCHDOG=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_CQHCI=y
-CONFIG_MMC_MTK=y
-CONFIG_MODULES_TREE_LOOKUP=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_MEDIATEK=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_MTK=y
-CONFIG_MTD_NAND_MTK_BMT=y
-CONFIG_MTD_PARSER_TRX=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_FIT_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_FASTMAP=y
-CONFIG_MTD_UBI_NVMEM=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-# CONFIG_MTK_CMDQ is not set
-# CONFIG_MTK_CQDMA is not set
-CONFIG_MTK_HSDMA=y
-CONFIG_MTK_INFRACFG=y
-CONFIG_MTK_PMIC_WRAP=y
-CONFIG_MTK_SCPSYS=y
-CONFIG_MTK_SCPSYS_PM_DOMAINS=y
-# CONFIG_MTK_SVS is not set
-CONFIG_MTK_THERMAL=y
-CONFIG_MTK_SOC_THERMAL=y
-CONFIG_MTK_LVTS_THERMAL=y
-CONFIG_MTK_LVTS_THERMAL_DEBUGFS=y
-CONFIG_MTK_TIMER=y
-# CONFIG_MTK_UART_APDMA is not set
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MT7530=y
-CONFIG_NET_DSA_MT7530_MDIO=y
-CONFIG_NET_DSA_MT7530_MMIO=y
-CONFIG_NET_DSA_TAG_MTK=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_MEDIATEK_SOC=y
-CONFIG_NET_MEDIATEK_SOC_WED=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NET_VENDOR_MEDIATEK=y
-CONFIG_NLS=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_NVMEM_MTK_EFUSE=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_DYNAMIC=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_OVERLAY=y
-CONFIG_OF_RESOLVE=y
-CONFIG_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_POOL_STATS=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PARTITION_PERCPU=y
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEASPM=y
-# CONFIG_PCIEASPM_DEFAULT is not set
-CONFIG_PCIEASPM_PERFORMANCE=y
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-CONFIG_PCIEPORTBUS=y
-# CONFIG_PCIE_MEDIATEK is not set
-CONFIG_PCIE_MEDIATEK_GEN3=y
-CONFIG_PCIE_PME=y
-CONFIG_PCI_DEBUG=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCS_MTK_LYNXI=y
-CONFIG_PCS_MTK_USXGMII=y
-CONFIG_PERF_EVENTS=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-# CONFIG_PHY_MTK_DP is not set
-# CONFIG_PHY_MTK_PCIE is not set
-CONFIG_PHY_MTK_TPHY=y
-# CONFIG_PHY_MTK_UFS is not set
-CONFIG_PHY_MTK_XFI_TPHY=y
-CONFIG_PHY_MTK_XSPHY=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_MT2712 is not set
-# CONFIG_PINCTRL_MT6765 is not set
-# CONFIG_PINCTRL_MT6795 is not set
-# CONFIG_PINCTRL_MT6797 is not set
-# CONFIG_PINCTRL_MT7622 is not set
-CONFIG_PINCTRL_MT7981=y
-CONFIG_PINCTRL_MT7986=y
-CONFIG_PINCTRL_MT7988=y
-# CONFIG_PINCTRL_MT8173 is not set
-# CONFIG_PINCTRL_MT8183 is not set
-# CONFIG_PINCTRL_MT8186 is not set
-# CONFIG_PINCTRL_MT8188 is not set
-# CONFIG_PINCTRL_MT8516 is not set
-CONFIG_PINCTRL_MTK_MOORE=y
-CONFIG_PINCTRL_MTK_V2=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_PM_OPP=y
-CONFIG_POLYNOMIAL=y
-CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PRINTK_TIME=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_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_MEDIATEK=y
-# CONFIG_PWM_MTK_DISP is not set
-CONFIG_PWM_SYSFS=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_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_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_MT6380=y
-CONFIG_REGULATOR_RT5190A=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_TI_SYSCON=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_MT7622=y
-CONFIG_RTC_I2C_AND_SPI=y
-# CONFIG_RTL8367S_GSW is not set
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCHED_MC=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_MT6577=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-CONFIG_SERIAL_DEV_BUS=y
-CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_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_DYNAMIC=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_MT65XX=y
-# CONFIG_SPI_MTK_NOR is not set
-CONFIG_SPI_MTK_SNFI=y
-# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set
-CONFIG_SQUASHFS_DECOMP_SINGLE=y
-CONFIG_SRCU=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_BANG_BANG=y
-CONFIG_THERMAL_GOV_FAIR_SHARE=y
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_GOV_USER_SPACE=y
-CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_OF=y
-CONFIG_THERMAL_WRITABLE_TRIPS=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-# CONFIG_UCLAMP_TASK is not set
-CONFIG_UIMAGE_FIT_BLK=y
-# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_VMAP_STACK=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y
-CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
-# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set
-CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y
-CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m
-CONFIG_WATCHDOG_SYSFS=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
endef
TARGET_DEVICES += bananapi_bpi-r3-mini
-define Device/bananapi_bpi-r4
+define Device/bananapi_bpi-r4-common
DEVICE_VENDOR := Bananapi
- DEVICE_MODEL := BPi-R4
- DEVICE_DTS := mt7988a-bananapi-bpi-r4
- DEVICE_DTS_CONFIG := config-mt7988a-bananapi-bpi-r4
DEVICE_DTS_DIR := $(DTS_DIR)/
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
sdcard.img.gz \
snand-preloader.bin snand-bl31-uboot.fip
ARTIFACT/emmc-preloader.bin := mt7988-bl2 emmc-comb
- ARTIFACT/emmc-bl31-uboot.fip := mt7988-bl31-uboot bananapi_bpi-r4-emmc
+ ARTIFACT/emmc-bl31-uboot.fip := mt7988-bl31-uboot $$(DEVICE_NAME)-emmc
ARTIFACT/snand-preloader.bin := mt7988-bl2 spim-nand-ubi-comb
- ARTIFACT/snand-bl31-uboot.fip := mt7988-bl31-uboot bananapi_bpi-r4-snand
+ ARTIFACT/snand-bl31-uboot.fip := mt7988-bl31-uboot $$(DEVICE_NAME)-snand
ARTIFACT/sdcard.img.gz := mt798x-gpt sdmmc |\
pad-to 17k | mt7988-bl2 sdmmc-comb |\
- pad-to 6656k | mt7988-bl31-uboot bananapi_bpi-r4-sdmmc |\
+ pad-to 6656k | mt7988-bl31-uboot $$(DEVICE_NAME)-sdmmc |\
$(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),\
pad-to 12M | append-image-stage initramfs-recovery.itb | check-size 44m |\
) \
pad-to 44M | mt7988-bl2 spim-nand-ubi-comb |\
- pad-to 45M | mt7988-bl31-uboot bananapi_bpi-r4-snand |\
+ pad-to 45M | mt7988-bl31-uboot $$(DEVICE_NAME)-snand |\
pad-to 51M | mt7988-bl2 emmc-comb |\
- pad-to 52M | mt7988-bl31-uboot bananapi_bpi-r4-emmc |\
+ pad-to 52M | mt7988-bl31-uboot $$(DEVICE_NAME)-emmc |\
pad-to 56M | mt798x-gpt emmc |\
$(if $(CONFIG_TARGET_ROOTFS_SQUASHFS),\
pad-to 64M | append-image squashfs-sysupgrade.itb | check-size |\
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-with-rootfs | pad-rootfs | append-metadata
endef
+
+define Device/bananapi_bpi-r4
+ DEVICE_MODEL := BPi-R4
+ DEVICE_DTS := mt7988a-bananapi-bpi-r4
+ DEVICE_DTS_CONFIG := config-mt7988a-bananapi-bpi-r4
+ $(call Device/bananapi_bpi-r4-common)
+endef
TARGET_DEVICES += bananapi_bpi-r4
+define Device/bananapi_bpi-r4-poe
+ DEVICE_MODEL := BPi-R4 2.5GE
+ DEVICE_DTS := mt7988a-bananapi-bpi-r4-poe
+ DEVICE_DTS_CONFIG := config-mt7988a-bananapi-bpi-r4-poe
+ $(call Device/bananapi_bpi-r4-common)
+ DEVICE_PACKAGES += mt7988-2p5g-phy-firmware
+endef
+TARGET_DEVICES += bananapi_bpi-r4-poe
+
define Device/cetron_ct3003
DEVICE_VENDOR := Cetron
DEVICE_MODEL := CT3003
endef
TARGET_DEVICES += confiabits_mt7981
+define Device/cudy_m3000-v1
+ DEVICE_VENDOR := Cudy
+ DEVICE_MODEL := M3000
+ DEVICE_VARIANT := v1
+ DEVICE_DTS := mt7981b-cudy-m3000-v1
+ DEVICE_DTS_DIR := ../dts
+ SUPPORTED_DEVICES += R37
+ DEVICE_DTS_LOADADDR := 0x44000000
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ IMAGE_SIZE := 65536k
+ KERNEL_IN_UBI := 1
+ KERNEL := kernel-bin | lzma | \
+ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
+ KERNEL_INITRAMFS := kernel-bin | lzma | \
+ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | pad-to 64k
+ IMAGES := sysupgrade.bin
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+ DEVICE_PACKAGES := kmod-mt7981-firmware mt7981-wo-firmware
+endef
+TARGET_DEVICES += cudy_m3000-v1
+
define Device/cudy_re3000-v1
DEVICE_VENDOR := Cudy
DEVICE_MODEL := RE3000
endef
TARGET_DEVICES += cudy_re3000-v1
+define Device/cudy_tr3000-v1
+ DEVICE_VENDOR := Cudy
+ DEVICE_MODEL := TR3000
+ DEVICE_VARIANT := v1
+ DEVICE_DTS := mt7981b-cudy-tr3000-v1
+ DEVICE_DTS_DIR := ../dts
+ SUPPORTED_DEVICES += R47
+ 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-usb3 kmod-mt7981-firmware mt7981-wo-firmware
+endef
+TARGET_DEVICES += cudy_tr3000-v1
+
define Device/cudy_wr3000-v1
DEVICE_VENDOR := Cudy
DEVICE_MODEL := WR3000
+++ /dev/null
-CONFIG_64BIT=y
-# CONFIG_AHCI_MTK is not set
-# CONFIG_AIROHA_EN8801SC_PHY is not set
-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_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MEDIATEK=y
-CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
-CONFIG_ARCH_MMAP_RND_BITS=18
-CONFIG_ARCH_MMAP_RND_BITS_MAX=24
-CONFIG_ARCH_MMAP_RND_BITS_MIN=18
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
-CONFIG_ARCH_NR_GPIO=0
-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_ERRATUM_843419=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_TAGGED_ADDR_ABI=y
-CONFIG_ARM64_VA_BITS=39
-CONFIG_ARM64_VA_BITS_39=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GIC_V2M=y
-CONFIG_ARM_GIC_V3=y
-CONFIG_ARM_GIC_V3_ITS=y
-CONFIG_ARM_GIC_V3_ITS_PCI=y
-CONFIG_ARM_MEDIATEK_CPUFREQ=y
-CONFIG_ARM_PMU=y
-CONFIG_ARM_PSCI_FW=y
-CONFIG_ATA=y
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_PM=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=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_CLKSRC_MMIO=y
-CONFIG_CLONE_BACKWARDS=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_MEDIATEK=y
-CONFIG_COMMON_CLK_MT2712=y
-# CONFIG_COMMON_CLK_MT2712_BDPSYS is not set
-# CONFIG_COMMON_CLK_MT2712_IMGSYS is not set
-# CONFIG_COMMON_CLK_MT2712_JPGDECSYS is not set
-# CONFIG_COMMON_CLK_MT2712_MFGCFG is not set
-# CONFIG_COMMON_CLK_MT2712_MMSYS is not set
-# CONFIG_COMMON_CLK_MT2712_VDECSYS is not set
-# CONFIG_COMMON_CLK_MT2712_VENCSYS is not set
-# CONFIG_COMMON_CLK_MT6779 is not set
-# CONFIG_COMMON_CLK_MT6795 is not set
-# CONFIG_COMMON_CLK_MT6797 is not set
-CONFIG_COMMON_CLK_MT7622=y
-CONFIG_COMMON_CLK_MT7622_AUDSYS=y
-CONFIG_COMMON_CLK_MT7622_ETHSYS=y
-CONFIG_COMMON_CLK_MT7622_HIFSYS=y
-# CONFIG_COMMON_CLK_MT7981 is not set
-# CONFIG_COMMON_CLK_MT7986 is not set
-# CONFIG_COMMON_CLK_MT7988 is not set
-# CONFIG_COMMON_CLK_MT8173 is not set
-# CONFIG_COMMON_CLK_MT8183 is not set
-# CONFIG_COMMON_CLK_MT8186 is not set
-# CONFIG_COMMON_CLK_MT8195 is not set
-# CONFIG_COMMON_CLK_MT8365 is not set
-# CONFIG_COMMON_CLK_MT8516 is not set
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-# CONFIG_CPUFREQ_DT is not set
-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=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CRC16=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRYPTO_AES_ARM64=y
-CONFIG_CRYPTO_AES_ARM64_CE=y
-CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
-CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
-CONFIG_CRYPTO_CMAC=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ECC=y
-CONFIG_CRYPTO_ECDH=y
-CONFIG_CRYPTO_GHASH_ARM64_CE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_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_SHA256_ARM64=y
-CONFIG_CRYPTO_SHA2_ARM64_CE=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_MISC=y
-CONFIG_DIMLIB=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_EDAC_SUPPORT=y
-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
-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_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=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_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IOREMAP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_PINCTRL_GROUPS=y
-CONFIG_GENERIC_PINMUX_FUNCTIONS=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GLOB=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_MTK=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MT65XX=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_TIME_ACCOUNTING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_JUMP_LABEL=y
-# CONFIG_LEDS_SMARTRG_LED 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_MAGIC_SYSRQ=y
-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_GE_PHY=y
-# CONFIG_MEDIATEK_GE_SOC_PHY is not set
-CONFIG_MEDIATEK_WATCHDOG=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_CQHCI=y
-CONFIG_MMC_MTK=y
-CONFIG_MODULES_TREE_LOOKUP=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_MEDIATEK=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_MTK=y
-CONFIG_MTD_NAND_MTK_BMT=y
-CONFIG_MTD_PARSER_TRX=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_FIT_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_FASTMAP=y
-CONFIG_MTD_UBI_NVMEM=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-# CONFIG_MTK_CMDQ is not set
-# CONFIG_MTK_CQDMA is not set
-CONFIG_MTK_HSDMA=y
-CONFIG_MTK_INFRACFG=y
-CONFIG_MTK_PMIC_WRAP=y
-CONFIG_MTK_SCPSYS=y
-CONFIG_MTK_SCPSYS_PM_DOMAINS=y
-# CONFIG_MTK_SVS is not set
-CONFIG_MTK_THERMAL=y
-CONFIG_MTK_SOC_THERMAL=y
-# CONFIG_MTK_LVTS_THERMAL is not set
-CONFIG_MTK_TIMER=y
-# CONFIG_MTK_UART_APDMA is not set
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MT7530=y
-CONFIG_NET_DSA_MT7530_MDIO=y
-# CONFIG_NET_DSA_MT7530_MMIO is not set
-CONFIG_NET_DSA_TAG_MTK=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_MEDIATEK_SOC=y
-# CONFIG_NET_MEDIATEK_SOC_USXGMII is not set
-CONFIG_NET_MEDIATEK_SOC_WED=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NET_VENDOR_MEDIATEK=y
-CONFIG_NLS=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=2
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_NVMEM_MTK_EFUSE=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_DYNAMIC=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_OVERLAY=y
-CONFIG_OF_RESOLVE=y
-CONFIG_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_POOL_STATS=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PARTITION_PERCPU=y
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEASPM=y
-# CONFIG_PCIEASPM_DEFAULT is not set
-CONFIG_PCIEASPM_PERFORMANCE=y
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_MEDIATEK=y
-CONFIG_PCIE_PME=y
-CONFIG_PCI_DEBUG=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCS_MTK_LYNXI=y
-CONFIG_PERF_EVENTS=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-# CONFIG_PHY_MTK_DP is not set
-# CONFIG_PHY_MTK_PCIE is not set
-CONFIG_PHY_MTK_TPHY=y
-# CONFIG_PHY_MTK_UFS is not set
-# CONFIG_PHY_MTK_XSPHY is not set
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_MT2712 is not set
-# CONFIG_PINCTRL_MT6765 is not set
-# CONFIG_PINCTRL_MT6795 is not set
-# CONFIG_PINCTRL_MT6797 is not set
-CONFIG_PINCTRL_MT7622=y
-# CONFIG_PINCTRL_MT7981 is not set
-# CONFIG_PINCTRL_MT7986 is not set
-# CONFIG_PINCTRL_MT7988 is not set
-# CONFIG_PINCTRL_MT8173 is not set
-# CONFIG_PINCTRL_MT8183 is not set
-# CONFIG_PINCTRL_MT8186 is not set
-# CONFIG_PINCTRL_MT8188 is not set
-# CONFIG_PINCTRL_MT8516 is not set
-CONFIG_PINCTRL_MTK_MOORE=y
-CONFIG_PINCTRL_MTK_V2=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_GENERIC_DOMAINS=y
-CONFIG_PM_GENERIC_DOMAINS_OF=y
-CONFIG_PM_OPP=y
-CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PRINTK_TIME=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_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_MEDIATEK=y
-# CONFIG_PWM_MTK_DISP is not set
-CONFIG_PWM_SYSFS=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_REALTEK_PHY=y
-CONFIG_REED_SOLOMON=y
-CONFIG_REED_SOLOMON_DEC8=y
-CONFIG_REED_SOLOMON_ENC8=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_MT6380=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_MT7622=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTL8367S_GSW=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCHED_MC=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_MT6577=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-CONFIG_SERIAL_DEV_BUS=y
-CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_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_DYNAMIC=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_MT65XX=y
-CONFIG_SPI_MTK_NOR=y
-CONFIG_SPI_MTK_SNFI=y
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_EMULATION=y
-CONFIG_THERMAL_GOV_BANG_BANG=y
-CONFIG_THERMAL_GOV_FAIR_SHARE=y
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_GOV_USER_SPACE=y
-CONFIG_THERMAL_OF=y
-CONFIG_THERMAL_WRITABLE_TRIPS=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-# CONFIG_UCLAMP_TASK is not set
-CONFIG_UIMAGE_FIT_BLK=y
-# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_VMAP_STACK=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y
-CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
-# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set
-CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y
-CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m
-CONFIG_WATCHDOG_SYSFS=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
+++ /dev/null
-# CONFIG_AIO is not set
-# CONFIG_AIROHA_EN8801SC_PHY is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_FORCE_MAX_ORDER=11
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MEDIATEK=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_APPENDED_DTB=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-CONFIG_ARM_CPU_SUSPEND=y
-# CONFIG_ARM_CPU_TOPOLOGY is not set
-CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8
-CONFIG_ARM_DMA_USE_IOMMU=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_MEDIATEK_CCI_DEVFREQ is not set
-CONFIG_ARM_MEDIATEK_CPUFREQ=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=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_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_GPIO=y
-CONFIG_BACKLIGHT_LED=y
-CONFIG_BACKLIGHT_PWM=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_PM=y
-CONFIG_BOUNCE=y
-# CONFIG_CACHE_L2X0 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_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_CMDLINE_PARTITION=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_MEDIATEK=y
-CONFIG_COMMON_CLK_MT2701=y
-CONFIG_COMMON_CLK_MT2701_AUDSYS=y
-CONFIG_COMMON_CLK_MT2701_BDPSYS=y
-CONFIG_COMMON_CLK_MT2701_ETHSYS=y
-CONFIG_COMMON_CLK_MT2701_G3DSYS=y
-CONFIG_COMMON_CLK_MT2701_HIFSYS=y
-CONFIG_COMMON_CLK_MT2701_IMGSYS=y
-CONFIG_COMMON_CLK_MT2701_MMSYS=y
-CONFIG_COMMON_CLK_MT2701_VDECSYS=y
-# CONFIG_COMMON_CLK_MT6795 is not set
-# CONFIG_COMMON_CLK_MT7622 is not set
-# CONFIG_COMMON_CLK_MT7629 is not set
-# CONFIG_COMMON_CLK_MT7981 is not set
-# CONFIG_COMMON_CLK_MT7986 is not set
-# CONFIG_COMMON_CLK_MT7988 is not set
-# CONFIG_COMMON_CLK_MT8135 is not set
-# CONFIG_COMMON_CLK_MT8173 is not set
-# CONFIG_COMMON_CLK_MT8365 is not set
-# CONFIG_COMMON_CLK_MT8516 is not set
-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_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=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 is not set
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_HAS_ASID=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_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_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_HW=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_SHA1=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_ALIGN_RODATA=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
-CONFIG_DEBUG_MISC=y
-CONFIG_DEBUG_MT6589_UART0=y
-# CONFIG_DEBUG_MT8127_UART0 is not set
-# CONFIG_DEBUG_MT8135_UART3 is not set
-CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_UART_8250=y
-CONFIG_DEBUG_UART_8250_SHIFT=2
-CONFIG_DEBUG_UART_PHYS=0x11004000
-CONFIG_DEBUG_UART_VIRT=0xf1004000
-# 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 is not set
-CONFIG_DIMLIB=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DRM=y
-CONFIG_DRM_BRIDGE=y
-CONFIG_DRM_DISPLAY_CONNECTOR=y
-CONFIG_DRM_FBDEV_EMULATION=y
-CONFIG_DRM_FBDEV_OVERALLOC=100
-CONFIG_DRM_GEM_DMA_HELPER=y
-CONFIG_DRM_GEM_SHMEM_HELPER=y
-CONFIG_DRM_KMS_HELPER=y
-CONFIG_DRM_LIMA=y
-CONFIG_DRM_LVDS_CODEC=y
-CONFIG_DRM_MEDIATEK=y
-# CONFIG_DRM_MEDIATEK_DP is not set
-CONFIG_DRM_MEDIATEK_HDMI=y
-CONFIG_DRM_MIPI_DSI=y
-CONFIG_DRM_NOMODESET=y
-CONFIG_DRM_PANEL=y
-CONFIG_DRM_PANEL_BRIDGE=y
-CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
-CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=y
-CONFIG_DRM_SCHED=y
-CONFIG_DRM_SIMPLE_BRIDGE=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EINT_MTK=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_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_FIT_PARTITION is not set
-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=y
-CONFIG_FRAME_WARN=1024
-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_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=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_GPIO_CDEV=y
-CONFIG_GRO_CELLS=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_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HWMON=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_MTK=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MT65XX=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_IIO=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INPUT_TOUCHSCREEN=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_IO_PGTABLE=y
-CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
-# CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST is not set
-# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
-CONFIG_IOMMU_SUPPORT=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_KALLSYMS=y
-CONFIG_KCMP=y
-# CONFIG_KEYBOARD_MT6779 is not set
-CONFIG_KEYBOARD_MTK_PMIC=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_LCD_PLATFORM=y
-CONFIG_LEDS_MT6323=y
-# CONFIG_LEDS_QCOM_LPG is not set
-# CONFIG_LEDS_SMARTRG_LED is not set
-CONFIG_LIBFDT=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_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-# CONFIG_MACH_MT2701 is not set
-# CONFIG_MACH_MT6589 is not set
-# CONFIG_MACH_MT6592 is not set
-CONFIG_MACH_MT7623=y
-# CONFIG_MACH_MT7629 is not set
-# CONFIG_MACH_MT8127 is not set
-# CONFIG_MACH_MT8135 is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MAILBOX=y
-# CONFIG_MAILBOX_TEST is not set
-CONFIG_MDIO_BITBANG=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MDIO_GPIO=y
-CONFIG_MEDIATEK_GE_PHY=y
-CONFIG_MEDIATEK_MT6577_AUXADC=y
-CONFIG_MEDIATEK_WATCHDOG=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MFD_CORE=y
-# CONFIG_MFD_HI6421_SPMI is not set
-CONFIG_MFD_MT6397=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_MTK=y
-CONFIG_MMC_SDHCI=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_NAND_ECC_MEDIATEK is not set
-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_MTK_ADSP_MBOX is not set
-CONFIG_MTK_CMDQ=y
-CONFIG_MTK_CMDQ_MBOX=y
-CONFIG_MTK_CQDMA=y
-# CONFIG_MTK_HSDMA is not set
-CONFIG_MTK_INFRACFG=y
-CONFIG_MTK_IOMMU=y
-CONFIG_MTK_IOMMU_V1=y
-CONFIG_MTK_MMSYS=y
-CONFIG_MTK_PMIC_WRAP=y
-CONFIG_MTK_SCPSYS=y
-CONFIG_MTK_SCPSYS_PM_DOMAINS=y
-CONFIG_MTK_SMI=y
-# CONFIG_MTK_SVS is not set
-CONFIG_MTK_THERMAL=y
-CONFIG_MTK_SOC_THERMAL=y
-# CONFIG_MTK_LVTS_THERMAL is not set
-CONFIG_MTK_TIMER=y
-# CONFIG_MTK_UART_APDMA is not set
-# CONFIG_MUSB_PIO_ONLY is not set
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NEON=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MT7530=y
-CONFIG_NET_DSA_MT7530_MDIO=y
-# CONFIG_NET_DSA_MT7530_MMIO is not set
-CONFIG_NET_DSA_TAG_MTK=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_MEDIATEK_SOC=y
-CONFIG_NET_MEDIATEK_SOC_WED=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NET_VENDOR_MEDIATEK=y
-# CONFIG_NET_VENDOR_WIZNET is not set
-CONFIG_NLS=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_MTK_EFUSE=y
-# 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_IOMMU=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_OVERLAY=y
-CONFIG_OF_RESOLVE=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_POOL_STATS=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_MEDIATEK=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_PCS_MTK_LYNXI=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_MTK_DP is not set
-CONFIG_PHY_MTK_HDMI=y
-CONFIG_PHY_MTK_MIPI_DSI=y
-# CONFIG_PHY_MTK_PCIE is not set
-CONFIG_PHY_MTK_TPHY=y
-# CONFIG_PHY_MTK_UFS is not set
-# CONFIG_PHY_MTK_XSPHY is not set
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_MT2701=y
-# CONFIG_PINCTRL_MT6397 is not set
-CONFIG_PINCTRL_MT7623=y
-CONFIG_PINCTRL_MTK=y
-CONFIG_PINCTRL_MTK_MOORE=y
-CONFIG_PINCTRL_MTK_V2=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_GENERIC_DOMAINS_SLEEP=y
-CONFIG_PM_OPP=y
-CONFIG_PM_SLEEP=y
-CONFIG_PM_SLEEP_SMP=y
-CONFIG_POWER_RESET=y
-# CONFIG_POWER_RESET_MT6323 is not set
-CONFIG_POWER_SUPPLY=y
-CONFIG_POWER_SUPPLY_HWMON=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_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_MEDIATEK=y
-# CONFIG_PWM_MTK_DISP is not set
-CONFIG_PWM_SYSFS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_GPIO=y
-CONFIG_REGULATOR_MT6323=y
-# CONFIG_REGULATOR_MT6331 is not set
-# CONFIG_REGULATOR_MT6332 is not set
-# CONFIG_REGULATOR_MT6358 is not set
-# CONFIG_REGULATOR_MT6380 is not set
-# CONFIG_REGULATOR_MT6397 is not set
-# CONFIG_REGULATOR_QCOM_LABIBB is not set
-# CONFIG_REGULATOR_QCOM_SPMI is not set
-# CONFIG_REGULATOR_QCOM_USB_VBUS is not set
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_MT6397 is not set
-# CONFIG_RTC_DRV_MT7622 is not set
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-# CONFIG_RTL8367S_GSW is not set
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-# CONFIG_SERIAL_8250_DMA is not set
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_MT6577=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-# CONFIG_SMP_ON_UP is not set
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_DYNAMIC=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_MT65XX=y
-# CONFIG_SPI_MTK_NOR is not set
-CONFIG_SPMI=y
-# CONFIG_SPMI_HISI3670 is not set
-# CONFIG_SPMI_MTK_PMIF is not set
-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_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_TOUCHSCREEN_EDT_FT5X06=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-# CONFIG_UACCE is not set
-CONFIG_UBIFS_FS=y
-CONFIG_UEVENT_HELPER_PATH=""
-CONFIG_UIMAGE_FIT_BLK=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_F_ACM=y
-CONFIG_USB_F_ECM=y
-CONFIG_USB_F_MASS_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GPIO_VBUS=y
-CONFIG_USB_G_MULTI=y
-CONFIG_USB_G_MULTI_CDC=y
-# CONFIG_USB_G_MULTI_RNDIS is not set
-CONFIG_USB_HID=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB_INVENTRA_DMA=y
-CONFIG_USB_LIBCOMPOSITE=y
-CONFIG_USB_MUSB_DUAL_ROLE=y
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_MEDIATEK=y
-CONFIG_USB_OTG=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_U_ETHER=y
-CONFIG_USB_U_SERIAL=y
-CONFIG_USE_OF=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VIDEOMODE_HELPERS=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_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=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
+++ /dev/null
-# CONFIG_AIROHA_EN8801SC_PHY is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_FORCE_MAX_ORDER=11
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MEDIATEK=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_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=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_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_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_PM=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=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_CC_OPTIMIZE_FOR_PERFORMANCE is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_CHR_DEV_SCH=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_CMDLINE_OVERRIDE=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_MEDIATEK=y
-# CONFIG_COMMON_CLK_MT2701 is not set
-# CONFIG_COMMON_CLK_MT6795 is not set
-# CONFIG_COMMON_CLK_MT7622 is not set
-CONFIG_COMMON_CLK_MT7629=y
-CONFIG_COMMON_CLK_MT7629_ETHSYS=y
-CONFIG_COMMON_CLK_MT7629_HIFSYS=y
-# CONFIG_COMMON_CLK_MT7981 is not set
-# CONFIG_COMMON_CLK_MT7986 is not set
-# CONFIG_COMMON_CLK_MT7988 is not set
-# CONFIG_COMMON_CLK_MT8135 is not set
-# CONFIG_COMMON_CLK_MT8173 is not set
-# CONFIG_COMMON_CLK_MT8365 is not set
-# CONFIG_COMMON_CLK_MT8516 is not set
-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_IDLE=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_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_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DEBUG_MISC=y
-CONFIG_DEFAULT_HOSTNAME="(mt7629)"
-CONFIG_DIMLIB=y
-CONFIG_DMA_OPS=y
-CONFIG_DTC=y
-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_FRAME_WARN=1024
-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_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_GPIO_CDEV=y
-CONFIG_GRO_CELLS=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_HOTPLUG_CPU=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_MTK=y
-CONFIG_HZ_FIXED=0
-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_TIME_ACCOUNTING=y
-CONFIG_IRQ_WORK=y
-# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
-CONFIG_LIBFDT=y
-# CONFIG_LEDS_SMARTRG_LED is not set
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-# CONFIG_MACH_MT2701 is not set
-# CONFIG_MACH_MT6589 is not set
-# CONFIG_MACH_MT6592 is not set
-# CONFIG_MACH_MT7623 is not set
-CONFIG_MACH_MT7629=y
-# CONFIG_MACH_MT8127 is not set
-# CONFIG_MACH_MT8135 is not set
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEDIATEK_GE_PHY=y
-CONFIG_MEDIATEK_WATCHDOG=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_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_MEDIATEK=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_MTK_BMT=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_FIT_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-# CONFIG_MTK_CMDQ is not set
-CONFIG_MTK_INFRACFG=y
-# CONFIG_MTK_PMIC_WRAP is not set
-CONFIG_MTK_SCPSYS=y
-CONFIG_MTK_SCPSYS_PM_DOMAINS=y
-CONFIG_MTK_TIMER=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NETFILTER=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MT7530=y
-CONFIG_NET_DSA_MT7530_MDIO=y
-# CONFIG_NET_DSA_MT7530_MMIO is not set
-CONFIG_NET_DSA_TAG_MTK=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_MEDIATEK_SOC=y
-CONFIG_NET_MEDIATEK_SOC_WED=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NET_VENDOR_MEDIATEK=y
-CONFIG_NLS=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=2
-CONFIG_NVMEM=y
-# CONFIG_NVMEM_MTK_EFUSE 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=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_POOL_STATS=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_MEDIATEK=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_PCS_MTK_LYNXI=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_MTK_DP is not set
-# CONFIG_PHY_MTK_PCIE is not set
-CONFIG_PHY_MTK_TPHY=y
-# CONFIG_PHY_MTK_UFS is not set
-# CONFIG_PHY_MTK_XSPHY is not set
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_MT7629=y
-CONFIG_PINCTRL_MTK_MOORE=y
-CONFIG_PINCTRL_MTK_V2=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_GENERIC_DOMAINS=y
-CONFIG_PM_GENERIC_DOMAINS_OF=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_MEDIATEK=y
-# CONFIG_PWM_MTK_DISP is not set
-CONFIG_PWM_SYSFS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-# CONFIG_RTL8367S_GSW is not set
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_MT6577=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=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_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_MT65XX=y
-CONFIG_SPI_MTK_NOR=y
-CONFIG_SPI_MTK_SNFI=y
-CONFIG_SRCU=y
-CONFIG_STACKTRACE=y
-# CONFIG_SWAP is not set
-CONFIG_SWCONFIG=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=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_TREE_RCU=y
-CONFIG_TREE_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_SUPPORT=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_MTK=y
-# CONFIG_USB_XHCI_PLATFORM is not set
-CONFIG_USE_OF=y
-# CONFIG_VFP is not set
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=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
+++ /dev/null
-From 363547d2191cbc32ca954ba75d72908712398ff2 Mon Sep 17 00:00:00 2001
-From: Andrew Davis <afd@ti.com>
-Date: Mon, 24 Oct 2022 12:34:28 -0500
-Subject: [PATCH] kbuild: Allow DTB overlays to built from .dtso named source
- files
-
-Currently DTB Overlays (.dtbo) are build from source files with the same
-extension (.dts) as the base DTs (.dtb). This may become confusing and
-even lead to wrong results. For example, a composite DTB (created from a
-base DTB and a set of overlays) might have the same name as one of the
-overlays that create it.
-
-Different files should be generated from differently named sources.
- .dtb <-> .dts
- .dtbo <-> .dtso
-
-We do not remove the ability to compile DTBO files from .dts files here,
-only add a new rule allowing the .dtso file name. The current .dts named
-overlays can be renamed with time. After all have been renamed we can
-remove the other rule.
-
-Signed-off-by: Andrew Davis <afd@ti.com>
-Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
-Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
-Reviewed-by: Frank Rowand <frowand.list@gmail.com>
-Tested-by: Frank Rowand <frowand.list@gmail.com>
-Link: https://lore.kernel.org/r/20221024173434.32518-2-afd@ti.com
-Signed-off-by: Rob Herring <robh@kernel.org>
----
- scripts/Makefile.lib | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/scripts/Makefile.lib
-+++ b/scripts/Makefile.lib
-@@ -408,6 +408,9 @@ $(obj)/%.dtb: $(src)/%.dts $(DTC) $(DT_T
- $(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE
- $(call if_changed_dep,dtc)
-
-+$(obj)/%.dtbo: $(src)/%.dtso $(DTC) FORCE
-+ $(call if_changed_dep,dtc)
-+
- dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
-
- # Bzip2
+++ /dev/null
-From 2c4daed9580164522859fa100128be408cc69be2 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 5 Nov 2022 23:36:16 +0100
-Subject: [PATCH 01/19] arm64: dts: mediatek: mt7986: add support for RX
- Wireless Ethernet Dispatch
-
-Similar to TX Wireless Ethernet Dispatch, introduce RX Wireless Ethernet
-Dispatch to offload traffic received by the wlan interface to lan/wan
-one.
-
-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>
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 65 +++++++++++++++++++++++
- 1 file changed, 65 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -76,6 +76,47 @@
- no-map;
- reg = <0 0x4fc00000 0 0x00100000>;
- };
-+
-+ wo_emi0: wo-emi@4fd00000 {
-+ reg = <0 0x4fd00000 0 0x40000>;
-+ no-map;
-+ };
-+
-+ wo_emi1: wo-emi@4fd40000 {
-+ reg = <0 0x4fd40000 0 0x40000>;
-+ no-map;
-+ };
-+
-+ wo_ilm0: wo-ilm@151e0000 {
-+ reg = <0 0x151e0000 0 0x8000>;
-+ no-map;
-+ };
-+
-+ wo_ilm1: wo-ilm@151f0000 {
-+ reg = <0 0x151f0000 0 0x8000>;
-+ no-map;
-+ };
-+
-+ wo_data: wo-data@4fd80000 {
-+ reg = <0 0x4fd80000 0 0x240000>;
-+ no-map;
-+ };
-+
-+ wo_dlm0: wo-dlm@151e8000 {
-+ reg = <0 0x151e8000 0 0x2000>;
-+ no-map;
-+ };
-+
-+ wo_dlm1: wo-dlm@151f8000 {
-+ reg = <0 0x151f8000 0 0x2000>;
-+ no-map;
-+ };
-+
-+ wo_boot: wo-boot@15194000 {
-+ reg = <0 0x15194000 0 0x1000>;
-+ no-map;
-+ };
-+
- };
-
- timer {
-@@ -240,6 +281,11 @@
- reg = <0 0x15010000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
-+ memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>,
-+ <&wo_data>, <&wo_boot>;
-+ memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
-+ "wo-data", "wo-boot";
-+ mediatek,wo-ccif = <&wo_ccif0>;
- };
-
- wed1: wed@15011000 {
-@@ -248,6 +294,25 @@
- reg = <0 0x15011000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
-+ memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>,
-+ <&wo_data>, <&wo_boot>;
-+ memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
-+ "wo-data", "wo-boot";
-+ mediatek,wo-ccif = <&wo_ccif1>;
-+ };
-+
-+ wo_ccif0: syscon@151a5000 {
-+ compatible = "mediatek,mt7986-wo-ccif", "syscon";
-+ reg = <0 0x151a5000 0 0x1000>;
-+ interrupt-parent = <&gic>;
-+ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
-+ wo_ccif1: syscon@151ad000 {
-+ compatible = "mediatek,mt7986-wo-ccif", "syscon";
-+ reg = <0 0x151ad000 0 0x1000>;
-+ interrupt-parent = <&gic>;
-+ interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- eth: ethernet@15100000 {
+++ /dev/null
-From 438e53828c08cf0e8a65b61cf6ce1e4b6620551a Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Sun, 6 Nov 2022 09:50:24 +0100
-Subject: [PATCH 02/19] arm64: dts: mt7986: harmonize device node order
-
-This arrange device tree nodes in alphabetical order.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221106085034.12582-2-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 94 ++++++++++----------
- arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 22 ++---
- 2 files changed, 58 insertions(+), 58 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-@@ -54,6 +54,53 @@
- };
- };
-
-+&pio {
-+ uart1_pins: uart1-pins {
-+ mux {
-+ function = "uart";
-+ groups = "uart1";
-+ };
-+ };
-+
-+ uart2_pins: uart2-pins {
-+ mux {
-+ function = "uart";
-+ groups = "uart2";
-+ };
-+ };
-+
-+ 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>;
-+ };
-+ };
-+
-+ wf_dbdc_pins: wf-dbdc-pins {
-+ mux {
-+ function = "wifi";
-+ groups = "wf_dbdc";
-+ };
-+ 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";
-+ drive-strength = <4>;
-+ };
-+ };
-+};
-+
- &switch {
- ports {
- #address-cells = <1>;
-@@ -121,50 +168,3 @@
- pinctrl-0 = <&wf_2g_5g_pins>;
- pinctrl-1 = <&wf_dbdc_pins>;
- };
--
--&pio {
-- uart1_pins: uart1-pins {
-- mux {
-- function = "uart";
-- groups = "uart1";
-- };
-- };
--
-- uart2_pins: uart2-pins {
-- mux {
-- function = "uart";
-- groups = "uart2";
-- };
-- };
--
-- 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>;
-- };
-- };
--
-- wf_dbdc_pins: wf-dbdc-pins {
-- mux {
-- function = "wifi";
-- groups = "wf_dbdc";
-- };
-- 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";
-- drive-strength = <4>;
-- };
-- };
--};
---- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-@@ -25,10 +25,6 @@
- };
- };
-
--&uart0 {
-- status = "okay";
--};
--
- ð {
- status = "okay";
-
-@@ -99,13 +95,6 @@
- };
- };
-
--&wifi {
-- status = "okay";
-- pinctrl-names = "default", "dbdc";
-- pinctrl-0 = <&wf_2g_5g_pins>;
-- pinctrl-1 = <&wf_dbdc_pins>;
--};
--
- &pio {
- wf_2g_5g_pins: wf-2g-5g-pins {
- mux {
-@@ -138,3 +127,14 @@
- };
- };
- };
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&wifi {
-+ status = "okay";
-+ pinctrl-names = "default", "dbdc";
-+ pinctrl-0 = <&wf_2g_5g_pins>;
-+ pinctrl-1 = <&wf_dbdc_pins>;
-+};
+++ /dev/null
-From ffb05357b47f06b2b4d1e14ba89169e28feb727b Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Sun, 6 Nov 2022 09:50:27 +0100
-Subject: [PATCH 03/19] arm64: dts: mt7986: add crypto related device nodes
-
-This patch adds crypto engine support for MT7986.
-
-Signed-off-by: Vic Wu <vic.wu@mediatek.com>
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Link: https://lore.kernel.org/r/20221106085034.12582-5-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 4 ++++
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 15 +++++++++++++++
- arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 4 ++++
- 3 files changed, 23 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-@@ -25,6 +25,10 @@
- };
- };
-
-+&crypto {
-+ status = "okay";
-+};
-+
- ð {
- status = "okay";
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -224,6 +224,21 @@
- status = "disabled";
- };
-
-+ crypto: crypto@10320000 {
-+ compatible = "inside-secure,safexcel-eip97";
-+ reg = <0 0x10320000 0 0x40000>;
-+ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
-+ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
-+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
-+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupt-names = "ring0", "ring1", "ring2", "ring3";
-+ clocks = <&infracfg CLK_INFRA_EIP97_CK>;
-+ clock-names = "infra_eip97_ck";
-+ assigned-clocks = <&topckgen CLK_TOP_EIP_B_SEL>;
-+ assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>;
-+ status = "disabled";
-+ };
-+
- uart0: serial@11002000 {
- compatible = "mediatek,mt7986-uart",
- "mediatek,mt6577-uart";
---- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-@@ -25,6 +25,10 @@
- };
- };
-
-+&crypto {
-+ status = "okay";
-+};
-+
- ð {
- status = "okay";
-
+++ /dev/null
-From b49b7dc404ded1d89cbc568d875009a5c1ed4ef6 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Sun, 6 Nov 2022 09:50:29 +0100
-Subject: [PATCH 04/19] arm64: dts: mt7986: add i2c node
-
-Add i2c Node to mt7986 devicetree.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Link: https://lore.kernel.org/r/20221106085034.12582-7-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -280,6 +280,20 @@
- status = "disabled";
- };
-
-+ i2c0: i2c@11008000 {
-+ compatible = "mediatek,mt7986-i2c";
-+ reg = <0 0x11008000 0 0x90>,
-+ <0 0x10217080 0 0x80>;
-+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
-+ clock-div = <5>;
-+ clocks = <&infracfg CLK_INFRA_I2C0_CK>,
-+ <&infracfg CLK_INFRA_AP_DMA_CK>;
-+ clock-names = "main", "dma";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
- ethsys: syscon@15000000 {
- #address-cells = <1>;
- #size-cells = <1>;
+++ /dev/null
-From 2cd6022800d6da7822e169f3e6f7f790c1431445 Mon Sep 17 00:00:00 2001
-From: Matthias Brugger <mbrugger@suse.com>
-Date: Mon, 14 Nov 2022 13:16:53 +0100
-Subject: [PATCH 05/19] arm64: dts: mediatek: mt7986: Add SoC compatible
-
-Missing SoC compatible in the board file causes dt bindings check.
-
-Signed-off-by: Matthias Brugger <mbrugger@suse.com>
-Link: https://lore.kernel.org/r/20221114121653.14739-1-matthias.bgg@kernel.org
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 2 +-
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 1 +
- arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 2 +-
- arch/arm64/boot/dts/mediatek/mt7986b.dtsi | 3 +++
- 4 files changed, 6 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-@@ -9,7 +9,7 @@
-
- / {
- model = "MediaTek MT7986a RFB";
-- compatible = "mediatek,mt7986a-rfb";
-+ compatible = "mediatek,mt7986a-rfb", "mediatek,mt7986a";
-
- aliases {
- serial0 = &uart0;
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -10,6 +10,7 @@
- #include <dt-bindings/reset/mt7986-resets.h>
-
- / {
-+ compatible = "mediatek,mt7986a";
- interrupt-parent = <&gic>;
- #address-cells = <2>;
- #size-cells = <2>;
---- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-@@ -9,7 +9,7 @@
-
- / {
- model = "MediaTek MT7986b RFB";
-- compatible = "mediatek,mt7986b-rfb";
-+ compatible = "mediatek,mt7986b-rfb", "mediatek,mt7986b";
-
- aliases {
- serial0 = &uart0;
---- a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
-@@ -5,6 +5,9 @@
- */
-
- #include "mt7986a.dtsi"
-+/ {
-+ compatible = "mediatek,mt7986b";
-+};
-
- &pio {
- compatible = "mediatek,mt7986b-pinctrl";
+++ /dev/null
-From f4029538f063a845dc9aae46cce4cf386e6253a5 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 18 Nov 2022 20:01:21 +0100
-Subject: [PATCH 06/19] arm64: dts: mt7986: add spi related device nodes
-
-This patch adds spi support for MT7986.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221118190126.100895-7-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 35 ++++++++++++++++++++
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 28 ++++++++++++++++
- arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 35 ++++++++++++++++++++
- 3 files changed, 98 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-@@ -59,6 +59,20 @@
- };
-
- &pio {
-+ spi_flash_pins: spi-flash-pins {
-+ mux {
-+ function = "spi";
-+ groups = "spi0", "spi0_wp_hold";
-+ };
-+ };
-+
-+ spic_pins: spic-pins {
-+ mux {
-+ function = "spi";
-+ groups = "spi1_2";
-+ };
-+ };
-+
- uart1_pins: uart1-pins {
- mux {
- function = "uart";
-@@ -105,6 +119,27 @@
- };
- };
-
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi_flash_pins>;
-+ cs-gpios = <0>, <0>;
-+ status = "okay";
-+ spi_nand: spi_nand@0 {
-+ compatible = "spi-nand";
-+ reg = <0>;
-+ spi-max-frequency = <10000000>;
-+ spi-tx-bus-width = <4>;
-+ spi-rx-bus-width = <4>;
-+ };
-+};
-+
-+&spi1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spic_pins>;
-+ cs-gpios = <0>, <0>;
-+ status = "okay";
-+};
-+
- &switch {
- ports {
- #address-cells = <1>;
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -295,6 +295,34 @@
- status = "disabled";
- };
-
-+ spi0: spi@1100a000 {
-+ compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0 0x1100a000 0 0x100>;
-+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&topckgen CLK_TOP_MPLL_D2>,
-+ <&topckgen CLK_TOP_SPI_SEL>,
-+ <&infracfg CLK_INFRA_SPI0_CK>,
-+ <&infracfg CLK_INFRA_SPI0_HCK_CK>;
-+ clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
-+ status = "disabled";
-+ };
-+
-+ spi1: spi@1100b000 {
-+ compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0 0x1100b000 0 0x100>;
-+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&topckgen CLK_TOP_MPLL_D2>,
-+ <&topckgen CLK_TOP_SPIM_MST_SEL>,
-+ <&infracfg CLK_INFRA_SPI1_CK>,
-+ <&infracfg CLK_INFRA_SPI1_HCK_CK>;
-+ clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
-+ status = "disabled";
-+ };
-+
- ethsys: syscon@15000000 {
- #address-cells = <1>;
- #size-cells = <1>;
---- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-@@ -100,6 +100,20 @@
- };
-
- &pio {
-+ spi_flash_pins: spi-flash-pins {
-+ mux {
-+ function = "spi";
-+ groups = "spi0", "spi0_wp_hold";
-+ };
-+ };
-+
-+ spic_pins: spic-pins {
-+ mux {
-+ function = "spi";
-+ groups = "spi1_2";
-+ };
-+ };
-+
- wf_2g_5g_pins: wf-2g-5g-pins {
- mux {
- function = "wifi";
-@@ -132,6 +146,27 @@
- };
- };
-
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi_flash_pins>;
-+ cs-gpios = <0>, <0>;
-+ status = "okay";
-+ spi_nand: spi_nand@0 {
-+ compatible = "spi-nand";
-+ reg = <0>;
-+ spi-max-frequency = <10000000>;
-+ spi-tx-bus-width = <4>;
-+ spi-rx-bus-width = <4>;
-+ };
-+};
-+
-+&spi1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spic_pins>;
-+ cs-gpios = <0>, <0>;
-+ status = "okay";
-+};
-+
- &uart0 {
- status = "okay";
- };
+++ /dev/null
-From 9e8e24ab716098e617195ce29b88e84608bf2108 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 6 Jan 2023 16:28:42 +0100
-Subject: [PATCH 07/19] arm64: dts: mt7986: add usb related device nodes
-
-This patch adds USB support for MT7986.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
-Link: https://lore.kernel.org/r/20230106152845.88717-3-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 8 +++
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 55 ++++++++++++++++++++
- arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 8 +++
- 3 files changed, 71 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-@@ -140,6 +140,10 @@
- status = "okay";
- };
-
-+&ssusb {
-+ status = "okay";
-+};
-+
- &switch {
- ports {
- #address-cells = <1>;
-@@ -201,6 +205,10 @@
- status = "okay";
- };
-
-+&usb_phy {
-+ status = "okay";
-+};
-+
- &wifi {
- status = "okay";
- pinctrl-names = "default", "dbdc";
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -323,6 +323,61 @@
- status = "disabled";
- };
-
-+ ssusb: usb@11200000 {
-+ compatible = "mediatek,mt7986-xhci",
-+ "mediatek,mtk-xhci";
-+ reg = <0 0x11200000 0 0x2e00>,
-+ <0 0x11203e00 0 0x0100>;
-+ reg-names = "mac", "ippc";
-+ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>,
-+ <&infracfg CLK_INFRA_IUSB_CK>,
-+ <&infracfg CLK_INFRA_IUSB_133_CK>,
-+ <&infracfg CLK_INFRA_IUSB_66M_CK>,
-+ <&topckgen CLK_TOP_U2U3_XHCI_SEL>;
-+ clock-names = "sys_ck",
-+ "ref_ck",
-+ "mcu_ck",
-+ "dma_ck",
-+ "xhci_ck";
-+ phys = <&u2port0 PHY_TYPE_USB2>,
-+ <&u3port0 PHY_TYPE_USB3>,
-+ <&u2port1 PHY_TYPE_USB2>;
-+ status = "disabled";
-+ };
-+
-+ usb_phy: t-phy@11e10000 {
-+ compatible = "mediatek,mt7986-tphy",
-+ "mediatek,generic-tphy-v2";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges = <0 0 0x11e10000 0x1700>;
-+ status = "disabled";
-+
-+ u2port0: usb-phy@0 {
-+ reg = <0x0 0x700>;
-+ clocks = <&topckgen CLK_TOP_DA_U2_REFSEL>,
-+ <&topckgen CLK_TOP_DA_U2_CK_1P_SEL>;
-+ clock-names = "ref", "da_ref";
-+ #phy-cells = <1>;
-+ };
-+
-+ u3port0: usb-phy@700 {
-+ reg = <0x700 0x900>;
-+ clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>;
-+ clock-names = "ref";
-+ #phy-cells = <1>;
-+ };
-+
-+ u2port1: usb-phy@1000 {
-+ reg = <0x1000 0x700>;
-+ clocks = <&topckgen CLK_TOP_DA_U2_REFSEL>,
-+ <&topckgen CLK_TOP_DA_U2_CK_1P_SEL>;
-+ clock-names = "ref", "da_ref";
-+ #phy-cells = <1>;
-+ };
-+ };
-+
- ethsys: syscon@15000000 {
- #address-cells = <1>;
- #size-cells = <1>;
---- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-@@ -167,10 +167,18 @@
- status = "okay";
- };
-
-+&ssusb {
-+ status = "okay";
-+};
-+
- &uart0 {
- status = "okay";
- };
-
-+&usb_phy {
-+ status = "okay";
-+};
-+
- &wifi {
- status = "okay";
- pinctrl-names = "default", "dbdc";
+++ /dev/null
-From c1744e9e75a6a8abc7c893f349bcbf725b9c0d74 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 6 Jan 2023 16:28:43 +0100
-Subject: [PATCH 08/19] arm64: dts: mt7986: add mmc related device nodes
-
-This patch adds mmc support for MT7986.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Link: https://lore.kernel.org/r/20230106152845.88717-4-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 96 ++++++++++++++++++++
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 15 +++
- 2 files changed, 111 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-@@ -5,6 +5,8 @@
- */
-
- /dts-v1/;
-+#include <dt-bindings/pinctrl/mt65xx.h>
-+
- #include "mt7986a.dtsi"
-
- / {
-@@ -23,6 +25,24 @@
- device_type = "memory";
- reg = <0 0x40000000 0 0x40000000>;
- };
-+
-+ reg_1p8v: regulator-1p8v {
-+ compatible = "regulator-fixed";
-+ regulator-name = "fixed-1.8V";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-boot-on;
-+ regulator-always-on;
-+ };
-+
-+ 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;
-+ };
- };
-
- &crypto {
-@@ -58,7 +78,83 @@
- };
- };
-
-+&mmc0 {
-+ pinctrl-names = "default", "state_uhs";
-+ pinctrl-0 = <&mmc0_pins_default>;
-+ pinctrl-1 = <&mmc0_pins_uhs>;
-+ bus-width = <8>;
-+ max-frequency = <200000000>;
-+ cap-mmc-highspeed;
-+ mmc-hs200-1_8v;
-+ mmc-hs400-1_8v;
-+ hs400-ds-delay = <0x14014>;
-+ vmmc-supply = <®_3p3v>;
-+ vqmmc-supply = <®_1p8v>;
-+ non-removable;
-+ no-sd;
-+ no-sdio;
-+ status = "okay";
-+};
-+
- &pio {
-+ mmc0_pins_default: mmc0-pins {
-+ mux {
-+ function = "emmc";
-+ groups = "emmc_51";
-+ };
-+ conf-cmd-dat {
-+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
-+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
-+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
-+ input-enable;
-+ drive-strength = <4>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
-+ };
-+ conf-clk {
-+ pins = "EMMC_CK";
-+ drive-strength = <6>;
-+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
-+ };
-+ conf-ds {
-+ pins = "EMMC_DSL";
-+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
-+ };
-+ conf-rst {
-+ pins = "EMMC_RSTB";
-+ drive-strength = <4>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
-+ };
-+ };
-+
-+ mmc0_pins_uhs: mmc0-uhs-pins {
-+ mux {
-+ function = "emmc";
-+ groups = "emmc_51";
-+ };
-+ conf-cmd-dat {
-+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
-+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
-+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
-+ input-enable;
-+ drive-strength = <4>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
-+ };
-+ conf-clk {
-+ pins = "EMMC_CK";
-+ drive-strength = <6>;
-+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
-+ };
-+ conf-ds {
-+ pins = "EMMC_DSL";
-+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
-+ };
-+ conf-rst {
-+ pins = "EMMC_RSTB";
-+ drive-strength = <4>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
-+ };
-+ };
-+
- spi_flash_pins: spi-flash-pins {
- mux {
- function = "spi";
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -346,6 +346,21 @@
- status = "disabled";
- };
-
-+ mmc0: mmc@11230000 {
-+ compatible = "mediatek,mt7986-mmc";
-+ reg = <0 0x11230000 0 0x1000>,
-+ <0 0x11c20000 0 0x1000>;
-+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>,
-+ <&infracfg CLK_INFRA_MSDC_HCK_CK>,
-+ <&infracfg CLK_INFRA_MSDC_CK>,
-+ <&infracfg CLK_INFRA_MSDC_133M_CK>,
-+ <&infracfg CLK_INFRA_MSDC_66M_CK>;
-+ clock-names = "source", "hclk", "source_cg", "bus_clk",
-+ "sys_cg";
-+ status = "disabled";
-+ };
-+
- usb_phy: t-phy@11e10000 {
- compatible = "mediatek,mt7986-tphy",
- "mediatek,generic-tphy-v2";
+++ /dev/null
-From 87a42ef1d6cf602e4aa40555b4404cad6149a90f Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 6 Jan 2023 16:28:44 +0100
-Subject: [PATCH 09/19] arm64: dts: mt7986: add pcie related device nodes
-
-This patch adds PCIe support for MT7986.
-
-Signed-off-by: Jieyy Yang <jieyy.yang@mediatek.com>
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230106152845.88717-5-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 16 ++++++
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 52 ++++++++++++++++++++
- 2 files changed, 68 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-@@ -93,6 +93,15 @@
- non-removable;
- no-sd;
- no-sdio;
-+};
-+
-+&pcie {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie_pins>;
-+ status = "okay";
-+};
-+
-+&pcie_phy {
- status = "okay";
- };
-
-@@ -155,6 +164,13 @@
- };
- };
-
-+ pcie_pins: pcie-pins {
-+ mux {
-+ function = "pcie";
-+ groups = "pcie_clk", "pcie_wake", "pcie_pereset";
-+ };
-+ };
-+
- spi_flash_pins: spi-flash-pins {
- mux {
- function = "spi";
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -8,6 +8,7 @@
- #include <dt-bindings/interrupt-controller/arm-gic.h>
- #include <dt-bindings/clock/mt7986-clk.h>
- #include <dt-bindings/reset/mt7986-resets.h>
-+#include <dt-bindings/phy/phy.h>
-
- / {
- compatible = "mediatek,mt7986a";
-@@ -361,6 +362,57 @@
- status = "disabled";
- };
-
-+ pcie: pcie@11280000 {
-+ compatible = "mediatek,mt7986-pcie",
-+ "mediatek,mt8192-pcie";
-+ device_type = "pci";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ reg = <0x00 0x11280000 0x00 0x4000>;
-+ reg-names = "pcie-mac";
-+ interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
-+ bus-range = <0x00 0xff>;
-+ ranges = <0x82000000 0x00 0x20000000 0x00
-+ 0x20000000 0x00 0x10000000>;
-+ clocks = <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
-+ <&infracfg CLK_INFRA_IPCIE_CK>,
-+ <&infracfg CLK_INFRA_IPCIER_CK>,
-+ <&infracfg CLK_INFRA_IPCIEB_CK>;
-+ clock-names = "pl_250m", "tl_26m", "peri_26m", "top_133m";
-+ status = "disabled";
-+
-+ phys = <&pcie_port PHY_TYPE_PCIE>;
-+ phy-names = "pcie-phy";
-+
-+ #interrupt-cells = <1>;
-+ interrupt-map-mask = <0 0 0 0x7>;
-+ interrupt-map = <0 0 0 1 &pcie_intc 0>,
-+ <0 0 0 2 &pcie_intc 1>,
-+ <0 0 0 3 &pcie_intc 2>,
-+ <0 0 0 4 &pcie_intc 3>;
-+ pcie_intc: interrupt-controller {
-+ #address-cells = <0>;
-+ #interrupt-cells = <1>;
-+ interrupt-controller;
-+ };
-+ };
-+
-+ pcie_phy: t-phy@11c00000 {
-+ compatible = "mediatek,mt7986-tphy",
-+ "mediatek,generic-tphy-v2";
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ ranges;
-+ status = "disabled";
-+
-+ pcie_port: pcie-phy@11c00000 {
-+ reg = <0 0x11c00000 0 0x20000>;
-+ clocks = <&clk40m>;
-+ clock-names = "ref";
-+ #phy-cells = <1>;
-+ };
-+ };
-+
- usb_phy: t-phy@11e10000 {
- compatible = "mediatek,mt7986-tphy",
- "mediatek,generic-tphy-v2";
+++ /dev/null
-From a751f7412e0098801673b80bc7a4738ae7d710ce Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Fri, 6 Jan 2023 16:28:45 +0100
-Subject: [PATCH 10/19] arm64: dts: mt7986: add Bananapi R3
-
-Add support for Bananapi R3 SBC.
-
-- SD/eMMC support (switching first 4 bits of data-bus with sw6/D)
-- SPI-NAND/NOR support (switched CS by sw5/C)
-- all rj45 ports and both SFP working (eth1/lan4)
-- all USB-Ports + SIM-Slot tested
-- i2c and all uarts tested
-- wifi tested (with eeprom calibration data)
-
-The device can boot from all 4 storage options. Both, SPI and MMC, can
-be switched using hardware switches on the board, see
-https://wiki.banana-pi.org/Banana_Pi_BPI-R3#Jumper_setting
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Link: https://lore.kernel.org/r/20230106152845.88717-6-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/Makefile | 5 +
- .../mt7986a-bananapi-bpi-r3-emmc.dtso | 29 ++
- .../mt7986a-bananapi-bpi-r3-nand.dtso | 55 +++
- .../mediatek/mt7986a-bananapi-bpi-r3-nor.dtso | 68 +++
- .../mediatek/mt7986a-bananapi-bpi-r3-sd.dtso | 23 +
- .../dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 450 ++++++++++++++++++
- 6 files changed, 630 insertions(+)
- create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
- create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
- create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
- create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
- create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-
---- a/arch/arm64/boot/dts/mediatek/Makefile
-+++ b/arch/arm64/boot/dts/mediatek/Makefile
-@@ -7,6 +7,11 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-ev
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
-+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb
-+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc.dtbo
-+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo
-+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo
-+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
-@@ -0,0 +1,29 @@
-+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-+/*
-+ * Copyright (C) 2021 MediaTek Inc.
-+ * Author: Sam.Shih <sam.shih@mediatek.com>
-+ */
-+
-+/dts-v1/;
-+/plugin/;
-+
-+/ {
-+ compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-+
-+ fragment@0 {
-+ target-path = "/soc/mmc@11230000";
-+ __overlay__ {
-+ bus-width = <8>;
-+ max-frequency = <200000000>;
-+ cap-mmc-highspeed;
-+ mmc-hs200-1_8v;
-+ mmc-hs400-1_8v;
-+ hs400-ds-delay = <0x14014>;
-+ non-removable;
-+ no-sd;
-+ no-sdio;
-+ status = "okay";
-+ };
-+ };
-+};
-+
---- /dev/null
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
-@@ -0,0 +1,55 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
-+/*
-+ * Authors: Daniel Golle <daniel@makrotopia.org>
-+ * Frank Wunderlich <frank-w@public-files.de>
-+ */
-+
-+/dts-v1/;
-+/plugin/;
-+
-+/ {
-+ compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-+
-+ fragment@0 {
-+ target-path = "/soc/spi@1100a000";
-+ __overlay__ {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ spi_nand: spi_nand@0 {
-+ compatible = "spi-nand";
-+ reg = <0>;
-+ spi-max-frequency = <10000000>;
-+ 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 0x80000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "reserved";
-+ reg = <0x80000 0x300000>;
-+ };
-+
-+ partition@380000 {
-+ label = "fip";
-+ reg = <0x380000 0x200000>;
-+ read-only;
-+ };
-+
-+ partition@580000 {
-+ label = "ubi";
-+ reg = <0x580000 0x7a80000>;
-+ };
-+ };
-+ };
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
-@@ -0,0 +1,68 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
-+/*
-+ * Authors: Daniel Golle <daniel@makrotopia.org>
-+ * Frank Wunderlich <frank-w@public-files.de>
-+ */
-+
-+/dts-v1/;
-+/plugin/;
-+
-+/ {
-+ compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-+
-+ fragment@0 {
-+ target-path = "/soc/spi@1100a000";
-+ __overlay__ {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ 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 = "bl2";
-+ reg = <0x0 0x20000>;
-+ read-only;
-+ };
-+
-+ partition@20000 {
-+ label = "reserved";
-+ reg = <0x20000 0x20000>;
-+ };
-+
-+ partition@40000 {
-+ label = "u-boot-env";
-+ reg = <0x40000 0x40000>;
-+ };
-+
-+ partition@80000 {
-+ label = "reserved2";
-+ reg = <0x80000 0x80000>;
-+ };
-+
-+ partition@100000 {
-+ label = "fip";
-+ reg = <0x100000 0x80000>;
-+ read-only;
-+ };
-+
-+ partition@180000 {
-+ label = "recovery";
-+ reg = <0x180000 0xa80000>;
-+ };
-+
-+ partition@c00000 {
-+ label = "fit";
-+ reg = <0xc00000 0x1400000>;
-+ };
-+ };
-+ };
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
-@@ -0,0 +1,23 @@
-+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-+/*
-+ * Copyright (C) 2021 MediaTek Inc.
-+ * Author: Sam.Shih <sam.shih@mediatek.com>
-+ */
-+
-+/dts-v1/;
-+/plugin/;
-+
-+/ {
-+ compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-+
-+ fragment@0 {
-+ target-path = "/soc/mmc@11230000";
-+ __overlay__ {
-+ bus-width = <4>;
-+ max-frequency = <52000000>;
-+ cap-sd-highspeed;
-+ status = "okay";
-+ };
-+ };
-+};
-+
---- /dev/null
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-@@ -0,0 +1,450 @@
-+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-+/*
-+ * Copyright (C) 2021 MediaTek Inc.
-+ * Authors: Sam.Shih <sam.shih@mediatek.com>
-+ * Frank Wunderlich <frank-w@public-files.de>
-+ * Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+/dts-v1/;
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/pinctrl/mt65xx.h>
-+
-+#include "mt7986a.dtsi"
-+
-+/ {
-+ model = "Bananapi BPI-R3";
-+ compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-+
-+ aliases {
-+ serial0 = &uart0;
-+ ethernet0 = &gmac0;
-+ ethernet1 = &gmac1;
-+ };
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ dcin: regulator-12vd {
-+ compatible = "regulator-fixed";
-+ regulator-name = "12vd";
-+ regulator-min-microvolt = <12000000>;
-+ regulator-max-microvolt = <12000000>;
-+ regulator-boot-on;
-+ regulator-always-on;
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ reset-key {
-+ label = "reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&pio 9 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wps-key {
-+ label = "wps";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&pio 10 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ /* i2c of the left SFP cage (wan) */
-+ i2c_sfp1: i2c-gpio-0 {
-+ compatible = "i2c-gpio";
-+ sda-gpios = <&pio 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-+ scl-gpios = <&pio 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-+ i2c-gpio,delay-us = <2>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+
-+ /* i2c of the right SFP cage (lan) */
-+ i2c_sfp2: i2c-gpio-1 {
-+ compatible = "i2c-gpio";
-+ sda-gpios = <&pio 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-+ scl-gpios = <&pio 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-+ i2c-gpio,delay-us = <2>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ green_led: led-0 {
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_POWER;
-+ gpios = <&pio 69 GPIO_ACTIVE_HIGH>;
-+ default-state = "on";
-+ };
-+
-+ blue_led: led-1 {
-+ color = <LED_COLOR_ID_BLUE>;
-+ function = LED_FUNCTION_STATUS;
-+ gpios = <&pio 86 GPIO_ACTIVE_HIGH>;
-+ default-state = "off";
-+ };
-+ };
-+
-+ reg_1p8v: regulator-1p8v {
-+ compatible = "regulator-fixed";
-+ regulator-name = "1.8vd";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-boot-on;
-+ regulator-always-on;
-+ vin-supply = <&dcin>;
-+ };
-+
-+ reg_3p3v: regulator-3p3v {
-+ compatible = "regulator-fixed";
-+ regulator-name = "3.3vd";
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ regulator-boot-on;
-+ regulator-always-on;
-+ vin-supply = <&dcin>;
-+ };
-+
-+ /* left SFP cage (wan) */
-+ sfp1: sfp-1 {
-+ compatible = "sff,sfp";
-+ i2c-bus = <&i2c_sfp1>;
-+ los-gpios = <&pio 46 GPIO_ACTIVE_HIGH>;
-+ mod-def0-gpios = <&pio 49 GPIO_ACTIVE_LOW>;
-+ tx-disable-gpios = <&pio 20 GPIO_ACTIVE_HIGH>;
-+ tx-fault-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ /* right SFP cage (lan) */
-+ sfp2: sfp-2 {
-+ compatible = "sff,sfp";
-+ i2c-bus = <&i2c_sfp2>;
-+ los-gpios = <&pio 31 GPIO_ACTIVE_HIGH>;
-+ mod-def0-gpios = <&pio 47 GPIO_ACTIVE_LOW>;
-+ tx-disable-gpios = <&pio 15 GPIO_ACTIVE_HIGH>;
-+ tx-fault-gpios = <&pio 48 GPIO_ACTIVE_HIGH>;
-+ };
-+};
-+
-+&crypto {
-+ status = "okay";
-+};
-+
-+ð {
-+ 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 = "2500base-x";
-+ sfp = <&sfp1>;
-+ managed = "in-band-status";
-+ };
-+
-+ mdio: mdio-bus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+};
-+
-+&mdio {
-+ switch: switch@1f {
-+ compatible = "mediatek,mt7531";
-+ reg = <31>;
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ interrupt-parent = <&pio>;
-+ interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;
-+ reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
-+ };
-+};
-+
-+&mmc0 {
-+ pinctrl-names = "default", "state_uhs";
-+ pinctrl-0 = <&mmc0_pins_default>;
-+ pinctrl-1 = <&mmc0_pins_uhs>;
-+ vmmc-supply = <®_3p3v>;
-+ vqmmc-supply = <®_1p8v>;
-+};
-+
-+&i2c0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c_pins>;
-+ status = "okay";
-+};
-+
-+&pcie {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie_pins>;
-+ status = "okay";
-+};
-+
-+&pcie_phy {
-+ status = "okay";
-+};
-+
-+&pio {
-+ i2c_pins: i2c-pins {
-+ mux {
-+ function = "i2c";
-+ groups = "i2c";
-+ };
-+ };
-+
-+ mmc0_pins_default: mmc0-pins {
-+ mux {
-+ function = "emmc";
-+ groups = "emmc_51";
-+ };
-+ conf-cmd-dat {
-+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
-+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
-+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
-+ input-enable;
-+ drive-strength = <4>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
-+ };
-+ conf-clk {
-+ pins = "EMMC_CK";
-+ drive-strength = <6>;
-+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
-+ };
-+ conf-ds {
-+ pins = "EMMC_DSL";
-+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
-+ };
-+ conf-rst {
-+ pins = "EMMC_RSTB";
-+ drive-strength = <4>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
-+ };
-+ };
-+
-+ mmc0_pins_uhs: mmc0-uhs-pins {
-+ mux {
-+ function = "emmc";
-+ groups = "emmc_51";
-+ };
-+ conf-cmd-dat {
-+ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
-+ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
-+ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
-+ input-enable;
-+ drive-strength = <4>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
-+ };
-+ conf-clk {
-+ pins = "EMMC_CK";
-+ drive-strength = <6>;
-+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
-+ };
-+ conf-ds {
-+ pins = "EMMC_DSL";
-+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
-+ };
-+ conf-rst {
-+ pins = "EMMC_RSTB";
-+ drive-strength = <4>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
-+ };
-+ };
-+
-+ pcie_pins: pcie-pins {
-+ mux {
-+ function = "pcie";
-+ groups = "pcie_clk", "pcie_pereset";
-+ };
-+ };
-+
-+ spi_flash_pins: spi-flash-pins {
-+ mux {
-+ function = "spi";
-+ groups = "spi0", "spi0_wp_hold";
-+ };
-+ };
-+
-+ spic_pins: spic-pins {
-+ mux {
-+ function = "spi";
-+ groups = "spi1_0";
-+ };
-+ };
-+
-+ uart1_pins: uart1-pins {
-+ mux {
-+ function = "uart";
-+ groups = "uart1_rx_tx";
-+ };
-+ };
-+
-+ uart2_pins: uart2-pins {
-+ mux {
-+ function = "uart";
-+ groups = "uart2_0_rx_tx";
-+ };
-+ };
-+
-+ 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>;
-+ };
-+ };
-+
-+ wf_dbdc_pins: wf-dbdc-pins {
-+ mux {
-+ function = "wifi";
-+ groups = "wf_dbdc";
-+ };
-+ 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>;
-+ };
-+ };
-+
-+ wf_led_pins: wf-led-pins {
-+ mux {
-+ function = "led";
-+ groups = "wifi_led";
-+ };
-+ };
-+};
-+
-+&spi0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi_flash_pins>;
-+ status = "okay";
-+};
-+
-+&spi1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spic_pins>;
-+ status = "okay";
-+};
-+
-+&ssusb {
-+ status = "okay";
-+};
-+
-+&switch {
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan0";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan1";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan2";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan3";
-+ };
-+
-+ port5: port@5 {
-+ reg = <5>;
-+ label = "lan4";
-+ phy-mode = "2500base-x";
-+ sfp = <&sfp2>;
-+ managed = "in-band-status";
-+ };
-+
-+ port@6 {
-+ reg = <6>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ phy-mode = "2500base-x";
-+
-+ fixed-link {
-+ speed = <2500>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-+ };
-+};
-+
-+&trng {
-+ status = "okay";
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart1_pins>;
-+ status = "okay";
-+};
-+
-+&uart2 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart2_pins>;
-+ status = "okay";
-+};
-+
-+&usb_phy {
-+ status = "okay";
-+};
-+
-+&watchdog {
-+ status = "okay";
-+};
-+
-+&wifi {
-+ status = "okay";
-+ pinctrl-names = "default", "dbdc";
-+ pinctrl-0 = <&wf_2g_5g_pins>, <&wf_led_pins>;
-+ pinctrl-1 = <&wf_dbdc_pins>, <&wf_led_pins>;
-+};
-+
+++ /dev/null
-From 4c2d5411f4b101f7aa0fd74f80109e3afd6dc967 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Wed, 17 May 2023 12:11:08 +0200
-Subject: [PATCH 11/19] arm64: mediatek: Propagate chassis-type where possible
-
-The chassis-type string identifies the form-factor of the system:
-add this property to all device trees of devices for which the form
-factor is known.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230517101108.205654-1-angelogioacchino.delregno@collabora.com
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt2712-evb.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt6755-evb.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt6779-evb.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt6795-evb.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt6797-evb.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt6797-x20-dev.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8173-elm.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-evb.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts | 1 +
- .../boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu-sku22.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku16.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku272.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku288.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts | 1 +
- arch/arm64/boot/dts/mediatek/mt8186-evb.dts | 1 +
- 28 files changed, 28 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
-@@ -11,6 +11,7 @@
-
- / {
- model = "MediaTek MT2712 evaluation board";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt2712-evb", "mediatek,mt2712";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt6755-evb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt6755-evb.dts
-@@ -9,6 +9,7 @@
-
- / {
- model = "MediaTek MT6755 EVB";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt6755-evb", "mediatek,mt6755";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt6779-evb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt6779-evb.dts
-@@ -10,6 +10,7 @@
-
- / {
- model = "MediaTek MT6779 EVB";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt6779-evb", "mediatek,mt6779";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt6795-evb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt6795-evb.dts
-@@ -9,6 +9,7 @@
-
- / {
- model = "MediaTek MT6795 Evaluation Board";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt6795-evb", "mediatek,mt6795";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
-@@ -9,6 +9,7 @@
-
- / {
- model = "MediaTek MT6797 Evaluation Board";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt6797-evb", "mediatek,mt6797";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt6797-x20-dev.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt6797-x20-dev.dts
-@@ -12,6 +12,7 @@
-
- / {
- model = "Mediatek X20 Development Board";
-+ chassis-type = "embedded";
- compatible = "archermind,mt6797-x20-dev", "mediatek,mt6797";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -15,6 +15,7 @@
-
- / {
- model = "Bananapi BPI-R64";
-+ chassis-type = "embedded";
- compatible = "bananapi,bpi-r64", "mediatek,mt7622";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -15,6 +15,7 @@
-
- / {
- model = "MediaTek MT7622 RFB1 board";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-@@ -16,6 +16,7 @@
-
- / {
- model = "Bananapi BPI-R3";
-+ chassis-type = "embedded";
- compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
-@@ -11,6 +11,7 @@
-
- / {
- model = "MediaTek MT7986a RFB";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt7986a-rfb", "mediatek,mt7986a";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
-@@ -9,6 +9,7 @@
-
- / {
- model = "MediaTek MT7986b RFB";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt7986b-rfb", "mediatek,mt7986b";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dts
-@@ -11,6 +11,7 @@
-
- / {
- model = "Pumpkin MT8167";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt8167-pumpkin", "mediatek,mt8167";
-
- memory@40000000 {
---- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
-@@ -8,6 +8,7 @@
-
- / {
- model = "Google Hanawl";
-+ chassis-type = "laptop";
- compatible = "google,hana-rev7", "mediatek,mt8173";
- };
-
---- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts
-@@ -8,6 +8,7 @@
-
- / {
- model = "Google Hana";
-+ chassis-type = "laptop";
- compatible = "google,hana-rev6", "google,hana-rev5",
- "google,hana-rev4", "google,hana-rev3",
- "google,hana", "mediatek,mt8173";
---- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dts
-@@ -8,6 +8,7 @@
-
- / {
- model = "Google Elm";
-+ chassis-type = "laptop";
- compatible = "google,elm-rev8", "google,elm-rev7", "google,elm-rev6",
- "google,elm-rev5", "google,elm-rev4", "google,elm-rev3",
- "google,elm", "mediatek,mt8173";
---- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
-@@ -10,6 +10,7 @@
-
- / {
- model = "MediaTek MT8173 evaluation board";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt8173-evb", "mediatek,mt8173";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
-@@ -11,6 +11,7 @@
-
- / {
- model = "MediaTek MT8183 evaluation board";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt8183-evb", "mediatek,mt8183";
-
- aliases {
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
-@@ -9,6 +9,7 @@
-
- / {
- model = "Google burnet board";
-+ chassis-type = "convertible";
- compatible = "google,burnet", "mediatek,mt8183";
- };
-
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
-@@ -9,6 +9,7 @@
-
- / {
- model = "Google damu board";
-+ chassis-type = "convertible";
- compatible = "google,damu", "mediatek,mt8183";
- };
-
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts
-@@ -9,6 +9,7 @@
-
- / {
- model = "Google juniper sku16 board";
-+ chassis-type = "convertible";
- compatible = "google,juniper-sku16", "google,juniper", "mediatek,mt8183";
- };
-
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu-sku22.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu-sku22.dts
-@@ -9,6 +9,7 @@
-
- / {
- model = "MediaTek kakadu board sku22";
-+ chassis-type = "tablet";
- compatible = "google,kakadu-rev3-sku22", "google,kakadu-rev2-sku22",
- "google,kakadu", "mediatek,mt8183";
- };
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts
-@@ -9,6 +9,7 @@
-
- / {
- model = "MediaTek kakadu board";
-+ chassis-type = "tablet";
- compatible = "google,kakadu-rev3", "google,kakadu-rev2",
- "google,kakadu", "mediatek,mt8183";
- };
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku16.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku16.dts
-@@ -12,6 +12,7 @@
-
- / {
- model = "MediaTek kodama sku16 board";
-+ chassis-type = "tablet";
- compatible = "google,kodama-sku16", "google,kodama", "mediatek,mt8183";
- };
-
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku272.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku272.dts
-@@ -12,6 +12,7 @@
-
- / {
- model = "MediaTek kodama sku272 board";
-+ chassis-type = "tablet";
- compatible = "google,kodama-sku272", "google,kodama", "mediatek,mt8183";
- };
-
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku288.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku288.dts
-@@ -12,6 +12,7 @@
-
- / {
- model = "MediaTek kodama sku288 board";
-+ chassis-type = "tablet";
- compatible = "google,kodama-sku288", "google,kodama", "mediatek,mt8183";
- };
-
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
-@@ -14,6 +14,7 @@
-
- / {
- model = "MediaTek krane sku0 board";
-+ chassis-type = "tablet";
- compatible = "google,krane-sku0", "google,krane", "mediatek,mt8183";
- };
-
---- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
-@@ -14,6 +14,7 @@
-
- / {
- model = "MediaTek krane sku176 board";
-+ chassis-type = "tablet";
- compatible = "google,krane-sku176", "google,krane", "mediatek,mt8183";
- };
-
---- a/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
-@@ -7,6 +7,7 @@
-
- / {
- model = "MediaTek MT8186 evaluation board";
-+ chassis-type = "embedded";
- compatible = "mediatek,mt8186-evb", "mediatek,mt8186";
-
- aliases {
+++ /dev/null
-From 3b92c547e3d4a35c6214b3e7fa1103d0749d83b1 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 21 Apr 2023 15:20:44 +0200
-Subject: [PATCH 12/19] arm64: dts: mt7986: add PWM
-
-This adds pwm node to mt7986.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Link: https://lore.kernel.org/r/20230421132047.42166-5-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -241,6 +241,20 @@
- status = "disabled";
- };
-
-+ pwm: pwm@10048000 {
-+ compatible = "mediatek,mt7986-pwm";
-+ reg = <0 0x10048000 0 0x1000>;
-+ #clock-cells = <1>;
-+ #pwm-cells = <2>;
-+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&topckgen CLK_TOP_PWM_SEL>,
-+ <&infracfg CLK_INFRA_PWM_STA>,
-+ <&infracfg CLK_INFRA_PWM1_CK>,
-+ <&infracfg CLK_INFRA_PWM2_CK>;
-+ clock-names = "top", "main", "pwm1", "pwm2";
-+ status = "disabled";
-+ };
-+
- uart0: serial@11002000 {
- compatible = "mediatek,mt7986-uart",
- "mediatek,mt6577-uart";
+++ /dev/null
-From 35e482bb599df010b4869017ff576dbb7a4d4c2e Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Fri, 21 Apr 2023 15:20:45 +0200
-Subject: [PATCH 13/19] arm64: dts: mt7986: add PWM to BPI-R3
-
-Add pwm node and pinctrl to BananaPi R3 devicetree.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Link: https://lore.kernel.org/r/20230421132047.42166-6-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-@@ -275,6 +275,13 @@
- };
- };
-
-+ pwm_pins: pwm-pins {
-+ mux {
-+ function = "pwm";
-+ groups = "pwm0", "pwm1_0";
-+ };
-+ };
-+
- spi_flash_pins: spi-flash-pins {
- mux {
- function = "spi";
-@@ -345,6 +352,12 @@
- };
- };
-
-+&pwm {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm_pins>;
-+ status = "okay";
-+};
-+
- &spi0 {
- pinctrl-names = "default";
- pinctrl-0 = <&spi_flash_pins>;
+++ /dev/null
-From ccdda5714446db8690505371442f7807f5d7c6fc Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Sun, 5 Feb 2023 18:48:33 +0100
-Subject: [PATCH 14/19] arm64: dts: mt7986: set Wifi Leds low-active for BPI-R3
-
-Leds for Wifi are low-active, so add property to devicetree.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230205174833.107050-1-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-@@ -460,5 +460,9 @@
- pinctrl-names = "default", "dbdc";
- pinctrl-0 = <&wf_2g_5g_pins>, <&wf_led_pins>;
- pinctrl-1 = <&wf_dbdc_pins>, <&wf_led_pins>;
-+
-+ led {
-+ led-active-low;
-+ };
- };
-
+++ /dev/null
-From 1423b4b780adcf3994e63a5988a62d5d1d509bb1 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Sun, 28 May 2023 13:33:42 +0200
-Subject: [PATCH 15/19] arm64: dts: mt7986: use size of reserved partition for
- bl2
-
-To store uncompressed bl2 more space is required than partition is
-actually defined.
-
-There is currently no known usage of this reserved partition.
-Openwrt uses same partition layout.
-
-We added same change to u-boot with commit d7bb1099 [1].
-
-[1] https://source.denx.de/u-boot/u-boot/-/commit/d7bb109900c1ca754a0198b9afb50e3161ffc21e
-
-Cc: stable@vger.kernel.org
-Fixes: 8e01fb15b815 ("arm64: dts: mt7986: add Bananapi R3")
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/20230528113343.7649-1-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso | 7 +------
- 1 file changed, 1 insertion(+), 6 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
-@@ -27,15 +27,10 @@
-
- partition@0 {
- label = "bl2";
-- reg = <0x0 0x20000>;
-+ reg = <0x0 0x40000>;
- read-only;
- };
-
-- partition@20000 {
-- label = "reserved";
-- reg = <0x20000 0x20000>;
-- };
--
- partition@40000 {
- label = "u-boot-env";
- reg = <0x40000 0x40000>;
+++ /dev/null
-From 40a5a767d698ef7a71f8be851ea18b0a7a8b47bd Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 30 May 2023 22:12:33 +0200
-Subject: [PATCH 16/19] arm64: dts: mt7986: add thermal and efuse
-
-Add thermal related nodes to mt7986 devicetree.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230530201235.22330-3-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 36 ++++++++++++++++++++++-
- 1 file changed, 35 insertions(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -338,6 +338,15 @@
- status = "disabled";
- };
-
-+ auxadc: adc@1100d000 {
-+ compatible = "mediatek,mt7986-auxadc";
-+ reg = <0 0x1100d000 0 0x1000>;
-+ clocks = <&infracfg CLK_INFRA_ADC_26M_CK>;
-+ clock-names = "main";
-+ #io-channel-cells = <1>;
-+ status = "disabled";
-+ };
-+
- ssusb: usb@11200000 {
- compatible = "mediatek,mt7986-xhci",
- "mediatek,mtk-xhci";
-@@ -376,6 +385,21 @@
- status = "disabled";
- };
-
-+ thermal: thermal@1100c800 {
-+ #thermal-sensor-cells = <1>;
-+ compatible = "mediatek,mt7986-thermal";
-+ reg = <0 0x1100c800 0 0x800>;
-+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&infracfg CLK_INFRA_THERM_CK>,
-+ <&infracfg CLK_INFRA_ADC_26M_CK>,
-+ <&infracfg CLK_INFRA_ADC_FRC_CK>;
-+ clock-names = "therm", "auxadc", "adc_32k";
-+ mediatek,auxadc = <&auxadc>;
-+ mediatek,apmixedsys = <&apmixedsys>;
-+ nvmem-cells = <&thermal_calibration>;
-+ nvmem-cell-names = "calibration-data";
-+ };
-+
- pcie: pcie@11280000 {
- compatible = "mediatek,mt7986-pcie",
- "mediatek,mt8192-pcie";
-@@ -427,6 +451,17 @@
- };
- };
-
-+ efuse: efuse@11d00000 {
-+ compatible = "mediatek,mt7986-efuse", "mediatek,efuse";
-+ reg = <0 0x11d00000 0 0x1000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ thermal_calibration: calib@274 {
-+ reg = <0x274 0xc>;
-+ };
-+ };
-+
- usb_phy: t-phy@11e10000 {
- compatible = "mediatek,mt7986-tphy",
- "mediatek,generic-tphy-v2";
-@@ -568,5 +603,4 @@
- memory-region = <&wmcpu_emi>;
- };
- };
--
- };
+++ /dev/null
-From bb78d0cf5117517f1ed296ae71048945d9107675 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 30 May 2023 22:12:34 +0200
-Subject: [PATCH 17/19] arm64: dts: mt7986: add thermal-zones
-
-Add thermal-zones to mt7986 devicetree.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230530201235.22330-4-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 28 +++++++++++++++++++++++
- 1 file changed, 28 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -603,4 +603,32 @@
- memory-region = <&wmcpu_emi>;
- };
- };
-+
-+ thermal-zones {
-+ cpu_thermal: cpu-thermal {
-+ polling-delay-passive = <1000>;
-+ polling-delay = <1000>;
-+ thermal-sensors = <&thermal 0>;
-+
-+ trips {
-+ cpu_trip_active_high: active-high {
-+ temperature = <115000>;
-+ hysteresis = <2000>;
-+ type = "active";
-+ };
-+
-+ cpu_trip_active_low: active-low {
-+ temperature = <85000>;
-+ hysteresis = <2000>;
-+ type = "active";
-+ };
-+
-+ cpu_trip_passive: passive {
-+ temperature = <40000>;
-+ hysteresis = <2000>;
-+ type = "passive";
-+ };
-+ };
-+ };
-+ };
- };
+++ /dev/null
-From 5d90603b09e5814ffc38c47e79ccf9bc564f9296 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 30 May 2023 22:12:35 +0200
-Subject: [PATCH 18/19] arm64: dts: mt7986: add pwm-fan and cooling-maps to
- BPI-R3 dts
-
-Add pwm-fan and cooling-maps to BananaPi-R3 devicetree.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230530201235.22330-5-linux@fw-web.de
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- .../dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 31 +++++++++++++++++++
- 1 file changed, 31 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-@@ -38,6 +38,15 @@
- regulator-always-on;
- };
-
-+ fan: pwm-fan {
-+ compatible = "pwm-fan";
-+ #cooling-cells = <2>;
-+ /* cooling level (0, 1, 2) - pwm inverted */
-+ cooling-levels = <255 96 0>;
-+ pwms = <&pwm 0 10000 0>;
-+ status = "okay";
-+ };
-+
- gpio-keys {
- compatible = "gpio-keys";
-
-@@ -133,6 +142,28 @@
- };
- };
-
-+&cpu_thermal {
-+ cooling-maps {
-+ cpu-active-high {
-+ /* active: set fan to cooling level 2 */
-+ cooling-device = <&fan 2 2>;
-+ trip = <&cpu_trip_active_high>;
-+ };
-+
-+ cpu-active-low {
-+ /* active: set fan to cooling level 1 */
-+ cooling-device = <&fan 1 1>;
-+ trip = <&cpu_trip_active_low>;
-+ };
-+
-+ cpu-passive {
-+ /* passive: set fan to cooling level 0 */
-+ cooling-device = <&fan 0 0>;
-+ trip = <&cpu_trip_passive>;
-+ };
-+ };
-+};
-+
- &crypto {
- status = "okay";
- };
+++ /dev/null
-From 6dd3b939370094eb79529683be84500f3c757404 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 6 Jun 2023 16:43:20 +0100
-Subject: [PATCH 19/19] arm64: dts: mt7986: increase bl2 partition on NAND of
- Bananapi R3
-
-The bootrom burned into the MT7986 SoC will try multiple locations on
-the SPI-NAND flash to load bl2 in case the bl2 image located at the the
-previously attempted offset is corrupt.
-
-Use 0x100000 instead of 0x80000 as partition size for bl2 on SPI-NAND,
-allowing for up to four redundant copies of bl2 (typically sized a
-bit less than 0x40000).
-
-Fixes: 8e01fb15b8157 ("arm64: dts: mt7986: add Bananapi R3")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/ZH9UGF99RgzrHZ88@makrotopia.org
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
-@@ -29,13 +29,13 @@
-
- partition@0 {
- label = "bl2";
-- reg = <0x0 0x80000>;
-+ reg = <0x0 0x100000>;
- read-only;
- };
-
-- partition@80000 {
-+ partition@100000 {
- label = "reserved";
-- reg = <0x80000 0x300000>;
-+ reg = <0x100000 0x280000>;
- };
-
- partition@380000 {
+++ /dev/null
-From f8ed4088ed9c61ae92193da6130d04c37e7b19f2 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Sun, 20 Aug 2023 17:31:33 +0200
-Subject: [PATCH 20/22] arm64: dts: mt7986: define 3W max power to both SFP on
- BPI-R3
-
-All SFP power supplies are connected to the system VDD33 which is 3v3/8A.
-Set 3A per SFP slot to allow SFPs work which need more power than the
-default 1W.
-
-Fixes: 8e01fb15b815 ("arm64: dts: mt7986: add Bananapi R3")
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
----
- arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-@@ -126,6 +126,7 @@
- compatible = "sff,sfp";
- i2c-bus = <&i2c_sfp1>;
- los-gpios = <&pio 46 GPIO_ACTIVE_HIGH>;
-+ maximum-power-milliwatt = <3000>;
- mod-def0-gpios = <&pio 49 GPIO_ACTIVE_LOW>;
- tx-disable-gpios = <&pio 20 GPIO_ACTIVE_HIGH>;
- tx-fault-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
-@@ -137,6 +138,7 @@
- i2c-bus = <&i2c_sfp2>;
- los-gpios = <&pio 31 GPIO_ACTIVE_HIGH>;
- mod-def0-gpios = <&pio 47 GPIO_ACTIVE_LOW>;
-+ maximum-power-milliwatt = <3000>;
- tx-disable-gpios = <&pio 15 GPIO_ACTIVE_HIGH>;
- tx-fault-gpios = <&pio 48 GPIO_ACTIVE_HIGH>;
- };
+++ /dev/null
-From aa3d6df9803c267725dc72286bb91602b7579882 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Sun, 20 Aug 2023 17:31:34 +0200
-Subject: [PATCH 21/22] arm64: dts: mt7986: change cooling trips
-
-Add Critical and hot trips for emergency system shutdown and limiting
-system load.
-
-Change passive trip to active to make sure fan is activated on the
-lowest trip.
-
-Fixes: 1f5be05132f3 ("arm64: dts: mt7986: add thermal-zones")
-Suggested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 20 ++++++++++++++++----
- 1 file changed, 16 insertions(+), 4 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -611,22 +611,34 @@
- thermal-sensors = <&thermal 0>;
-
- trips {
-+ cpu_trip_crit: crit {
-+ temperature = <125000>;
-+ hysteresis = <2000>;
-+ type = "critical";
-+ };
-+
-+ cpu_trip_hot: hot {
-+ temperature = <120000>;
-+ hysteresis = <2000>;
-+ type = "hot";
-+ };
-+
- cpu_trip_active_high: active-high {
- temperature = <115000>;
- hysteresis = <2000>;
- type = "active";
- };
-
-- cpu_trip_active_low: active-low {
-+ cpu_trip_active_med: active-med {
- temperature = <85000>;
- hysteresis = <2000>;
- type = "active";
- };
-
-- cpu_trip_passive: passive {
-- temperature = <40000>;
-+ cpu_trip_active_low: active-low {
-+ temperature = <60000>;
- hysteresis = <2000>;
-- type = "passive";
-+ type = "active";
- };
- };
- };
+++ /dev/null
-From 6ddf23526955b8dbedfeaa57e691261fd73f9d4e Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Sun, 20 Aug 2023 17:31:35 +0200
-Subject: [PATCH 22/22] arm64: dts: mt7986: change thermal trips on BPI-R3
-
-Apply new naming after mt7986 thermal trips were changed.
-
-Fixes: c26f779a2295 ("arm64: dts: mt7986: add pwm-fan and cooling-maps to BPI-R3 dts")
-Suggested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
----
- .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-@@ -152,16 +152,16 @@
- trip = <&cpu_trip_active_high>;
- };
-
-- cpu-active-low {
-+ cpu-active-med {
- /* active: set fan to cooling level 1 */
- cooling-device = <&fan 1 1>;
-- trip = <&cpu_trip_active_low>;
-+ trip = <&cpu_trip_active_med>;
- };
-
-- cpu-passive {
-- /* passive: set fan to cooling level 0 */
-+ cpu-active-low {
-+ /* active: set fan to cooling level 0 */
- cooling-device = <&fan 0 0>;
-- trip = <&cpu_trip_passive>;
-+ trip = <&cpu_trip_active_low>;
- };
- };
- };
+++ /dev/null
-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
-@@ -414,6 +414,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 (*check_part[])(struct parsed
- #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
-@@ -439,6 +445,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)
-@@ -631,6 +642,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
-@@ -432,7 +432,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,
-
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -1,7 +1,6 @@
- /*
-- * Copyright (c) 2017 MediaTek Inc.
-- * Author: Ming Huang <ming.huang@mediatek.com>
-- * Sean Wang <sean.wang@mediatek.com>
-+ * Copyright (c) 2018 MediaTek Inc.
-+ * Author: Ryder Lee <ryder.lee@mediatek.com>
- *
- * SPDX-License-Identifier: (GPL-2.0 OR MIT)
- */
-@@ -24,7 +23,7 @@
-
- chosen {
- stdout-path = "serial0:115200n8";
-- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
-+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
- };
-
- cpus {
-@@ -45,18 +44,18 @@
- key-factory {
- label = "factory";
- linux,code = <BTN_0>;
-- gpios = <&pio 0 0>;
-+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
- };
-
- key-wps {
- label = "wps";
- linux,code = <KEY_WPS_BUTTON>;
-- gpios = <&pio 102 0>;
-+ gpios = <&pio 102 GPIO_ACTIVE_LOW>;
- };
- };
-
- memory@40000000 {
-- reg = <0 0x40000000 0 0x20000000>;
-+ reg = <0 0x40000000 0 0x40000000>;
- device_type = "memory";
- };
-
-@@ -133,22 +132,22 @@
-
- port@0 {
- reg = <0>;
-- label = "lan0";
-+ label = "lan1";
- };
-
- port@1 {
- reg = <1>;
-- label = "lan1";
-+ label = "lan2";
- };
-
- port@2 {
- reg = <2>;
-- label = "lan2";
-+ label = "lan3";
- };
-
- port@3 {
- reg = <3>;
-- label = "lan3";
-+ label = "lan4";
- };
-
- port@4 {
-@@ -241,7 +240,22 @@
- status = "okay";
- };
-
-+&pcie1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie1_pins>;
-+ status = "okay";
-+};
-+
- &pio {
-+ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and
-+ * SATA functions. i.e. output-high: PCIe, output-low: SATA
-+ */
-+ asm_sel {
-+ gpio-hog;
-+ gpios = <90 GPIO_ACTIVE_HIGH>;
-+ output-high;
-+ };
-+
- /* eMMC is shared pin with parallel NAND */
- emmc_pins_default: emmc-pins-default {
- mux {
-@@ -518,11 +532,11 @@
- };
-
- &sata {
-- status = "okay";
-+ status = "disabled";
- };
-
- &sata_phy {
-- status = "okay";
-+ status = "disabled";
- };
-
- &spi0 {
+++ /dev/null
---- a/arch/arm/boot/dts/mt7629-rfb.dts
-+++ b/arch/arm/boot/dts/mt7629-rfb.dts
-@@ -18,6 +18,7 @@
-
- chosen {
- stdout-path = "serial0:115200n8";
-+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8";
- };
-
- gpio-keys {
-@@ -70,6 +71,10 @@
- compatible = "mediatek,eth-mac";
- reg = <0>;
- phy-mode = "2500base-x";
-+
-+ nvmem-cells = <&macaddr_factory_2a>;
-+ nvmem-cell-names = "mac-address";
-+
- fixed-link {
- speed = <2500>;
- full-duplex;
-@@ -82,6 +87,9 @@
- reg = <1>;
- phy-mode = "gmii";
- phy-handle = <&phy0>;
-+
-+ nvmem-cells = <&macaddr_factory_24>;
-+ nvmem-cell-names = "mac-address";
- };
-
- mdio: mdio-bus {
-@@ -133,8 +141,9 @@
- };
-
- partition@b0000 {
-- label = "kernel";
-+ label = "firmware";
- reg = <0xb0000 0xb50000>;
-+ compatible = "denx,fit";
- };
- };
- };
-@@ -273,3 +282,17 @@
- pinctrl-0 = <&watchdog_pins>;
- status = "okay";
- };
-+
-+&factory {
-+ compatible = "nvmem-cells";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ macaddr_factory_24: macaddr@24 {
-+ reg = <0x24 0x6>;
-+ };
-+
-+ macaddr_factory_2a: macaddr@2a {
-+ reg = <0x2a 0x6>;
-+ };
-+};
+++ /dev/null
-From d6a596012150960f0f3a214d31bbac4b607dbd1e Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Fri, 29 Apr 2022 10:40:56 +0800
-Subject: [PATCH] arm: mediatek: select arch timer for mt7623
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
----
- arch/arm/mach-mediatek/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/mach-mediatek/Kconfig
-+++ b/arch/arm/mach-mediatek/Kconfig
-@@ -26,6 +26,7 @@ config MACH_MT6592
- config MACH_MT7623
- bool "MediaTek MT7623 SoCs support"
- default ARCH_MEDIATEK
-+ select HAVE_ARM_ARCH_TIMER
-
- config MACH_MT7629
- bool "MediaTek MT7629 SoCs support"
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -578,6 +578,7 @@
- compatible = "mediatek,mt7622-nor",
- "mediatek,mt8173-nor";
- reg = <0 0x11014000 0 0xe0>;
-+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_LOW>;
- clocks = <&pericfg CLK_PERI_FLASH_PD>,
- <&topckgen CLK_TOP_FLASH_SEL>;
- clock-names = "spi", "sf";
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -134,6 +134,13 @@
- #size-cells = <2>;
- ranges;
-
-+ /* 64 KiB reserved for ramoops/pstore */
-+ ramoops@42ff0000 {
-+ compatible = "ramoops";
-+ reg = <0 0x42ff0000 0 0x10000>;
-+ record-size = <0x1000>;
-+ };
-+
- /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
- secmon_reserved: secmon@43000000 {
- reg = <0 0x43000000 0 0x30000>;
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -109,10 +109,6 @@
- status = "disabled";
- };
-
--&btif {
-- status = "okay";
--};
--
- &cir {
- pinctrl-names = "default";
- pinctrl-0 = <&irrx_pins>;
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -90,10 +90,6 @@
- status = "disabled";
- };
-
--&btif {
-- status = "okay";
--};
--
- &cir {
- pinctrl-names = "default";
- pinctrl-0 = <&irrx_pins>;
+++ /dev/null
---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-@@ -19,6 +19,7 @@
-
- chosen {
- stdout-path = "serial2:115200n8";
-+ bootargs = "console=ttyS2,115200n8 console=tty1";
- };
-
- connector {
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -24,7 +24,7 @@
-
- chosen {
- stdout-path = "serial0:115200n8";
-- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
-+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
- };
-
- cpus {
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -20,6 +20,7 @@
-
- aliases {
- serial0 = &uart0;
-+ ethernet0 = &gmac0;
- };
-
- chosen {
-@@ -161,22 +162,22 @@
-
- port@1 {
- reg = <1>;
-- label = "lan0";
-+ label = "lan1";
- };
-
- port@2 {
- reg = <2>;
-- label = "lan1";
-+ label = "lan2";
- };
-
- port@3 {
- reg = <3>;
-- label = "lan2";
-+ label = "lan3";
- };
-
- port@4 {
- reg = <4>;
-- label = "lan3";
-+ label = "lan4";
- };
-
- port@6 {
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -21,6 +21,12 @@
- aliases {
- serial0 = &uart0;
- ethernet0 = &gmac0;
-+ led-boot = &led_system_green;
-+ led-failsafe = &led_system_blue;
-+ led-running = &led_system_green;
-+ led-upgrade = &led_system_blue;
-+ mmc0 = &mmc0;
-+ mmc1 = &mmc1;
- };
-
- chosen {
-@@ -44,8 +50,8 @@
- compatible = "gpio-keys";
-
- factory-key {
-- label = "factory";
-- linux,code = <BTN_0>;
-+ label = "reset";
-+ linux,code = <KEY_RESTART>;
- gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
- };
-
-@@ -59,17 +65,17 @@
- leds {
- compatible = "gpio-leds";
-
-- led-0 {
-+ led_system_green: led-0 {
- label = "bpi-r64:pio:green";
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&pio 89 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
-
-- led-1 {
-- label = "bpi-r64:pio:red";
-- color = <LED_COLOR_ID_RED>;
-- gpios = <&pio 88 GPIO_ACTIVE_HIGH>;
-+ led_system_blue: led-1 {
-+ label = "bpi-r64:pio:blue";
-+ color = <LED_COLOR_ID_BLUE>;
-+ gpios = <&pio 85 GPIO_ACTIVE_HIGH>;
- default-state = "off";
- };
- };
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -557,12 +557,16 @@
- status = "okay";
- };
-
-+&rtc {
-+ status = "disabled";
-+};
-+
- &sata {
-- status = "disable";
-+ status = "disabled";
- };
-
- &sata_phy {
-- status = "disable";
-+ status = "disabled";
- };
-
- &spi0 {
+++ /dev/null
-From d278f43f25beedfd0cb784d1dd0a9e7e8c8f123f Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 19 Apr 2023 20:15:53 +0100
-Subject: [PATCH] arm64: dts: mt7622: declare SPI-NAND present on BPI-R64
-
-The SPI-NOR node in the device tree of the BananaPi R64 has most likely
-been copied from the reference board's device tree even though the R64
-comes with an SPI-NAND chip rather than SPI-NOR.
-
-Setup the Serial NAND Flash Interface (SNFI) controller, enable
-hardware BCH error detection and correction engine and add the SPI-NAND
-chip including basic partitions,
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/ZEA96dmaXqTpk8u8@makrotopia.org
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 38 ++++++++++++++++---
- 1 file changed, 33 insertions(+), 5 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -254,14 +254,42 @@
- status = "disabled";
- };
-
--&nor_flash {
-- pinctrl-names = "default";
-- pinctrl-0 = <&spi_nor_pins>;
-- status = "disabled";
-+&bch {
-+ status = "okay";
-+};
-
-+&snfi {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&serial_nand_pins>;
-+ status = "okay";
- flash@0 {
-- compatible = "jedec,spi-nor";
-+ compatible = "spi-nand";
- reg = <0>;
-+ spi-tx-bus-width = <4>;
-+ spi-rx-bus-width = <4>;
-+ nand-ecc-engine = <&snfi>;
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "bl2";
-+ reg = <0x0 0x80000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "fip";
-+ reg = <0x80000 0x200000>;
-+ read-only;
-+ };
-+
-+ ubi: partition@280000 {
-+ label = "ubi";
-+ reg = <0x280000 0x7d80000>;
-+ };
-+ };
- };
- };
-
+++ /dev/null
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -724,7 +724,7 @@ static int spinand_mtd_write(struct mtd_
- static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
- {
- struct spinand_device *spinand = nand_to_spinand(nand);
-- u8 marker[2] = { };
-+ u8 marker[1] = { };
- struct nand_page_io_req req = {
- .pos = *pos,
- .ooblen = sizeof(marker),
-@@ -735,7 +735,7 @@ static bool spinand_isbad(struct nand_de
-
- spinand_select_target(spinand, pos->target);
- spinand_read_page(spinand, &req);
-- if (marker[0] != 0xff || marker[1] != 0xff)
-+ if (marker[0] != 0xff)
- return true;
-
- return false;
+++ /dev/null
-From c813fbe806257c574240770ef716fbee19f7dbfa Mon Sep 17 00:00:00 2001
-From: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
-Date: Thu, 6 Jun 2019 16:29:04 +0800
-Subject: [PATCH] spi: spi-mem: Mediatek: Add SPI Nand support for MT7629
-
-Signed-off-by: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
----
- arch/arm/boot/dts/mt7629-rfb.dts | 45 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/mt7629.dtsi | 22 ++++++++++++++++
- 3 files changed, 79 insertions(+)
-
---- a/arch/arm/boot/dts/mt7629.dtsi
-+++ b/arch/arm/boot/dts/mt7629.dtsi
-@@ -272,6 +272,27 @@
- status = "disabled";
- };
-
-+ snfi: spi@1100d000 {
-+ compatible = "mediatek,mt7629-snand";
-+ reg = <0x1100d000 0x1000>;
-+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&pericfg CLK_PERI_NFI_PD>, <&pericfg CLK_PERI_SNFI_PD>;
-+ clock-names = "nfi_clk", "pad_clk";
-+ nand-ecc-engine = <&bch>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ bch: ecc@1100e000 {
-+ compatible = "mediatek,mt7622-ecc";
-+ reg = <0x1100e000 0x1000>;
-+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&pericfg CLK_PERI_NFIECC_PD>;
-+ clock-names = "nfiecc_clk";
-+ status = "disabled";
-+ };
-+
- spi: spi@1100a000 {
- compatible = "mediatek,mt7629-spi",
- "mediatek,mt7622-spi";
---- a/arch/arm/boot/dts/mt7629-rfb.dts
-+++ b/arch/arm/boot/dts/mt7629-rfb.dts
-@@ -255,6 +255,50 @@
- };
- };
-
-+&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>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "Bootloader";
-+ reg = <0x00000 0x0100000>;
-+ read-only;
-+ };
-+
-+ partition@100000 {
-+ label = "Config";
-+ reg = <0x100000 0x0040000>;
-+ };
-+
-+ partition@140000 {
-+ label = "factory";
-+ reg = <0x140000 0x0080000>;
-+ };
-+
-+ partition@1c0000 {
-+ label = "firmware";
-+ reg = <0x1c0000 0x1000000>;
-+ };
-+ };
-+ };
-+};
-+
- &spi {
- pinctrl-names = "default";
- pinctrl-0 = <&spi_pins>;
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -535,6 +535,65 @@
- status = "disabled";
- };
-
-+&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>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "Preloader";
-+ reg = <0x00000 0x0080000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "ATF";
-+ reg = <0x80000 0x0040000>;
-+ };
-+
-+ partition@c0000 {
-+ label = "Bootloader";
-+ reg = <0xc0000 0x0080000>;
-+ };
-+
-+ partition@140000 {
-+ label = "Config";
-+ reg = <0x140000 0x0080000>;
-+ };
-+
-+ partition@1c0000 {
-+ label = "Factory";
-+ reg = <0x1c0000 0x0100000>;
-+ };
-+
-+ partition@200000 {
-+ label = "firmware";
-+ reg = <0x2c0000 0x2000000>;
-+ };
-+
-+ partition@2200000 {
-+ label = "User_data";
-+ reg = <0x22c0000 0x4000000>;
-+ };
-+ };
-+ };
-+};
-+
- &spi0 {
- pinctrl-names = "default";
- pinctrl-0 = <&spic0_pins>;
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -576,7 +576,7 @@
- reg = <0x140000 0x0080000>;
- };
-
-- partition@1c0000 {
-+ factory: partition@1c0000 {
- label = "Factory";
- reg = <0x1c0000 0x0100000>;
- };
-@@ -637,5 +637,6 @@
- &wmac {
- pinctrl-names = "default";
- pinctrl-0 = <&wmac_pins>;
-+ mediatek,mtd-eeprom = <&factory 0x0000>;
- status = "okay";
- };
+++ /dev/null
---- a/arch/arm/boot/dts/mt7623.dtsi
-+++ b/arch/arm/boot/dts/mt7623.dtsi
-@@ -984,17 +984,15 @@
- };
-
- crypto: crypto@1b240000 {
-- compatible = "mediatek,eip97-crypto";
-+ compatible = "inside-secure,safexcel-eip97";
- reg = <0 0x1b240000 0 0x20000>;
- interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_LOW>,
- <GIC_SPI 83 IRQ_TYPE_LEVEL_LOW>,
- <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>,
-- <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>,
-- <GIC_SPI 97 IRQ_TYPE_LEVEL_LOW>;
-+ <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
-+ interrupt-names = "ring0", "ring1", "ring2", "ring3";
- clocks = <ðsys CLK_ETHSYS_CRYPTO>;
-- clock-names = "cryp";
-- power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
-- status = "disabled";
-+ status = "okay";
- };
-
- bdpsys: syscon@1c000000 {
+++ /dev/null
---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-@@ -19,7 +19,7 @@
-
- chosen {
- stdout-path = "serial2:115200n8";
-- bootargs = "console=ttyS2,115200n8 console=tty1";
-+ bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
- };
-
- connector {
+++ /dev/null
---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-@@ -15,6 +15,8 @@
-
- aliases {
- serial2 = &uart2;
-+ mmc0 = &mmc0;
-+ mmc1 = &mmc1;
- };
-
- chosen {
+++ /dev/null
---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-@@ -17,6 +17,10 @@
- serial2 = &uart2;
- mmc0 = &mmc0;
- mmc1 = &mmc1;
-+ led-boot = &led_system_green;
-+ led-failsafe = &led_system_blue;
-+ led-running = &led_system_green;
-+ led-upgrade = &led_system_blue;
- };
-
- chosen {
-@@ -112,13 +116,13 @@
- pinctrl-names = "default";
- pinctrl-0 = <&led_pins_a>;
-
-- blue {
-+ led_system_blue: blue {
- label = "bpi-r2:pio:blue";
- gpios = <&pio 240 GPIO_ACTIVE_LOW>;
- default-state = "off";
- };
-
-- green {
-+ led_system_green: green {
- label = "bpi-r2:pio:green";
- gpios = <&pio 241 GPIO_ACTIVE_LOW>;
- default-state = "off";
+++ /dev/null
---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-@@ -15,6 +15,7 @@
-
- aliases {
- serial2 = &uart2;
-+ ethernet0 = &gmac0;
- mmc0 = &mmc0;
- mmc1 = &mmc1;
- led-boot = &led_system_green;
+++ /dev/null
---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
-@@ -26,7 +26,9 @@
-
- chosen {
- stdout-path = "serial2:115200n8";
-- bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
-+ bootargs = "root=/dev/fit0 rootwait earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
-+ rootdisk-emmc = <&emmc_rootdisk>;
-+ rootdisk-sd = <&sd_rootdisk>;
- };
-
- connector {
-@@ -315,6 +317,20 @@
- vmmc-supply = <®_3p3v>;
- vqmmc-supply = <®_1p8v>;
- non-removable;
-+
-+ card@0 {
-+ compatible = "mmc-card";
-+ reg = <0>;
-+
-+ block {
-+ compatible = "block-device";
-+ partitions {
-+ emmc_rootdisk: block-partition-fit {
-+ partno = <3>;
-+ };
-+ };
-+ };
-+ };
- };
-
- &mmc1 {
-@@ -328,6 +344,20 @@
- cd-gpios = <&pio 261 GPIO_ACTIVE_LOW>;
- vmmc-supply = <®_3p3v>;
- vqmmc-supply = <®_3p3v>;
-+
-+ card@0 {
-+ compatible = "mmc-card";
-+ reg = <0>;
-+
-+ block {
-+ compatible = "block-device";
-+ partitions {
-+ sd_rootdisk: block-partition-fit {
-+ partno = <3>;
-+ };
-+ };
-+ };
-+ };
- };
-
- &mt6323_leds {
+++ /dev/null
-From 983f37ee08acb60435744f1b1e2afea2d2a09c48 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 19 Apr 2023 20:16:29 +0100
-Subject: [PATCH] arm64: dts: mt7622: handle interrupts from MT7531 switch on
- BPI-R64
-
-Since commit ba751e28d442 ("net: dsa: mt7530: add interrupt support")
-the mt7530 driver can act as an interrupt controller. Wire up irq line
-of the MT7531 switch on the BananaPi BPi-R64 board, so the status of
-the PHYs of the five 1000Base-T ports doesn't need to be polled any
-more.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/ZEA-DV_OsmFg5egL@makrotopia.org
-Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
----
- arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -155,6 +155,10 @@
- switch@0 {
- compatible = "mediatek,mt7531";
- reg = <0>;
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ interrupt-parent = <&pio>;
-+ interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
- reset-gpios = <&pio 54 0>;
-
- ports {
+++ /dev/null
-From patchwork Tue Apr 26 19:51:36 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: 12827872
-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
-Received: from bombadil.infradead.org (bombadil.infradead.org
- [198.137.202.133])
- (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
- (No client certificate requested)
- by smtp.lore.kernel.org (Postfix) with ESMTPS id BACF3C433EF
- for <linux-arm-kernel@archiver.kernel.org>;
- Tue, 26 Apr 2022 19:53:05 +0000 (UTC)
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=lists.infradead.org; s=bombadil.20210309; h=Sender:
- Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:
- List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Subject:Cc:To:
- From:Date:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:
- Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:
- List-Owner; bh=OWGSxvlKoyPWz6b629RNINucULo6oOdFssAIiJETWRg=; b=T0HEjee0FX3hlb
- x5jl7xLK5sKM0pkE2oRgwzthbFlNg8ST1j/2GkgcgT0S2Bi0vRfFxHeu/RKzS9RmiVnKJnPGL8ctg
- WoBLyO5i+NcmosGoy6MmoOjGTNhj/+3q3Z1jRLBSJ4ySSP22X77YeuJTmVzySPUllQhWvDhjMVCR9
- QBRmQdc6gCAg3IYGEbWwS2TG+UHveDCeZRWxMzrwI8UPadNCRFROwugmiQ3mdU41lHCTDpnlfuRJh
- o1igLKfMBLz+D8rFYvDh7FfkcKkY6lNoswA2HKUun1MEzgoyQKmITPnG2maX/BvJJuj/B3ZJShh4k
- AZHmXoQxq1mrsm2FxfnQ==;
-Received: from localhost ([::1] helo=bombadil.infradead.org)
- by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))
- id 1njRE5-00G05D-9z; Tue, 26 Apr 2022 19:51:57 +0000
-Received: from fudo.makrotopia.org ([2a07:2ec0:3002::71])
- by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))
- id 1njRE1-00G03h-9H; Tue, 26 Apr 2022 19:51:55 +0000
-Received: from local
- by fudo.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256)
- (Exim 4.94.2) (envelope-from <daniel@makrotopia.org>)
- id 1njRDu-0006aF-4F; Tue, 26 Apr 2022 21:51:46 +0200
-Date: Tue, 26 Apr 2022 20:51:36 +0100
-From: Daniel Golle <daniel@makrotopia.org>
-To: devicetree@vger.kernel.org, linux-mediatek@lists.infradead.org,
- linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
-Cc: Rob Herring <robh+dt@kernel.org>,
- Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
- Matthias Brugger <matthias.bgg@gmail.com>
-Subject: [PATCH] arm64: dts: mediatek: mt7622: fix GICv2 range
-Message-ID: <YmhNSLgp/yg8Vr1F@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
-X-CRM114-CacheID: sfid-20220426_125153_359242_EA3D452C
-X-CRM114-Status: GOOD ( 12.45 )
-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-Unsubscribe:
- <http://lists.infradead.org/mailman/options/linux-arm-kernel>,
- <mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>
-List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
-List-Post: <mailto:linux-arm-kernel@lists.infradead.org>
-List-Help: <mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>
-List-Subscribe:
- <http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,
- <mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>
-Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
-Errors-To:
- linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org
-
-With the current range specified for the CPU interface there is an
-error message at boot:
-
-GIC: GICv2 detected, but range too small and irqchip.gicv2_force_probe not set
-
-Setting irqchip.gicv2_force_probe=1 in bootargs results in:
-
-GIC: Aliased GICv2 at 0x0000000010320000, trying to find the canonical range over 128kB
-GIC: Adjusting CPU interface base to 0x000000001032f000
-GIC: Using split EOI/Deactivate mode
-
-Using the adjusted CPU interface base and 8K size results in only the
-final line remaining and fully working system as well as /proc/interrupts
-showing additional IPI3,4,5,6:
-
-IPI3: 0 0 CPU stop (for crash dump) interrupts
-IPI4: 0 0 Timer broadcast interrupts
-IPI5: 0 0 IRQ work interrupts
-IPI6: 0 0 CPU wake-up interrupts
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- arch/arm64/boot/dts/mediatek/mt7622.dtsi | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -346,7 +346,7 @@
- #interrupt-cells = <3>;
- interrupt-parent = <&gic>;
- reg = <0 0x10310000 0 0x1000>,
-- <0 0x10320000 0 0x1000>,
-+ <0 0x1032f000 0 0x2000>,
- <0 0x10340000 0 0x2000>,
- <0 0x10360000 0 0x2000>;
- };
+++ /dev/null
-From 824d56e753a588fcfd650db1822e34a02a48bb77 Mon Sep 17 00:00:00 2001
-From: Bruno Umuarama <anonimou_eu@hotmail.com>
-Date: Thu, 13 Oct 2022 21:18:21 +0000
-Subject: [PATCH] mediatek: mt7623: fix thermal zone
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Raising the temperatures for passive and active trips. @VA1DER
-proposed at issue 9396 to remove passive trip. This commit relates to
-his suggestion.
-
-Without this patch. the CPU will be throttled all the way down to 98MHz
-if the temperature rises even a degree above the trip point, and it was
-further discovered that if the internal temperature of the device is
-above the first trip point temperature when it boots then it will start
-in a throttled state and even
-$ echo disabled > /sys/class/thermal/thermal_zone0/mode
-will have no effect.
-
-The patch increases the passive trip point and active cooling map. The
-throttling temperature will then be at 77°C and 82°C, which is still a
-low enough temperature for ARM devices to not be in the real danger
-zone, and gives some operational headroom.
-
-Signed-off-by: Bruno Umuarama <anonimou_eu@hotmail.com>
----
- arch/arm/boot/dts/mt7623.dtsi | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/mt7623.dtsi
-+++ b/arch/arm/boot/dts/mt7623.dtsi
-@@ -160,13 +160,13 @@
-
- trips {
- cpu_passive: cpu-passive {
-- temperature = <57000>;
-+ temperature = <77000>;
- hysteresis = <2000>;
- type = "passive";
- };
-
- cpu_active: cpu-active {
-- temperature = <67000>;
-+ temperature = <82000>;
- hysteresis = <2000>;
- type = "active";
- };
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -68,6 +68,14 @@
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-+
-+ /* 64 KiB reserved for ramoops/pstore */
-+ ramoops@42ff0000 {
-+ compatible = "ramoops";
-+ reg = <0 0x42ff0000 0 0x10000>;
-+ record-size = <0x1000>;
-+ };
-+
- /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
- secmon_reserved: secmon@43000000 {
- reg = <0 0x43000000 0 0x30000>;
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
-@@ -23,6 +23,10 @@
- serial0 = &uart0;
- ethernet0 = &gmac0;
- ethernet1 = &gmac1;
-+ led-boot = &green_led;
-+ led-failsafe = &green_led;
-+ led-running = &green_led;
-+ led-upgrade = &blue_led;
- };
-
- chosen {
-@@ -419,27 +423,27 @@
-
- port@1 {
- reg = <1>;
-- label = "lan0";
-+ label = "lan1";
- };
-
- port@2 {
- reg = <2>;
-- label = "lan1";
-+ label = "lan2";
- };
-
- port@3 {
- reg = <3>;
-- label = "lan2";
-+ label = "lan3";
- };
-
- port@4 {
- reg = <4>;
-- label = "lan3";
-+ label = "lan4";
- };
-
- port5: port@5 {
- reg = <5>;
-- label = "lan4";
-+ label = "sfp2";
- phy-mode = "2500base-x";
- sfp = <&sfp2>;
- managed = "in-band-status";
-@@ -490,9 +494,137 @@
-
- &wifi {
- status = "okay";
-- pinctrl-names = "default", "dbdc";
-+ pinctrl-names = "default";
- pinctrl-0 = <&wf_2g_5g_pins>, <&wf_led_pins>;
-- pinctrl-1 = <&wf_dbdc_pins>, <&wf_led_pins>;
-+
-+ mediatek,eeprom-data = <0x86790900 0x000c4326 0x60000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x01000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000800 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x24649090 0x00280000 0x05100000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00021e00 0x021e0002 0x1e00021e 0x00022800 0x02280002 0x28000228 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00008080 0x8080fdf7
-+ 0x0903150d 0x80808080 0x80808080 0x05050d0d 0x1313c6c6 0xc3c3c200 0x00c200c2 0x00008182
-+ 0x8585c2c2 0x82828282 0x858500c2 0xc2000081 0x82858587 0x87c2c200 0x81818285 0x858787c2
-+ 0xc2000081 0x82858587 0x87c2c200 0x00818285 0x858787c2 0xc2000081 0x82858587 0x87c4c4c2
-+ 0xc100c300 0xc3c3c100 0x818383c3 0xc3c3c100 0x81838300 0xc2c2c2c0 0x81828484 0x000000c3
-+ 0xc3c3c100 0x81838386 0x86c3c3c3 0xc1008183 0x838686c2 0xc2c2c081 0x82848486 0x86c3c3c3
-+ 0xc1008183 0x838686c3 0xc3c3c100 0x81838386 0x86c3c3c3 0xc1008183 0x83868622 0x28002228
-+ 0x00222800 0x22280000 0xdddddddd 0xdddddddd 0xddbbbbbb 0xccccccdd 0xdddddddd 0xdddddddd
-+ 0xeeeeeecc 0xccccdddd 0xdddddddd 0x004a5662 0x0000004a 0x56620000 0x004a5662 0x0000004a
-+ 0x56620000 0x88888888 0x33333326 0x26262626 0x26262600 0x33333326 0x26262626 0x26262600
-+ 0x33333326 0x26262626 0x26262600 0x33333326 0x26262626 0x26262600 0x00000000 0xf0f0cc00
-+ 0x00000000 0x0000aaaa 0xaabbbbbb 0xcccccccc 0xccccbbbb 0xbbbbbbbb 0xbbbbbbaa 0xaaaabbbb
-+ 0xbbaaaaaa 0x999999aa 0xaaaabbbb 0xbbcccccc 0x00000000 0x0000aaaa 0xaa000000 0xbbbbbbbb
-+ 0xbbbbaaaa 0xaa999999 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaabbbb 0xbbbbbbbb
-+ 0x00000000 0x00000000 0x00000000 0x99999999 0x9999aaaa 0xaaaaaaaa 0x999999aa 0xaaaaaaaa
-+ 0xaaaaaaaa 0xaaaaaaaa 0xaaaabbbb 0xbbbbbbbb 0x00000000 0x0000eeee 0xeeffffff 0xcccccccc
-+ 0xccccdddd 0xddbbbbbb 0xccccccbb 0xbbbbbbbb 0xbbbbbbbb 0xbbbbbbbb 0xbbbbcccc 0xccdddddd
-+ 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051
-+ 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200
-+ 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e
-+ 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051
-+ 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200
-+ 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e
-+ 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000001 0x06000100 0x01050002 0x00ff0300
-+ 0xf900fe03 0x00000000 0x00000000 0x0000009b 0x6e370000 0x00000000 0x00fc0009 0x0a00fe00
-+ 0x060700fe 0x00070800 0x05000b0a 0x00000000 0x00000000 0x000000e2 0x96460000 0x00000000
-+ 0x000400f7 0xf8000300 0xfcfe0003 0x00fbfc00 0xee00e3f2 0x00000000 0x00000000 0x00000011
-+ 0xbb550000 0x00000000 0x000600f6 0xfc000300 0xfbfe0004 0x00fafe00 0xf600ecf2 0x00000000
-+ 0x00000000 0x0000001f 0xbf580000 0x00000000 0x000600f5 0xf6000400 0xf8f90004 0x00f7f800
-+ 0xf700f0f4 0x00000000 0x00000000 0x00000024 0xbe570000 0x00000000 0x000800f8 0xfe000600
-+ 0xf8fd0007 0x00f9fe00 0xf500f0f4 0x00000000 0x00000000 0x0000002d 0xd6610000 0x00000000
-+ 0x000400f7 0xfc000500 0xf7fc0005 0x00f7fc00 0xf900f5f8 0x00000000 0x00000000 0x00000026
-+ 0xd96e0000 0x00000000 0x000400f7 0xf9000600 0xf5f70005 0x00f5f800 0xf900f4f7 0x00000000
-+ 0x00000000 0x0000001b 0xce690000 0x00000000 0x000300f8 0xf8000600 0xf6f60004 0x00f6f700
-+ 0xf900f4f7 0x00000000 0x00000000 0x00000018 0xd8720000 0x00000000 0x00000000 0x02404002
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0xc1c2c1c2 0x41c341c3 0x3fc13fc1 0x40c13fc2 0x3fc240c1 0x41c040c0 0x3fc23fc2 0x40c13fc2
-+ 0x3fc140c0 0x41c040c0 0x3fc33fc3 0x40c23fc2 0x3fc240c1 0x41c040c0 0x3fc23fc2 0x40c23fc2
-+ 0x3fc140c1 0x41c040c0 0x00000000 0x00000000 0x41c741c7 0xc1c7c1c7 0x00000000 0x00000000
-+ 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0
-+ 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0
-+ 0x00a0ce00 0x00000000 0xb6840000 0x00000000 0x00000000 0x00000000 0x18181818 0x18181818
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x004b5763 0x0000004b 0x57630000 0x004b5763 0x0000004b 0x57630000 0x88888888 0x08474759
-+ 0x69780849 0x49596d7a 0x0849495a 0x6d790848 0x48596c78 0x08484858 0x6a780848 0x48586a78
-+ 0x08484858 0x6c78084a 0x4a5b6d79 0x08474759 0x697a0848 0x48596b79 0x08484859 0x6c7a0848
-+ 0x48586c79 0x08484857 0x68770848 0x48576877 0x08484857 0x6a77084a 0x4a5a6a77 0x08464659
-+ 0x69790848 0x48586b79 0x08484858 0x6c7a0848 0x48596c79 0x08484857 0x68770848 0x48576877
-+ 0x08494958 0x6d7a084b 0x4b5c6c77 0x0847475a 0x6a7b0849 0x495a6e7c 0x0849495a 0x6e7c0849
-+ 0x495b6e7c 0x08494959 0x6a7a0849 0x49596a7a 0x084a4a5a 0x6f7d084b 0x4b5c6e7b 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x85848484
-+ 0xc3c4c4c5 0xc4c3c33f 0xc3c3c2c2 0xc2c2c03f 0xc3c3c3c4 0xc4c4c33f 0xc2c2c2c2 0xc1c3c1c1
-+ 0xc0c08282 0x83848686 0x88880000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00001111 0x00000000
-+ 0x8080f703 0x10808080 0x80050d13 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x000000a4 0xce000000 0x0000b684 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
-+ 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000>;
-
- led {
- led-active-low;
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
-@@ -55,6 +55,7 @@
- partition@c00000 {
- label = "fit";
- reg = <0xc00000 0x1400000>;
-+ compatible = "denx,fit";
- };
- };
- };
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
-@@ -23,7 +23,27 @@
- no-sd;
- no-sdio;
- status = "okay";
-+
-+ card@0 {
-+ compatible = "mmc-card";
-+ reg = <0>;
-+
-+ block {
-+ compatible = "block-device";
-+ partitions {
-+ emmc_rootdisk: block-partition-production {
-+ partname = "production";
-+ };
-+ };
-+ };
-+ };
- };
- };
--};
-
-+ fragment@1 {
-+ target-path = "/chosen";
-+ __overlay__ {
-+ rootdisk-emmc = <&emmc_rootdisk>;
-+ };
-+ };
-+};
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
-@@ -29,27 +29,30 @@
-
- partition@0 {
- label = "bl2";
-- reg = <0x0 0x100000>;
-+ reg = <0x0 0x200000>;
- read-only;
- };
-
-- partition@100000 {
-- label = "reserved";
-- reg = <0x100000 0x280000>;
-- };
--
-- partition@380000 {
-- label = "fip";
-- reg = <0x380000 0x200000>;
-- read-only;
-- };
--
-- partition@580000 {
-+ partition@200000 {
- label = "ubi";
-- reg = <0x580000 0x7a80000>;
-+ reg = <0x200000 0x7e00000>;
-+ compatible = "linux,ubi";
-+
-+ volumes {
-+ nand_rootdisk: ubi-volume-fit {
-+ volname = "fit";
-+ };
-+ };
- };
- };
- };
- };
- };
-+
-+ fragment@1 {
-+ target-path = "/chosen";
-+ __overlay__ {
-+ rootdisk-spim-nand = <&nand_rootdisk>;
-+ };
-+ };
- };
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
-@@ -52,7 +52,7 @@
- reg = <0x180000 0xa80000>;
- };
-
-- partition@c00000 {
-+ nor_rootdisk: partition@c00000 {
- label = "fit";
- reg = <0xc00000 0x1400000>;
- compatible = "denx,fit";
-@@ -61,4 +61,11 @@
- };
- };
- };
-+
-+ fragment@1 {
-+ target-path = "/chosen";
-+ __overlay__ {
-+ rootdisk-nor = <&nor_rootdisk>;
-+ };
-+ };
- };
---- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
-@@ -17,6 +17,27 @@
- max-frequency = <52000000>;
- cap-sd-highspeed;
- status = "okay";
-+
-+ card@0 {
-+ compatible = "mmc-card";
-+ reg = <0>;
-+
-+ block {
-+ compatible = "block-device";
-+ partitions {
-+ sd_rootdisk: block-partition-production {
-+ partname = "production";
-+ };
-+ };
-+ };
-+ };
-+ };
-+ };
-+
-+ fragment@1 {
-+ target-path = "/chosen";
-+ __overlay__ {
-+ rootdisk-sd = <&sd_rootdisk>;
- };
- };
- };
+++ /dev/null
-From 28f9a5e2a3f5441ab5594669ed82da11e32277a9 Mon Sep 17 00:00:00 2001
-From: Kristian Evensen <kristian.evensen@gmail.com>
-Date: Mon, 30 Apr 2018 14:38:01 +0200
-Subject: [PATCH] phy: phy-mtk-tphy: Add hifsys-support
-
----
- drivers/phy/mediatek/phy-mtk-tphy.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/drivers/phy/mediatek/phy-mtk-tphy.c
-+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
-@@ -17,6 +17,8 @@
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
- #include <linux/regmap.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/regmap.h>
-
- #include "phy-mtk-io.h"
-
-@@ -264,6 +266,9 @@
-
- #define TPHY_CLKS_CNT 2
-
-+#define HIF_SYSCFG1 0x14
-+#define HIF_SYSCFG1_PHY2_MASK (0x3 << 20)
-+
- enum mtk_phy_version {
- MTK_PHY_V1 = 1,
- MTK_PHY_V2,
-@@ -331,6 +336,7 @@ struct mtk_tphy {
- void __iomem *sif_base; /* only shared sif */
- const struct mtk_phy_pdata *pdata;
- struct mtk_phy_instance **phys;
-+ struct regmap *hif;
- int nphys;
- int src_ref_clk; /* MHZ, reference clock for slew rate calibrate */
- int src_coef; /* coefficient for slew rate calibrate */
-@@ -596,6 +602,10 @@ static void pcie_phy_instance_init(struc
- if (tphy->pdata->version != MTK_PHY_V1)
- return;
-
-+ if (tphy->hif)
-+ regmap_update_bits(tphy->hif, HIF_SYSCFG1,
-+ HIF_SYSCFG1_PHY2_MASK, 0);
-+
- mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG0,
- P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H,
- FIELD_PREP(P3A_RG_XTAL_EXT_PE1H, 0x2) |
-@@ -1241,6 +1251,16 @@ static int mtk_tphy_probe(struct platfor
- &tphy->src_coef);
- }
-
-+ if (of_find_property(np, "mediatek,phy-switch", NULL)) {
-+ tphy->hif = syscon_regmap_lookup_by_phandle(np,
-+ "mediatek,phy-switch");
-+ if (IS_ERR(tphy->hif)) {
-+ dev_err(&pdev->dev,
-+ "missing \"mediatek,phy-switch\" phandle\n");
-+ return PTR_ERR(tphy->hif);
-+ }
-+ }
-+
- port = 0;
- for_each_child_of_node(np, child_np) {
- struct mtk_phy_instance *instance;
+++ /dev/null
-From f76e8bc416bebb0f7b9f57b1247eae945421c0b9 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Sat, 8 Oct 2022 18:48:06 +0200
-Subject: [PATCH 1/2] pinctrl: mt7986: allow configuring uart rx/tx and rts/cts
- separately
-
-Some mt7986 boards use uart rts/cts pins as gpio,
-This patch allows to change rts/cts to gpio mode, but keep
-rx/tx as UART function.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Link: https://lore.kernel.org/r/20221008164807.113590-1-linux@fw-web.de
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/mediatek/pinctrl-mt7986.c | 32 ++++++++++++++++++-----
- 1 file changed, 25 insertions(+), 7 deletions(-)
-
---- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
-@@ -675,11 +675,17 @@ static int mt7986_uart1_1_funcs[] = { 4,
- static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, };
- static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, };
-
--static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, };
--static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, };
-+static int mt7986_uart1_2_rx_tx_pins[] = { 29, 30, };
-+static int mt7986_uart1_2_rx_tx_funcs[] = { 3, 3, };
-
--static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, };
--static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, };
-+static int mt7986_uart1_2_cts_rts_pins[] = { 31, 32, };
-+static int mt7986_uart1_2_cts_rts_funcs[] = { 3, 3, };
-+
-+static int mt7986_uart2_0_rx_tx_pins[] = { 29, 30, };
-+static int mt7986_uart2_0_rx_tx_funcs[] = { 4, 4, };
-+
-+static int mt7986_uart2_0_cts_rts_pins[] = { 31, 32, };
-+static int mt7986_uart2_0_cts_rts_funcs[] = { 4, 4, };
-
- static int mt7986_spi0_pins[] = { 33, 34, 35, 36, };
- static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, };
-@@ -708,6 +714,12 @@ static int mt7986_pcie_reset_funcs[] = {
- static int mt7986_uart1_pins[] = { 42, 43, 44, 45, };
- static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, };
-
-+static int mt7986_uart1_rx_tx_pins[] = { 42, 43, };
-+static int mt7986_uart1_rx_tx_funcs[] = { 1, 1, };
-+
-+static int mt7986_uart1_cts_rts_pins[] = { 44, 45, };
-+static int mt7986_uart1_cts_rts_funcs[] = { 1, 1, };
-+
- static int mt7986_uart2_pins[] = { 46, 47, 48, 49, };
- static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, };
-
-@@ -749,6 +761,8 @@ static const struct group_desc mt7986_gr
- PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led),
- PINCTRL_PIN_GROUP("i2c", mt7986_i2c),
- PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0),
-+ PINCTRL_PIN_GROUP("uart1_rx_tx", mt7986_uart1_rx_tx),
-+ PINCTRL_PIN_GROUP("uart1_cts_rts", mt7986_uart1_cts_rts),
- PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk),
- PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake),
- PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0),
-@@ -760,8 +774,10 @@ static const struct group_desc mt7986_gr
- PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1),
- PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1),
- PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2),
-- PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2),
-- PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0),
-+ PINCTRL_PIN_GROUP("uart1_2_rx_tx", mt7986_uart1_2_rx_tx),
-+ PINCTRL_PIN_GROUP("uart1_2_cts_rts", mt7986_uart1_2_cts_rts),
-+ PINCTRL_PIN_GROUP("uart2_0_rx_tx", mt7986_uart2_0_rx_tx),
-+ PINCTRL_PIN_GROUP("uart2_0_cts_rts", mt7986_uart2_0_cts_rts),
- PINCTRL_PIN_GROUP("spi0", mt7986_spi0),
- PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold),
- PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1),
-@@ -800,7 +816,9 @@ static const char *mt7986_pwm_groups[] =
- static const char *mt7986_spi_groups[] = {
- "spi0", "spi0_wp_hold", "spi1_0", "spi1_1", "spi1_2", "spi1_3", };
- static const char *mt7986_uart_groups[] = {
-- "uart1_0", "uart1_1", "uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts",
-+ "uart1_0", "uart1_1", "uart1_rx_tx", "uart1_cts_rts",
-+ "uart1_2_rx_tx", "uart1_2_cts_rts",
-+ "uart1_3_rx_tx", "uart1_3_cts_rts", "uart2_0_rx_tx", "uart2_0_cts_rts",
- "uart2_0", "uart2_1", "uart0", "uart1", "uart2",
- };
- static const char *mt7986_wdt_groups[] = { "watchdog", };
+++ /dev/null
-From 822d774abbcc66b811e28c68b59b40b964ba5b46 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Sun, 6 Nov 2022 09:01:13 +0100
-Subject: [PATCH 2/2] pinctrl: mediatek: add pull_type attribute for mediatek
- MT7986 SoC
-
-Commit fb34a9ae383a ("pinctrl: mediatek: support rsel feature")
-add SoC specify 'pull_type' attribute for bias configuration.
-
-This patch add pull_type attribute to pinctrl-mt7986.c, and make
-bias_set_combo and bias_get_combo available to mediatek MT7986 SoC.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221106080114.7426-7-linux@fw-web.de
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/mediatek/pinctrl-mt7986.c | 56 +++++++++++++++++++++++
- 1 file changed, 56 insertions(+)
-
---- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
-@@ -407,6 +407,60 @@ static const struct mtk_pin_field_calc m
- PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x60, 0x10, 2, 1),
- };
-
-+static const unsigned int mt7986_pull_type[] = {
-+ MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PUPD_R1R0_TYPE,/*7*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*8*/ MTK_PULL_PUPD_R1R0_TYPE,/*9*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PUPD_R1R0_TYPE,/*13*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*14*/ MTK_PULL_PUPD_R1R0_TYPE,/*15*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*16*/ MTK_PULL_PUPD_R1R0_TYPE,/*17*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PUPD_R1R0_TYPE,/*63*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PU_PD_TYPE,/*69*/
-+ MTK_PULL_PU_PD_TYPE,/*70*/ MTK_PULL_PU_PD_TYPE,/*71*/
-+ MTK_PULL_PU_PD_TYPE,/*72*/ MTK_PULL_PU_PD_TYPE,/*73*/
-+ MTK_PULL_PU_PD_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,/*75*/
-+ MTK_PULL_PU_PD_TYPE,/*76*/ MTK_PULL_PU_PD_TYPE,/*77*/
-+ MTK_PULL_PU_PD_TYPE,/*78*/ MTK_PULL_PU_PD_TYPE,/*79*/
-+ MTK_PULL_PU_PD_TYPE,/*80*/ MTK_PULL_PU_PD_TYPE,/*81*/
-+ MTK_PULL_PU_PD_TYPE,/*82*/ MTK_PULL_PU_PD_TYPE,/*83*/
-+ MTK_PULL_PU_PD_TYPE,/*84*/ MTK_PULL_PU_PD_TYPE,/*85*/
-+ MTK_PULL_PU_PD_TYPE,/*86*/ MTK_PULL_PU_PD_TYPE,/*87*/
-+ MTK_PULL_PU_PD_TYPE,/*88*/ MTK_PULL_PU_PD_TYPE,/*89*/
-+ MTK_PULL_PU_PD_TYPE,/*90*/ MTK_PULL_PU_PD_TYPE,/*91*/
-+ MTK_PULL_PU_PD_TYPE,/*92*/ MTK_PULL_PU_PD_TYPE,/*93*/
-+ MTK_PULL_PU_PD_TYPE,/*94*/ MTK_PULL_PU_PD_TYPE,/*95*/
-+ MTK_PULL_PU_PD_TYPE,/*96*/ MTK_PULL_PU_PD_TYPE,/*97*/
-+ MTK_PULL_PU_PD_TYPE,/*98*/ MTK_PULL_PU_PD_TYPE,/*99*/
-+ MTK_PULL_PU_PD_TYPE,/*100*/
-+};
-+
- static const struct mtk_pin_reg_calc mt7986_reg_cals[] = {
- [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range),
- [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range),
-@@ -868,6 +922,7 @@ static struct mtk_pin_soc mt7986a_data =
- .ies_present = false,
- .base_names = mt7986_pinctrl_register_base_names,
- .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
-+ .pull_type = mt7986_pull_type,
- .bias_set_combo = mtk_pinconf_bias_set_combo,
- .bias_get_combo = mtk_pinconf_bias_get_combo,
- .drive_set = mtk_pinconf_drive_set_rev1,
-@@ -889,6 +944,7 @@ static struct mtk_pin_soc mt7986b_data =
- .ies_present = false,
- .base_names = mt7986_pinctrl_register_base_names,
- .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
-+ .pull_type = mt7986_pull_type,
- .bias_set_combo = mtk_pinconf_bias_set_combo,
- .bias_get_combo = mtk_pinconf_bias_get_combo,
- .drive_set = mtk_pinconf_drive_set_rev1,
+++ /dev/null
-From 6c83b2d94fcca735cf7d8aa7a55a4957eb404a9d Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 26 Jan 2023 00:34:56 +0000
-Subject: [PATCH] pinctrl: add mt7981 pinctrl driver
-
-Add pinctrl driver for the MediaTek MT7981 SoC, based on the driver
-which can also be found the SDK.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/ef5112946d16cacc67e65e439ba7b52a9950c1bb.1674693008.git.daniel@makrotopia.org
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/mediatek/Kconfig | 5 +
- drivers/pinctrl/mediatek/Makefile | 1 +
- drivers/pinctrl/mediatek/pinctrl-mt7981.c | 1048 +++++++++++++++++++++
- 3 files changed, 1054 insertions(+)
- create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7981.c
-
---- a/drivers/pinctrl/mediatek/Kconfig
-+++ b/drivers/pinctrl/mediatek/Kconfig
-@@ -127,6 +127,11 @@ config PINCTRL_MT7622
- default ARM64 && ARCH_MEDIATEK
- select PINCTRL_MTK_MOORE
-
-+config PINCTRL_MT7981
-+ bool "Mediatek MT7981 pin control"
-+ depends on OF
-+ select PINCTRL_MTK_MOORE
-+
- config PINCTRL_MT7986
- bool "Mediatek MT7986 pin control"
- depends on OF
---- a/drivers/pinctrl/mediatek/Makefile
-+++ b/drivers/pinctrl/mediatek/Makefile
-@@ -18,6 +18,7 @@ obj-$(CONFIG_PINCTRL_MT6797) += pinctrl-
- obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o
- obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
- obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
-+obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o
- obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o
- obj-$(CONFIG_PINCTRL_MT8167) += pinctrl-mt8167.o
- obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
---- /dev/null
-+++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
-@@ -0,0 +1,1048 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * The MT7981 driver based on Linux generic pinctrl binding.
-+ *
-+ * Copyright (C) 2020 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ */
-+
-+#include "pinctrl-moore.h"
-+
-+#define MT7981_PIN(_number, _name) \
-+ MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
-+
-+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, _x_bits) \
-+ PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
-+ _x_bits, 32, 0)
-+
-+#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, _x_bits) \
-+ PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
-+ _x_bits, 32, 1)
-+
-+static const struct mtk_pin_field_calc mt7981_pin_mode_range[] = {
-+ PIN_FIELD(0, 56, 0x300, 0x10, 0, 4),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_dir_range[] = {
-+ PIN_FIELD(0, 56, 0x0, 0x10, 0, 1),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_di_range[] = {
-+ PIN_FIELD(0, 56, 0x200, 0x10, 0, 1),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_do_range[] = {
-+ PIN_FIELD(0, 56, 0x100, 0x10, 0, 1),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_ies_range[] = {
-+ PIN_FIELD_BASE(0, 0, 1, 0x10, 0x10, 1, 1),
-+ PIN_FIELD_BASE(1, 1, 1, 0x10, 0x10, 0, 1),
-+ PIN_FIELD_BASE(2, 2, 5, 0x20, 0x10, 6, 1),
-+ PIN_FIELD_BASE(3, 3, 4, 0x20, 0x10, 6, 1),
-+ PIN_FIELD_BASE(4, 4, 4, 0x20, 0x10, 2, 1),
-+ PIN_FIELD_BASE(5, 5, 4, 0x20, 0x10, 1, 1),
-+ PIN_FIELD_BASE(6, 6, 4, 0x20, 0x10, 3, 1),
-+ PIN_FIELD_BASE(7, 7, 4, 0x20, 0x10, 0, 1),
-+ PIN_FIELD_BASE(8, 8, 4, 0x20, 0x10, 4, 1),
-+
-+ PIN_FIELD_BASE(9, 9, 5, 0x20, 0x10, 9, 1),
-+ PIN_FIELD_BASE(10, 10, 5, 0x20, 0x10, 8, 1),
-+ PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1),
-+ PIN_FIELD_BASE(12, 12, 5, 0x20, 0x10, 7, 1),
-+ PIN_FIELD_BASE(13, 13, 5, 0x20, 0x10, 11, 1),
-+
-+ PIN_FIELD_BASE(14, 14, 4, 0x20, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(15, 15, 2, 0x20, 0x10, 0, 1),
-+ PIN_FIELD_BASE(16, 16, 2, 0x20, 0x10, 1, 1),
-+ PIN_FIELD_BASE(17, 17, 2, 0x20, 0x10, 5, 1),
-+ PIN_FIELD_BASE(18, 18, 2, 0x20, 0x10, 4, 1),
-+ PIN_FIELD_BASE(19, 19, 2, 0x20, 0x10, 2, 1),
-+ PIN_FIELD_BASE(20, 20, 2, 0x20, 0x10, 3, 1),
-+ PIN_FIELD_BASE(21, 21, 2, 0x20, 0x10, 6, 1),
-+ PIN_FIELD_BASE(22, 22, 2, 0x20, 0x10, 7, 1),
-+ PIN_FIELD_BASE(23, 23, 2, 0x20, 0x10, 10, 1),
-+ PIN_FIELD_BASE(24, 24, 2, 0x20, 0x10, 9, 1),
-+ PIN_FIELD_BASE(25, 25, 2, 0x20, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(26, 26, 5, 0x20, 0x10, 0, 1),
-+ PIN_FIELD_BASE(27, 27, 5, 0x20, 0x10, 4, 1),
-+ PIN_FIELD_BASE(28, 28, 5, 0x20, 0x10, 3, 1),
-+ PIN_FIELD_BASE(29, 29, 5, 0x20, 0x10, 1, 1),
-+ PIN_FIELD_BASE(30, 30, 5, 0x20, 0x10, 2, 1),
-+ PIN_FIELD_BASE(31, 31, 5, 0x20, 0x10, 5, 1),
-+
-+ PIN_FIELD_BASE(32, 32, 1, 0x10, 0x10, 2, 1),
-+ PIN_FIELD_BASE(33, 33, 1, 0x10, 0x10, 3, 1),
-+
-+ PIN_FIELD_BASE(34, 34, 4, 0x20, 0x10, 5, 1),
-+ PIN_FIELD_BASE(35, 35, 4, 0x20, 0x10, 7, 1),
-+
-+ PIN_FIELD_BASE(36, 36, 3, 0x10, 0x10, 2, 1),
-+ PIN_FIELD_BASE(37, 37, 3, 0x10, 0x10, 3, 1),
-+ PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 0, 1),
-+ PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 1, 1),
-+
-+ PIN_FIELD_BASE(40, 40, 7, 0x30, 0x10, 1, 1),
-+ PIN_FIELD_BASE(41, 41, 7, 0x30, 0x10, 0, 1),
-+ PIN_FIELD_BASE(42, 42, 7, 0x30, 0x10, 9, 1),
-+ PIN_FIELD_BASE(43, 43, 7, 0x30, 0x10, 7, 1),
-+ PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
-+ PIN_FIELD_BASE(45, 45, 7, 0x30, 0x10, 3, 1),
-+ PIN_FIELD_BASE(46, 46, 7, 0x30, 0x10, 4, 1),
-+ PIN_FIELD_BASE(47, 47, 7, 0x30, 0x10, 5, 1),
-+ PIN_FIELD_BASE(48, 48, 7, 0x30, 0x10, 6, 1),
-+ PIN_FIELD_BASE(49, 49, 7, 0x30, 0x10, 2, 1),
-+
-+ PIN_FIELD_BASE(50, 50, 6, 0x10, 0x10, 0, 1),
-+ PIN_FIELD_BASE(51, 51, 6, 0x10, 0x10, 2, 1),
-+ PIN_FIELD_BASE(52, 52, 6, 0x10, 0x10, 3, 1),
-+ PIN_FIELD_BASE(53, 53, 6, 0x10, 0x10, 4, 1),
-+ PIN_FIELD_BASE(54, 54, 6, 0x10, 0x10, 5, 1),
-+ PIN_FIELD_BASE(55, 55, 6, 0x10, 0x10, 6, 1),
-+ PIN_FIELD_BASE(56, 56, 6, 0x10, 0x10, 1, 1),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_smt_range[] = {
-+ PIN_FIELD_BASE(0, 0, 1, 0x60, 0x10, 1, 1),
-+ PIN_FIELD_BASE(1, 1, 1, 0x60, 0x10, 0, 1),
-+ PIN_FIELD_BASE(2, 2, 5, 0x90, 0x10, 6, 1),
-+ PIN_FIELD_BASE(3, 3, 4, 0x80, 0x10, 6, 1),
-+ PIN_FIELD_BASE(4, 4, 4, 0x80, 0x10, 2, 1),
-+ PIN_FIELD_BASE(5, 5, 4, 0x80, 0x10, 1, 1),
-+ PIN_FIELD_BASE(6, 6, 4, 0x80, 0x10, 3, 1),
-+ PIN_FIELD_BASE(7, 7, 4, 0x80, 0x10, 0, 1),
-+ PIN_FIELD_BASE(8, 8, 4, 0x80, 0x10, 4, 1),
-+
-+ PIN_FIELD_BASE(9, 9, 5, 0x90, 0x10, 9, 1),
-+ PIN_FIELD_BASE(10, 10, 5, 0x90, 0x10, 8, 1),
-+ PIN_FIELD_BASE(11, 11, 5, 0x90, 0x10, 10, 1),
-+ PIN_FIELD_BASE(12, 12, 5, 0x90, 0x10, 7, 1),
-+ PIN_FIELD_BASE(13, 13, 5, 0x90, 0x10, 11, 1),
-+
-+ PIN_FIELD_BASE(14, 14, 4, 0x80, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(15, 15, 2, 0x90, 0x10, 0, 1),
-+ PIN_FIELD_BASE(16, 16, 2, 0x90, 0x10, 1, 1),
-+ PIN_FIELD_BASE(17, 17, 2, 0x90, 0x10, 5, 1),
-+ PIN_FIELD_BASE(18, 18, 2, 0x90, 0x10, 4, 1),
-+ PIN_FIELD_BASE(19, 19, 2, 0x90, 0x10, 2, 1),
-+ PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
-+ PIN_FIELD_BASE(21, 21, 2, 0x90, 0x10, 6, 1),
-+ PIN_FIELD_BASE(22, 22, 2, 0x90, 0x10, 7, 1),
-+ PIN_FIELD_BASE(23, 23, 2, 0x90, 0x10, 10, 1),
-+ PIN_FIELD_BASE(24, 24, 2, 0x90, 0x10, 9, 1),
-+ PIN_FIELD_BASE(25, 25, 2, 0x90, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(26, 26, 5, 0x90, 0x10, 0, 1),
-+ PIN_FIELD_BASE(27, 27, 5, 0x90, 0x10, 4, 1),
-+ PIN_FIELD_BASE(28, 28, 5, 0x90, 0x10, 3, 1),
-+ PIN_FIELD_BASE(29, 29, 5, 0x90, 0x10, 1, 1),
-+ PIN_FIELD_BASE(30, 30, 5, 0x90, 0x10, 2, 1),
-+ PIN_FIELD_BASE(31, 31, 5, 0x90, 0x10, 5, 1),
-+
-+ PIN_FIELD_BASE(32, 32, 1, 0x60, 0x10, 2, 1),
-+ PIN_FIELD_BASE(33, 33, 1, 0x60, 0x10, 3, 1),
-+
-+ PIN_FIELD_BASE(34, 34, 4, 0x80, 0x10, 5, 1),
-+ PIN_FIELD_BASE(35, 35, 4, 0x80, 0x10, 7, 1),
-+
-+ PIN_FIELD_BASE(36, 36, 3, 0x60, 0x10, 2, 1),
-+ PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 3, 1),
-+ PIN_FIELD_BASE(38, 38, 3, 0x60, 0x10, 0, 1),
-+ PIN_FIELD_BASE(39, 39, 3, 0x60, 0x10, 1, 1),
-+
-+ PIN_FIELD_BASE(40, 40, 7, 0x70, 0x10, 1, 1),
-+ PIN_FIELD_BASE(41, 41, 7, 0x70, 0x10, 0, 1),
-+ PIN_FIELD_BASE(42, 42, 7, 0x70, 0x10, 9, 1),
-+ PIN_FIELD_BASE(43, 43, 7, 0x70, 0x10, 7, 1),
-+ PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
-+ PIN_FIELD_BASE(45, 45, 7, 0x70, 0x10, 3, 1),
-+ PIN_FIELD_BASE(46, 46, 7, 0x70, 0x10, 4, 1),
-+ PIN_FIELD_BASE(47, 47, 7, 0x70, 0x10, 5, 1),
-+ PIN_FIELD_BASE(48, 48, 7, 0x70, 0x10, 6, 1),
-+ PIN_FIELD_BASE(49, 49, 7, 0x70, 0x10, 2, 1),
-+
-+ PIN_FIELD_BASE(50, 50, 6, 0x50, 0x10, 0, 1),
-+ PIN_FIELD_BASE(51, 51, 6, 0x50, 0x10, 2, 1),
-+ PIN_FIELD_BASE(52, 52, 6, 0x50, 0x10, 3, 1),
-+ PIN_FIELD_BASE(53, 53, 6, 0x50, 0x10, 4, 1),
-+ PIN_FIELD_BASE(54, 54, 6, 0x50, 0x10, 5, 1),
-+ PIN_FIELD_BASE(55, 55, 6, 0x50, 0x10, 6, 1),
-+ PIN_FIELD_BASE(56, 56, 6, 0x50, 0x10, 1, 1),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_pu_range[] = {
-+ PIN_FIELD_BASE(40, 40, 7, 0x50, 0x10, 1, 1),
-+ PIN_FIELD_BASE(41, 41, 7, 0x50, 0x10, 0, 1),
-+ PIN_FIELD_BASE(42, 42, 7, 0x50, 0x10, 9, 1),
-+ PIN_FIELD_BASE(43, 43, 7, 0x50, 0x10, 7, 1),
-+ PIN_FIELD_BASE(44, 44, 7, 0x50, 0x10, 8, 1),
-+ PIN_FIELD_BASE(45, 45, 7, 0x50, 0x10, 3, 1),
-+ PIN_FIELD_BASE(46, 46, 7, 0x50, 0x10, 4, 1),
-+ PIN_FIELD_BASE(47, 47, 7, 0x50, 0x10, 5, 1),
-+ PIN_FIELD_BASE(48, 48, 7, 0x50, 0x10, 6, 1),
-+ PIN_FIELD_BASE(49, 49, 7, 0x50, 0x10, 2, 1),
-+
-+ PIN_FIELD_BASE(50, 50, 6, 0x30, 0x10, 0, 1),
-+ PIN_FIELD_BASE(51, 51, 6, 0x30, 0x10, 2, 1),
-+ PIN_FIELD_BASE(52, 52, 6, 0x30, 0x10, 3, 1),
-+ PIN_FIELD_BASE(53, 53, 6, 0x30, 0x10, 4, 1),
-+ PIN_FIELD_BASE(54, 54, 6, 0x30, 0x10, 5, 1),
-+ PIN_FIELD_BASE(55, 55, 6, 0x30, 0x10, 6, 1),
-+ PIN_FIELD_BASE(56, 56, 6, 0x30, 0x10, 1, 1),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_pd_range[] = {
-+ PIN_FIELD_BASE(40, 40, 7, 0x40, 0x10, 1, 1),
-+ PIN_FIELD_BASE(41, 41, 7, 0x40, 0x10, 0, 1),
-+ PIN_FIELD_BASE(42, 42, 7, 0x40, 0x10, 9, 1),
-+ PIN_FIELD_BASE(43, 43, 7, 0x40, 0x10, 7, 1),
-+ PIN_FIELD_BASE(44, 44, 7, 0x40, 0x10, 8, 1),
-+ PIN_FIELD_BASE(45, 45, 7, 0x40, 0x10, 3, 1),
-+ PIN_FIELD_BASE(46, 46, 7, 0x40, 0x10, 4, 1),
-+ PIN_FIELD_BASE(47, 47, 7, 0x40, 0x10, 5, 1),
-+ PIN_FIELD_BASE(48, 48, 7, 0x40, 0x10, 6, 1),
-+ PIN_FIELD_BASE(49, 49, 7, 0x40, 0x10, 2, 1),
-+
-+ PIN_FIELD_BASE(50, 50, 6, 0x20, 0x10, 0, 1),
-+ PIN_FIELD_BASE(51, 51, 6, 0x20, 0x10, 2, 1),
-+ PIN_FIELD_BASE(52, 52, 6, 0x20, 0x10, 3, 1),
-+ PIN_FIELD_BASE(53, 53, 6, 0x20, 0x10, 4, 1),
-+ PIN_FIELD_BASE(54, 54, 6, 0x20, 0x10, 5, 1),
-+ PIN_FIELD_BASE(55, 55, 6, 0x20, 0x10, 6, 1),
-+ PIN_FIELD_BASE(56, 56, 6, 0x20, 0x10, 1, 1),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_drv_range[] = {
-+ PIN_FIELD_BASE(0, 0, 1, 0x00, 0x10, 3, 3),
-+ PIN_FIELD_BASE(1, 1, 1, 0x00, 0x10, 0, 3),
-+
-+ PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 18, 3),
-+
-+ PIN_FIELD_BASE(3, 3, 4, 0x00, 0x10, 18, 1),
-+ PIN_FIELD_BASE(4, 4, 4, 0x00, 0x10, 6, 1),
-+ PIN_FIELD_BASE(5, 5, 4, 0x00, 0x10, 3, 3),
-+ PIN_FIELD_BASE(6, 6, 4, 0x00, 0x10, 9, 3),
-+ PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 0, 3),
-+ PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 12, 3),
-+
-+ PIN_FIELD_BASE(9, 9, 5, 0x00, 0x10, 27, 3),
-+ PIN_FIELD_BASE(10, 10, 5, 0x00, 0x10, 24, 3),
-+ PIN_FIELD_BASE(11, 11, 5, 0x00, 0x10, 0, 3),
-+ PIN_FIELD_BASE(12, 12, 5, 0x00, 0x10, 21, 3),
-+ PIN_FIELD_BASE(13, 13, 5, 0x00, 0x10, 3, 3),
-+
-+ PIN_FIELD_BASE(14, 14, 4, 0x00, 0x10, 27, 3),
-+
-+ PIN_FIELD_BASE(15, 15, 2, 0x00, 0x10, 0, 3),
-+ PIN_FIELD_BASE(16, 16, 2, 0x00, 0x10, 3, 3),
-+ PIN_FIELD_BASE(17, 17, 2, 0x00, 0x10, 15, 3),
-+ PIN_FIELD_BASE(18, 18, 2, 0x00, 0x10, 12, 3),
-+ PIN_FIELD_BASE(19, 19, 2, 0x00, 0x10, 6, 3),
-+ PIN_FIELD_BASE(20, 20, 2, 0x00, 0x10, 9, 3),
-+ PIN_FIELD_BASE(21, 21, 2, 0x00, 0x10, 18, 3),
-+ PIN_FIELD_BASE(22, 22, 2, 0x00, 0x10, 21, 3),
-+ PIN_FIELD_BASE(23, 23, 2, 0x00, 0x10, 0, 3),
-+ PIN_FIELD_BASE(24, 24, 2, 0x00, 0x10, 27, 3),
-+ PIN_FIELD_BASE(25, 25, 2, 0x00, 0x10, 24, 3),
-+
-+ PIN_FIELD_BASE(26, 26, 5, 0x00, 0x10, 0, 3),
-+ PIN_FIELD_BASE(27, 27, 5, 0x00, 0x10, 12, 3),
-+ PIN_FIELD_BASE(28, 28, 5, 0x00, 0x10, 9, 3),
-+ PIN_FIELD_BASE(29, 29, 5, 0x00, 0x10, 3, 3),
-+ PIN_FIELD_BASE(30, 30, 5, 0x00, 0x10, 6, 3),
-+ PIN_FIELD_BASE(31, 31, 5, 0x00, 0x10, 15, 3),
-+
-+ PIN_FIELD_BASE(32, 32, 1, 0x00, 0x10, 9, 3),
-+ PIN_FIELD_BASE(33, 33, 1, 0x00, 0x10, 12, 3),
-+
-+ PIN_FIELD_BASE(34, 34, 4, 0x00, 0x10, 15, 3),
-+ PIN_FIELD_BASE(35, 35, 4, 0x00, 0x10, 21, 3),
-+
-+ PIN_FIELD_BASE(36, 36, 3, 0x00, 0x10, 6, 3),
-+ PIN_FIELD_BASE(37, 37, 3, 0x00, 0x10, 9, 3),
-+ PIN_FIELD_BASE(38, 38, 3, 0x00, 0x10, 0, 3),
-+ PIN_FIELD_BASE(39, 39, 3, 0x00, 0x10, 3, 3),
-+
-+ PIN_FIELD_BASE(40, 40, 7, 0x00, 0x10, 3, 3),
-+ PIN_FIELD_BASE(41, 41, 7, 0x00, 0x10, 0, 3),
-+ PIN_FIELD_BASE(42, 42, 7, 0x00, 0x10, 27, 3),
-+ PIN_FIELD_BASE(43, 43, 7, 0x00, 0x10, 21, 3),
-+ PIN_FIELD_BASE(44, 44, 7, 0x00, 0x10, 24, 3),
-+ PIN_FIELD_BASE(45, 45, 7, 0x00, 0x10, 9, 3),
-+ PIN_FIELD_BASE(46, 46, 7, 0x00, 0x10, 12, 3),
-+ PIN_FIELD_BASE(47, 47, 7, 0x00, 0x10, 15, 3),
-+ PIN_FIELD_BASE(48, 48, 7, 0x00, 0x10, 18, 3),
-+ PIN_FIELD_BASE(49, 49, 7, 0x00, 0x10, 6, 3),
-+
-+ PIN_FIELD_BASE(50, 50, 6, 0x00, 0x10, 0, 3),
-+ PIN_FIELD_BASE(51, 51, 6, 0x00, 0x10, 6, 3),
-+ PIN_FIELD_BASE(52, 52, 6, 0x00, 0x10, 9, 3),
-+ PIN_FIELD_BASE(53, 53, 6, 0x00, 0x10, 12, 3),
-+ PIN_FIELD_BASE(54, 54, 6, 0x00, 0x10, 15, 3),
-+ PIN_FIELD_BASE(55, 55, 6, 0x00, 0x10, 18, 3),
-+ PIN_FIELD_BASE(56, 56, 6, 0x00, 0x10, 3, 3),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_pupd_range[] = {
-+ PIN_FIELD_BASE(0, 0, 1, 0x20, 0x10, 1, 1),
-+ PIN_FIELD_BASE(1, 1, 1, 0x20, 0x10, 0, 1),
-+ PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 6, 1),
-+ PIN_FIELD_BASE(3, 3, 4, 0x30, 0x10, 6, 1),
-+ PIN_FIELD_BASE(4, 4, 4, 0x30, 0x10, 2, 1),
-+ PIN_FIELD_BASE(5, 5, 4, 0x30, 0x10, 1, 1),
-+ PIN_FIELD_BASE(6, 6, 4, 0x30, 0x10, 3, 1),
-+ PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 0, 1),
-+ PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 4, 1),
-+
-+ PIN_FIELD_BASE(9, 9, 5, 0x30, 0x10, 9, 1),
-+ PIN_FIELD_BASE(10, 10, 5, 0x30, 0x10, 8, 1),
-+ PIN_FIELD_BASE(11, 11, 5, 0x30, 0x10, 10, 1),
-+ PIN_FIELD_BASE(12, 12, 5, 0x30, 0x10, 7, 1),
-+ PIN_FIELD_BASE(13, 13, 5, 0x30, 0x10, 11, 1),
-+
-+ PIN_FIELD_BASE(14, 14, 4, 0x30, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(15, 15, 2, 0x30, 0x10, 0, 1),
-+ PIN_FIELD_BASE(16, 16, 2, 0x30, 0x10, 1, 1),
-+ PIN_FIELD_BASE(17, 17, 2, 0x30, 0x10, 5, 1),
-+ PIN_FIELD_BASE(18, 18, 2, 0x30, 0x10, 4, 1),
-+ PIN_FIELD_BASE(19, 19, 2, 0x30, 0x10, 2, 1),
-+ PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
-+ PIN_FIELD_BASE(21, 21, 2, 0x30, 0x10, 6, 1),
-+ PIN_FIELD_BASE(22, 22, 2, 0x30, 0x10, 7, 1),
-+ PIN_FIELD_BASE(23, 23, 2, 0x30, 0x10, 10, 1),
-+ PIN_FIELD_BASE(24, 24, 2, 0x30, 0x10, 9, 1),
-+ PIN_FIELD_BASE(25, 25, 2, 0x30, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(26, 26, 5, 0x30, 0x10, 0, 1),
-+ PIN_FIELD_BASE(27, 27, 5, 0x30, 0x10, 4, 1),
-+ PIN_FIELD_BASE(28, 28, 5, 0x30, 0x10, 3, 1),
-+ PIN_FIELD_BASE(29, 29, 5, 0x30, 0x10, 1, 1),
-+ PIN_FIELD_BASE(30, 30, 5, 0x30, 0x10, 2, 1),
-+ PIN_FIELD_BASE(31, 31, 5, 0x30, 0x10, 5, 1),
-+
-+ PIN_FIELD_BASE(32, 32, 1, 0x20, 0x10, 2, 1),
-+ PIN_FIELD_BASE(33, 33, 1, 0x20, 0x10, 3, 1),
-+
-+ PIN_FIELD_BASE(34, 34, 4, 0x30, 0x10, 5, 1),
-+ PIN_FIELD_BASE(35, 35, 4, 0x30, 0x10, 7, 1),
-+
-+ PIN_FIELD_BASE(36, 36, 3, 0x20, 0x10, 2, 1),
-+ PIN_FIELD_BASE(37, 37, 3, 0x20, 0x10, 3, 1),
-+ PIN_FIELD_BASE(38, 38, 3, 0x20, 0x10, 0, 1),
-+ PIN_FIELD_BASE(39, 39, 3, 0x20, 0x10, 1, 1),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_r0_range[] = {
-+ PIN_FIELD_BASE(0, 0, 1, 0x30, 0x10, 1, 1),
-+ PIN_FIELD_BASE(1, 1, 1, 0x30, 0x10, 0, 1),
-+ PIN_FIELD_BASE(2, 2, 5, 0x40, 0x10, 6, 1),
-+ PIN_FIELD_BASE(3, 3, 4, 0x40, 0x10, 6, 1),
-+ PIN_FIELD_BASE(4, 4, 4, 0x40, 0x10, 2, 1),
-+ PIN_FIELD_BASE(5, 5, 4, 0x40, 0x10, 1, 1),
-+ PIN_FIELD_BASE(6, 6, 4, 0x40, 0x10, 3, 1),
-+ PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 0, 1),
-+ PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
-+
-+ PIN_FIELD_BASE(9, 9, 5, 0x40, 0x10, 9, 1),
-+ PIN_FIELD_BASE(10, 10, 5, 0x40, 0x10, 8, 1),
-+ PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1),
-+ PIN_FIELD_BASE(12, 12, 5, 0x40, 0x10, 7, 1),
-+ PIN_FIELD_BASE(13, 13, 5, 0x40, 0x10, 11, 1),
-+
-+ PIN_FIELD_BASE(14, 14, 4, 0x40, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(15, 15, 2, 0x40, 0x10, 0, 1),
-+ PIN_FIELD_BASE(16, 16, 2, 0x40, 0x10, 1, 1),
-+ PIN_FIELD_BASE(17, 17, 2, 0x40, 0x10, 5, 1),
-+ PIN_FIELD_BASE(18, 18, 2, 0x40, 0x10, 4, 1),
-+ PIN_FIELD_BASE(19, 19, 2, 0x40, 0x10, 2, 1),
-+ PIN_FIELD_BASE(20, 20, 2, 0x40, 0x10, 3, 1),
-+ PIN_FIELD_BASE(21, 21, 2, 0x40, 0x10, 6, 1),
-+ PIN_FIELD_BASE(22, 22, 2, 0x40, 0x10, 7, 1),
-+ PIN_FIELD_BASE(23, 23, 2, 0x40, 0x10, 10, 1),
-+ PIN_FIELD_BASE(24, 24, 2, 0x40, 0x10, 9, 1),
-+ PIN_FIELD_BASE(25, 25, 2, 0x40, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(26, 26, 5, 0x40, 0x10, 0, 1),
-+ PIN_FIELD_BASE(27, 27, 5, 0x40, 0x10, 4, 1),
-+ PIN_FIELD_BASE(28, 28, 5, 0x40, 0x10, 3, 1),
-+ PIN_FIELD_BASE(29, 29, 5, 0x40, 0x10, 1, 1),
-+ PIN_FIELD_BASE(30, 30, 5, 0x40, 0x10, 2, 1),
-+ PIN_FIELD_BASE(31, 31, 5, 0x40, 0x10, 5, 1),
-+
-+ PIN_FIELD_BASE(32, 32, 1, 0x30, 0x10, 2, 1),
-+ PIN_FIELD_BASE(33, 33, 1, 0x30, 0x10, 3, 1),
-+
-+ PIN_FIELD_BASE(34, 34, 4, 0x40, 0x10, 5, 1),
-+ PIN_FIELD_BASE(35, 35, 4, 0x40, 0x10, 7, 1),
-+
-+ PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 2, 1),
-+ PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 3, 1),
-+ PIN_FIELD_BASE(38, 38, 3, 0x30, 0x10, 0, 1),
-+ PIN_FIELD_BASE(39, 39, 3, 0x30, 0x10, 1, 1),
-+};
-+
-+static const struct mtk_pin_field_calc mt7981_pin_r1_range[] = {
-+ PIN_FIELD_BASE(0, 0, 1, 0x40, 0x10, 1, 1),
-+ PIN_FIELD_BASE(1, 1, 1, 0x40, 0x10, 0, 1),
-+ PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 6, 1),
-+ PIN_FIELD_BASE(3, 3, 4, 0x50, 0x10, 6, 1),
-+ PIN_FIELD_BASE(4, 4, 4, 0x50, 0x10, 2, 1),
-+ PIN_FIELD_BASE(5, 5, 4, 0x50, 0x10, 1, 1),
-+ PIN_FIELD_BASE(6, 6, 4, 0x50, 0x10, 3, 1),
-+ PIN_FIELD_BASE(7, 7, 4, 0x50, 0x10, 0, 1),
-+ PIN_FIELD_BASE(8, 8, 4, 0x50, 0x10, 4, 1),
-+
-+ PIN_FIELD_BASE(9, 9, 5, 0x50, 0x10, 9, 1),
-+ PIN_FIELD_BASE(10, 10, 5, 0x50, 0x10, 8, 1),
-+ PIN_FIELD_BASE(11, 11, 5, 0x50, 0x10, 10, 1),
-+ PIN_FIELD_BASE(12, 12, 5, 0x50, 0x10, 7, 1),
-+ PIN_FIELD_BASE(13, 13, 5, 0x50, 0x10, 11, 1),
-+
-+ PIN_FIELD_BASE(14, 14, 4, 0x50, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(15, 15, 2, 0x50, 0x10, 0, 1),
-+ PIN_FIELD_BASE(16, 16, 2, 0x50, 0x10, 1, 1),
-+ PIN_FIELD_BASE(17, 17, 2, 0x50, 0x10, 5, 1),
-+ PIN_FIELD_BASE(18, 18, 2, 0x50, 0x10, 4, 1),
-+ PIN_FIELD_BASE(19, 19, 2, 0x50, 0x10, 2, 1),
-+ PIN_FIELD_BASE(20, 20, 2, 0x50, 0x10, 3, 1),
-+ PIN_FIELD_BASE(21, 21, 2, 0x50, 0x10, 6, 1),
-+ PIN_FIELD_BASE(22, 22, 2, 0x50, 0x10, 7, 1),
-+ PIN_FIELD_BASE(23, 23, 2, 0x50, 0x10, 10, 1),
-+ PIN_FIELD_BASE(24, 24, 2, 0x50, 0x10, 9, 1),
-+ PIN_FIELD_BASE(25, 25, 2, 0x50, 0x10, 8, 1),
-+
-+ PIN_FIELD_BASE(26, 26, 5, 0x50, 0x10, 0, 1),
-+ PIN_FIELD_BASE(27, 27, 5, 0x50, 0x10, 4, 1),
-+ PIN_FIELD_BASE(28, 28, 5, 0x50, 0x10, 3, 1),
-+ PIN_FIELD_BASE(29, 29, 5, 0x50, 0x10, 1, 1),
-+ PIN_FIELD_BASE(30, 30, 5, 0x50, 0x10, 2, 1),
-+ PIN_FIELD_BASE(31, 31, 5, 0x50, 0x10, 5, 1),
-+
-+ PIN_FIELD_BASE(32, 32, 1, 0x40, 0x10, 2, 1),
-+ PIN_FIELD_BASE(33, 33, 1, 0x40, 0x10, 3, 1),
-+
-+ PIN_FIELD_BASE(34, 34, 4, 0x50, 0x10, 5, 1),
-+ PIN_FIELD_BASE(35, 35, 4, 0x50, 0x10, 7, 1),
-+
-+ PIN_FIELD_BASE(36, 36, 3, 0x40, 0x10, 2, 1),
-+ PIN_FIELD_BASE(37, 37, 3, 0x40, 0x10, 3, 1),
-+ PIN_FIELD_BASE(38, 38, 3, 0x40, 0x10, 0, 1),
-+ PIN_FIELD_BASE(39, 39, 3, 0x40, 0x10, 1, 1),
-+};
-+
-+static const unsigned int mt7981_pull_type[] = {
-+ MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PUPD_R1R0_TYPE,/*7*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*8*/ MTK_PULL_PUPD_R1R0_TYPE,/*9*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PUPD_R1R0_TYPE,/*13*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*14*/ MTK_PULL_PUPD_R1R0_TYPE,/*15*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*16*/ MTK_PULL_PUPD_R1R0_TYPE,/*17*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PUPD_R1R0_TYPE,/*63*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
-+ MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PU_PD_TYPE,/*69*/
-+ MTK_PULL_PU_PD_TYPE,/*70*/ MTK_PULL_PU_PD_TYPE,/*71*/
-+ MTK_PULL_PU_PD_TYPE,/*72*/ MTK_PULL_PU_PD_TYPE,/*73*/
-+ MTK_PULL_PU_PD_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,/*75*/
-+ MTK_PULL_PU_PD_TYPE,/*76*/ MTK_PULL_PU_PD_TYPE,/*77*/
-+ MTK_PULL_PU_PD_TYPE,/*78*/ MTK_PULL_PU_PD_TYPE,/*79*/
-+ MTK_PULL_PU_PD_TYPE,/*80*/ MTK_PULL_PU_PD_TYPE,/*81*/
-+ MTK_PULL_PU_PD_TYPE,/*82*/ MTK_PULL_PU_PD_TYPE,/*83*/
-+ MTK_PULL_PU_PD_TYPE,/*84*/ MTK_PULL_PU_PD_TYPE,/*85*/
-+ MTK_PULL_PU_PD_TYPE,/*86*/ MTK_PULL_PU_PD_TYPE,/*87*/
-+ MTK_PULL_PU_PD_TYPE,/*88*/ MTK_PULL_PU_PD_TYPE,/*89*/
-+ MTK_PULL_PU_PD_TYPE,/*90*/ MTK_PULL_PU_PD_TYPE,/*91*/
-+ MTK_PULL_PU_PD_TYPE,/*92*/ MTK_PULL_PU_PD_TYPE,/*93*/
-+ MTK_PULL_PU_PD_TYPE,/*94*/ MTK_PULL_PU_PD_TYPE,/*95*/
-+ MTK_PULL_PU_PD_TYPE,/*96*/ MTK_PULL_PU_PD_TYPE,/*97*/
-+ MTK_PULL_PU_PD_TYPE,/*98*/ MTK_PULL_PU_PD_TYPE,/*99*/
-+ MTK_PULL_PU_PD_TYPE,/*100*/
-+};
-+
-+static const struct mtk_pin_reg_calc mt7981_reg_cals[] = {
-+ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7981_pin_mode_range),
-+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7981_pin_dir_range),
-+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7981_pin_di_range),
-+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7981_pin_do_range),
-+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7981_pin_smt_range),
-+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7981_pin_ies_range),
-+ [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7981_pin_pu_range),
-+ [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7981_pin_pd_range),
-+ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7981_pin_drv_range),
-+ [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7981_pin_pupd_range),
-+ [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7981_pin_r0_range),
-+ [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7981_pin_r1_range),
-+};
-+
-+static const struct mtk_pin_desc mt7981_pins[] = {
-+ MT7981_PIN(0, "GPIO_WPS"),
-+ MT7981_PIN(1, "GPIO_RESET"),
-+ MT7981_PIN(2, "SYS_WATCHDOG"),
-+ MT7981_PIN(3, "PCIE_PERESET_N"),
-+ MT7981_PIN(4, "JTAG_JTDO"),
-+ MT7981_PIN(5, "JTAG_JTDI"),
-+ MT7981_PIN(6, "JTAG_JTMS"),
-+ MT7981_PIN(7, "JTAG_JTCLK"),
-+ MT7981_PIN(8, "JTAG_JTRST_N"),
-+ MT7981_PIN(9, "WO_JTAG_JTDO"),
-+ MT7981_PIN(10, "WO_JTAG_JTDI"),
-+ MT7981_PIN(11, "WO_JTAG_JTMS"),
-+ MT7981_PIN(12, "WO_JTAG_JTCLK"),
-+ MT7981_PIN(13, "WO_JTAG_JTRST_N"),
-+ MT7981_PIN(14, "USB_VBUS"),
-+ MT7981_PIN(15, "PWM0"),
-+ MT7981_PIN(16, "SPI0_CLK"),
-+ MT7981_PIN(17, "SPI0_MOSI"),
-+ MT7981_PIN(18, "SPI0_MISO"),
-+ MT7981_PIN(19, "SPI0_CS"),
-+ MT7981_PIN(20, "SPI0_HOLD"),
-+ MT7981_PIN(21, "SPI0_WP"),
-+ MT7981_PIN(22, "SPI1_CLK"),
-+ MT7981_PIN(23, "SPI1_MOSI"),
-+ MT7981_PIN(24, "SPI1_MISO"),
-+ MT7981_PIN(25, "SPI1_CS"),
-+ MT7981_PIN(26, "SPI2_CLK"),
-+ MT7981_PIN(27, "SPI2_MOSI"),
-+ MT7981_PIN(28, "SPI2_MISO"),
-+ MT7981_PIN(29, "SPI2_CS"),
-+ MT7981_PIN(30, "SPI2_HOLD"),
-+ MT7981_PIN(31, "SPI2_WP"),
-+ MT7981_PIN(32, "UART0_RXD"),
-+ MT7981_PIN(33, "UART0_TXD"),
-+ MT7981_PIN(34, "PCIE_CLK_REQ"),
-+ MT7981_PIN(35, "PCIE_WAKE_N"),
-+ MT7981_PIN(36, "SMI_MDC"),
-+ MT7981_PIN(37, "SMI_MDIO"),
-+ MT7981_PIN(38, "GBE_INT"),
-+ MT7981_PIN(39, "GBE_RESET"),
-+ MT7981_PIN(40, "WF_DIG_RESETB"),
-+ MT7981_PIN(41, "WF_CBA_RESETB"),
-+ MT7981_PIN(42, "WF_XO_REQ"),
-+ MT7981_PIN(43, "WF_TOP_CLK"),
-+ MT7981_PIN(44, "WF_TOP_DATA"),
-+ MT7981_PIN(45, "WF_HB1"),
-+ MT7981_PIN(46, "WF_HB2"),
-+ MT7981_PIN(47, "WF_HB3"),
-+ MT7981_PIN(48, "WF_HB4"),
-+ MT7981_PIN(49, "WF_HB0"),
-+ MT7981_PIN(50, "WF_HB0_B"),
-+ MT7981_PIN(51, "WF_HB5"),
-+ MT7981_PIN(52, "WF_HB6"),
-+ MT7981_PIN(53, "WF_HB7"),
-+ MT7981_PIN(54, "WF_HB8"),
-+ MT7981_PIN(55, "WF_HB9"),
-+ MT7981_PIN(56, "WF_HB10"),
-+};
-+
-+/* List all groups consisting of these pins dedicated to the enablement of
-+ * certain hardware block and the corresponding mode for all of the pins.
-+ * The hardware probably has multiple combinations of these pinouts.
-+ */
-+
-+/* WA_AICE */
-+static int mt7981_wa_aice1_pins[] = { 0, 1, };
-+static int mt7981_wa_aice1_funcs[] = { 2, 2, };
-+
-+static int mt7981_wa_aice2_pins[] = { 0, 1, };
-+static int mt7981_wa_aice2_funcs[] = { 3, 3, };
-+
-+static int mt7981_wa_aice3_pins[] = { 28, 29, };
-+static int mt7981_wa_aice3_funcs[] = { 3, 3, };
-+
-+static int mt7981_wm_aice1_pins[] = { 9, 10, };
-+static int mt7981_wm_aice1_funcs[] = { 2, 2, };
-+
-+static int mt7981_wm_aice2_pins[] = { 30, 31, };
-+static int mt7981_wm_aice2_funcs[] = { 5, 5, };
-+
-+/* WM_UART */
-+static int mt7981_wm_uart_0_pins[] = { 0, 1, };
-+static int mt7981_wm_uart_0_funcs[] = { 5, 5, };
-+
-+static int mt7981_wm_uart_1_pins[] = { 20, 21, };
-+static int mt7981_wm_uart_1_funcs[] = { 4, 4, };
-+
-+static int mt7981_wm_uart_2_pins[] = { 30, 31, };
-+static int mt7981_wm_uart_2_funcs[] = { 3, 3, };
-+
-+/* DFD */
-+static int mt7981_dfd_pins[] = { 0, 1, 4, 5, };
-+static int mt7981_dfd_funcs[] = { 5, 5, 6, 6, };
-+
-+/* SYS_WATCHDOG */
-+static int mt7981_watchdog_pins[] = { 2, };
-+static int mt7981_watchdog_funcs[] = { 1, };
-+
-+static int mt7981_watchdog1_pins[] = { 13, };
-+static int mt7981_watchdog1_funcs[] = { 5, };
-+
-+/* PCIE_PERESET_N */
-+static int mt7981_pcie_pereset_pins[] = { 3, };
-+static int mt7981_pcie_pereset_funcs[] = { 1, };
-+
-+/* JTAG */
-+static int mt7981_jtag_pins[] = { 4, 5, 6, 7, 8, };
-+static int mt7981_jtag_funcs[] = { 1, 1, 1, 1, 1, };
-+
-+/* WM_JTAG */
-+static int mt7981_wm_jtag_0_pins[] = { 4, 5, 6, 7, 8, };
-+static int mt7981_wm_jtag_0_funcs[] = { 2, 2, 2, 2, 2, };
-+
-+static int mt7981_wm_jtag_1_pins[] = { 20, 21, 22, 23, 24, };
-+static int mt7981_wm_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
-+
-+/* WO0_JTAG */
-+static int mt7981_wo0_jtag_0_pins[] = { 9, 10, 11, 12, 13, };
-+static int mt7981_wo0_jtag_0_funcs[] = { 1, 1, 1, 1, 1, };
-+
-+static int mt7981_wo0_jtag_1_pins[] = { 25, 26, 27, 28, 29, };
-+static int mt7981_wo0_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
-+
-+/* UART2 */
-+static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, };
-+static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, };
-+
-+/* GBE_LED0 */
-+static int mt7981_gbe_led0_pins[] = { 8, };
-+static int mt7981_gbe_led0_funcs[] = { 3, };
-+
-+/* PTA_EXT */
-+static int mt7981_pta_ext_0_pins[] = { 4, 5, 6, };
-+static int mt7981_pta_ext_0_funcs[] = { 4, 4, 4, };
-+
-+static int mt7981_pta_ext_1_pins[] = { 22, 23, 24, };
-+static int mt7981_pta_ext_1_funcs[] = { 4, 4, 4, };
-+
-+/* PWM2 */
-+static int mt7981_pwm2_pins[] = { 7, };
-+static int mt7981_pwm2_funcs[] = { 4, };
-+
-+/* NET_WO0_UART_TXD */
-+static int mt7981_net_wo0_uart_txd_0_pins[] = { 8, };
-+static int mt7981_net_wo0_uart_txd_0_funcs[] = { 4, };
-+
-+static int mt7981_net_wo0_uart_txd_1_pins[] = { 14, };
-+static int mt7981_net_wo0_uart_txd_1_funcs[] = { 3, };
-+
-+static int mt7981_net_wo0_uart_txd_2_pins[] = { 15, };
-+static int mt7981_net_wo0_uart_txd_2_funcs[] = { 4, };
-+
-+/* SPI1 */
-+static int mt7981_spi1_0_pins[] = { 4, 5, 6, 7, };
-+static int mt7981_spi1_0_funcs[] = { 5, 5, 5, 5, };
-+
-+/* I2C */
-+static int mt7981_i2c0_0_pins[] = { 6, 7, };
-+static int mt7981_i2c0_0_funcs[] = { 6, 6, };
-+
-+static int mt7981_i2c0_1_pins[] = { 30, 31, };
-+static int mt7981_i2c0_1_funcs[] = { 4, 4, };
-+
-+static int mt7981_i2c0_2_pins[] = { 36, 37, };
-+static int mt7981_i2c0_2_funcs[] = { 2, 2, };
-+
-+static int mt7981_u2_phy_i2c_pins[] = { 30, 31, };
-+static int mt7981_u2_phy_i2c_funcs[] = { 6, 6, };
-+
-+static int mt7981_u3_phy_i2c_pins[] = { 32, 33, };
-+static int mt7981_u3_phy_i2c_funcs[] = { 3, 3, };
-+
-+static int mt7981_sgmii1_phy_i2c_pins[] = { 32, 33, };
-+static int mt7981_sgmii1_phy_i2c_funcs[] = { 2, 2, };
-+
-+static int mt7981_sgmii0_phy_i2c_pins[] = { 32, 33, };
-+static int mt7981_sgmii0_phy_i2c_funcs[] = { 5, 5, };
-+
-+/* DFD_NTRST */
-+static int mt7981_dfd_ntrst_pins[] = { 8, };
-+static int mt7981_dfd_ntrst_funcs[] = { 6, };
-+
-+/* PWM0 */
-+static int mt7981_pwm0_0_pins[] = { 13, };
-+static int mt7981_pwm0_0_funcs[] = { 2, };
-+
-+static int mt7981_pwm0_1_pins[] = { 15, };
-+static int mt7981_pwm0_1_funcs[] = { 1, };
-+
-+/* PWM1 */
-+static int mt7981_pwm1_0_pins[] = { 14, };
-+static int mt7981_pwm1_0_funcs[] = { 2, };
-+
-+static int mt7981_pwm1_1_pins[] = { 15, };
-+static int mt7981_pwm1_1_funcs[] = { 3, };
-+
-+/* GBE_LED1 */
-+static int mt7981_gbe_led1_pins[] = { 13, };
-+static int mt7981_gbe_led1_funcs[] = { 3, };
-+
-+/* PCM */
-+static int mt7981_pcm_pins[] = { 9, 10, 11, 12, 13, 25 };
-+static int mt7981_pcm_funcs[] = { 4, 4, 4, 4, 4, 4, };
-+
-+/* UDI */
-+static int mt7981_udi_pins[] = { 9, 10, 11, 12, 13, };
-+static int mt7981_udi_funcs[] = { 6, 6, 6, 6, 6, };
-+
-+/* DRV_VBUS */
-+static int mt7981_drv_vbus_pins[] = { 14, };
-+static int mt7981_drv_vbus_funcs[] = { 1, };
-+
-+/* EMMC */
-+static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, };
-+static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
-+
-+/* SNFI */
-+static int mt7981_snfi_pins[] = { 16, 17, 18, 19, 20, 21, };
-+static int mt7981_snfi_funcs[] = { 3, 3, 3, 3, 3, 3, };
-+
-+/* SPI0 */
-+static int mt7981_spi0_pins[] = { 16, 17, 18, 19, };
-+static int mt7981_spi0_funcs[] = { 1, 1, 1, 1, };
-+
-+/* SPI0 */
-+static int mt7981_spi0_wp_hold_pins[] = { 20, 21, };
-+static int mt7981_spi0_wp_hold_funcs[] = { 1, 1, };
-+
-+/* SPI1 */
-+static int mt7981_spi1_1_pins[] = { 22, 23, 24, 25, };
-+static int mt7981_spi1_1_funcs[] = { 1, 1, 1, 1, };
-+
-+/* SPI2 */
-+static int mt7981_spi2_pins[] = { 26, 27, 28, 29, };
-+static int mt7981_spi2_funcs[] = { 1, 1, 1, 1, };
-+
-+/* SPI2 */
-+static int mt7981_spi2_wp_hold_pins[] = { 30, 31, };
-+static int mt7981_spi2_wp_hold_funcs[] = { 1, 1, };
-+
-+/* UART1 */
-+static int mt7981_uart1_0_pins[] = { 16, 17, 18, 19, };
-+static int mt7981_uart1_0_funcs[] = { 4, 4, 4, 4, };
-+
-+static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, };
-+static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, };
-+
-+/* UART2 */
-+static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, };
-+static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, };
-+
-+/* UART0 */
-+static int mt7981_uart0_pins[] = { 32, 33, };
-+static int mt7981_uart0_funcs[] = { 1, 1, };
-+
-+/* PCIE_CLK_REQ */
-+static int mt7981_pcie_clk_pins[] = { 34, };
-+static int mt7981_pcie_clk_funcs[] = { 2, };
-+
-+/* PCIE_WAKE_N */
-+static int mt7981_pcie_wake_pins[] = { 35, };
-+static int mt7981_pcie_wake_funcs[] = { 2, };
-+
-+/* MDC_MDIO */
-+static int mt7981_smi_mdc_mdio_pins[] = { 36, 37, };
-+static int mt7981_smi_mdc_mdio_funcs[] = { 1, 1, };
-+
-+static int mt7981_gbe_ext_mdc_mdio_pins[] = { 36, 37, };
-+static int mt7981_gbe_ext_mdc_mdio_funcs[] = { 3, 3, };
-+
-+/* WF0_MODE1 */
-+static int mt7981_wf0_mode1_pins[] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 };
-+static int mt7981_wf0_mode1_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
-+
-+/* WF0_MODE3 */
-+static int mt7981_wf0_mode3_pins[] = { 45, 46, 47, 48, 49, 51 };
-+static int mt7981_wf0_mode3_funcs[] = { 2, 2, 2, 2, 2, 2 };
-+
-+/* WF2G_LED */
-+static int mt7981_wf2g_led0_pins[] = { 30, };
-+static int mt7981_wf2g_led0_funcs[] = { 2, };
-+
-+static int mt7981_wf2g_led1_pins[] = { 34, };
-+static int mt7981_wf2g_led1_funcs[] = { 1, };
-+
-+/* WF5G_LED */
-+static int mt7981_wf5g_led0_pins[] = { 31, };
-+static int mt7981_wf5g_led0_funcs[] = { 2, };
-+
-+static int mt7981_wf5g_led1_pins[] = { 35, };
-+static int mt7981_wf5g_led1_funcs[] = { 1, };
-+
-+/* MT7531_INT */
-+static int mt7981_mt7531_int_pins[] = { 38, };
-+static int mt7981_mt7531_int_funcs[] = { 1, };
-+
-+/* ANT_SEL */
-+static int mt7981_ant_sel_pins[] = { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 34, 35 };
-+static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
-+
-+static const struct group_desc mt7981_groups[] = {
-+ /* @GPIO(0,1): WA_AICE(2) */
-+ PINCTRL_PIN_GROUP("wa_aice1", mt7981_wa_aice1),
-+ /* @GPIO(0,1): WA_AICE(3) */
-+ PINCTRL_PIN_GROUP("wa_aice2", mt7981_wa_aice2),
-+ /* @GPIO(0,1): WM_UART(5) */
-+ PINCTRL_PIN_GROUP("wm_uart_0", mt7981_wm_uart_0),
-+ /* @GPIO(0,1,4,5): DFD(6) */
-+ PINCTRL_PIN_GROUP("dfd", mt7981_dfd),
-+ /* @GPIO(2): SYS_WATCHDOG(1) */
-+ PINCTRL_PIN_GROUP("watchdog", mt7981_watchdog),
-+ /* @GPIO(3): PCIE_PERESET_N(1) */
-+ PINCTRL_PIN_GROUP("pcie_pereset", mt7981_pcie_pereset),
-+ /* @GPIO(4,8) JTAG(1) */
-+ PINCTRL_PIN_GROUP("jtag", mt7981_jtag),
-+ /* @GPIO(4,8) WM_JTAG(2) */
-+ PINCTRL_PIN_GROUP("wm_jtag_0", mt7981_wm_jtag_0),
-+ /* @GPIO(9,13) WO0_JTAG(1) */
-+ PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0),
-+ /* @GPIO(4,7) WM_JTAG(3) */
-+ PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0),
-+ /* @GPIO(8) GBE_LED0(3) */
-+ PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0),
-+ /* @GPIO(4,6) PTA_EXT(4) */
-+ PINCTRL_PIN_GROUP("pta_ext_0", mt7981_pta_ext_0),
-+ /* @GPIO(7) PWM2(4) */
-+ PINCTRL_PIN_GROUP("pwm2", mt7981_pwm2),
-+ /* @GPIO(8) NET_WO0_UART_TXD(4) */
-+ PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7981_net_wo0_uart_txd_0),
-+ /* @GPIO(4,7) SPI1(5) */
-+ PINCTRL_PIN_GROUP("spi1_0", mt7981_spi1_0),
-+ /* @GPIO(6,7) I2C(5) */
-+ PINCTRL_PIN_GROUP("i2c0_0", mt7981_i2c0_0),
-+ /* @GPIO(0,1,4,5): DFD_NTRST(6) */
-+ PINCTRL_PIN_GROUP("dfd_ntrst", mt7981_dfd_ntrst),
-+ /* @GPIO(9,10): WM_AICE(2) */
-+ PINCTRL_PIN_GROUP("wm_aice1", mt7981_wm_aice1),
-+ /* @GPIO(13): PWM0(2) */
-+ PINCTRL_PIN_GROUP("pwm0_0", mt7981_pwm0_0),
-+ /* @GPIO(15): PWM0(1) */
-+ PINCTRL_PIN_GROUP("pwm0_1", mt7981_pwm0_1),
-+ /* @GPIO(14): PWM1(2) */
-+ PINCTRL_PIN_GROUP("pwm1_0", mt7981_pwm1_0),
-+ /* @GPIO(15): PWM1(3) */
-+ PINCTRL_PIN_GROUP("pwm1_1", mt7981_pwm1_1),
-+ /* @GPIO(14) NET_WO0_UART_TXD(3) */
-+ PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7981_net_wo0_uart_txd_1),
-+ /* @GPIO(15) NET_WO0_UART_TXD(4) */
-+ PINCTRL_PIN_GROUP("net_wo0_uart_txd_2", mt7981_net_wo0_uart_txd_2),
-+ /* @GPIO(13) GBE_LED0(3) */
-+ PINCTRL_PIN_GROUP("gbe_led1", mt7981_gbe_led1),
-+ /* @GPIO(9,13) PCM(4) */
-+ PINCTRL_PIN_GROUP("pcm", mt7981_pcm),
-+ /* @GPIO(13): SYS_WATCHDOG1(5) */
-+ PINCTRL_PIN_GROUP("watchdog1", mt7981_watchdog1),
-+ /* @GPIO(9,13) UDI(4) */
-+ PINCTRL_PIN_GROUP("udi", mt7981_udi),
-+ /* @GPIO(14) DRV_VBUS(1) */
-+ PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus),
-+ /* @GPIO(15,25): EMMC(2) */
-+ PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45),
-+ /* @GPIO(16,21): SNFI(3) */
-+ PINCTRL_PIN_GROUP("snfi", mt7981_snfi),
-+ /* @GPIO(16,19): SPI0(1) */
-+ PINCTRL_PIN_GROUP("spi0", mt7981_spi0),
-+ /* @GPIO(20,21): SPI0(1) */
-+ PINCTRL_PIN_GROUP("spi0_wp_hold", mt7981_spi0_wp_hold),
-+ /* @GPIO(22,25) SPI1(1) */
-+ PINCTRL_PIN_GROUP("spi1_1", mt7981_spi1_1),
-+ /* @GPIO(26,29): SPI2(1) */
-+ PINCTRL_PIN_GROUP("spi2", mt7981_spi2),
-+ /* @GPIO(30,31): SPI0(1) */
-+ PINCTRL_PIN_GROUP("spi2_wp_hold", mt7981_spi2_wp_hold),
-+ /* @GPIO(16,19): UART1(4) */
-+ PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0),
-+ /* @GPIO(26,29): UART1(2) */
-+ PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1),
-+ /* @GPIO(22,25): UART1(3) */
-+ PINCTRL_PIN_GROUP("uart2_1", mt7981_uart2_1),
-+ /* @GPIO(22,24) PTA_EXT(4) */
-+ PINCTRL_PIN_GROUP("pta_ext_1", mt7981_pta_ext_1),
-+ /* @GPIO(20,21): WM_UART(4) */
-+ PINCTRL_PIN_GROUP("wm_aurt_1", mt7981_wm_uart_1),
-+ /* @GPIO(30,31): WM_UART(3) */
-+ PINCTRL_PIN_GROUP("wm_aurt_2", mt7981_wm_uart_2),
-+ /* @GPIO(20,24) WM_JTAG(5) */
-+ PINCTRL_PIN_GROUP("wm_jtag_1", mt7981_wm_jtag_1),
-+ /* @GPIO(25,29) WO0_JTAG(5) */
-+ PINCTRL_PIN_GROUP("wo0_jtag_1", mt7981_wo0_jtag_1),
-+ /* @GPIO(28,29): WA_AICE(3) */
-+ PINCTRL_PIN_GROUP("wa_aice3", mt7981_wa_aice3),
-+ /* @GPIO(30,31): WM_AICE(5) */
-+ PINCTRL_PIN_GROUP("wm_aice2", mt7981_wm_aice2),
-+ /* @GPIO(30,31): I2C(4) */
-+ PINCTRL_PIN_GROUP("i2c0_1", mt7981_i2c0_1),
-+ /* @GPIO(30,31): I2C(6) */
-+ PINCTRL_PIN_GROUP("u2_phy_i2c", mt7981_u2_phy_i2c),
-+ /* @GPIO(32,33): I2C(1) */
-+ PINCTRL_PIN_GROUP("uart0", mt7981_uart0),
-+ /* @GPIO(32,33): I2C(2) */
-+ PINCTRL_PIN_GROUP("sgmii1_phy_i2c", mt7981_sgmii1_phy_i2c),
-+ /* @GPIO(32,33): I2C(3) */
-+ PINCTRL_PIN_GROUP("u3_phy_i2c", mt7981_u3_phy_i2c),
-+ /* @GPIO(32,33): I2C(5) */
-+ PINCTRL_PIN_GROUP("sgmii0_phy_i2c", mt7981_sgmii0_phy_i2c),
-+ /* @GPIO(34): PCIE_CLK_REQ(2) */
-+ PINCTRL_PIN_GROUP("pcie_clk", mt7981_pcie_clk),
-+ /* @GPIO(35): PCIE_WAKE_N(2) */
-+ PINCTRL_PIN_GROUP("pcie_wake", mt7981_pcie_wake),
-+ /* @GPIO(36,37): I2C(2) */
-+ PINCTRL_PIN_GROUP("i2c0_2", mt7981_i2c0_2),
-+ /* @GPIO(36,37): MDC_MDIO(1) */
-+ PINCTRL_PIN_GROUP("smi_mdc_mdio", mt7981_smi_mdc_mdio),
-+ /* @GPIO(36,37): MDC_MDIO(3) */
-+ PINCTRL_PIN_GROUP("gbe_ext_mdc_mdio", mt7981_gbe_ext_mdc_mdio),
-+ /* @GPIO(69,85): WF0_MODE1(1) */
-+ PINCTRL_PIN_GROUP("wf0_mode1", mt7981_wf0_mode1),
-+ /* @GPIO(74,80): WF0_MODE3(3) */
-+ PINCTRL_PIN_GROUP("wf0_mode3", mt7981_wf0_mode3),
-+ /* @GPIO(30): WF2G_LED(2) */
-+ PINCTRL_PIN_GROUP("wf2g_led0", mt7981_wf2g_led0),
-+ /* @GPIO(34): WF2G_LED(1) */
-+ PINCTRL_PIN_GROUP("wf2g_led1", mt7981_wf2g_led1),
-+ /* @GPIO(31): WF5G_LED(2) */
-+ PINCTRL_PIN_GROUP("wf5g_led0", mt7981_wf5g_led0),
-+ /* @GPIO(35): WF5G_LED(1) */
-+ PINCTRL_PIN_GROUP("wf5g_led1", mt7981_wf5g_led1),
-+ /* @GPIO(38): MT7531_INT(1) */
-+ PINCTRL_PIN_GROUP("mt7531_int", mt7981_mt7531_int),
-+ /* @GPIO(14,15,26,17,18,19,20,21,22,23,24,25,34,35): ANT_SEL(1) */
-+ PINCTRL_PIN_GROUP("ant_sel", mt7981_ant_sel),
-+};
-+
-+/* Joint those groups owning the same capability in user point of view which
-+ * allows that people tend to use through the device tree.
-+ */
-+static const char *mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", "wm_aice1_1",
-+ "wa_aice3", "wm_aice1_2", };
-+static const char *mt7981_uart_groups[] = { "wm_uart_0", "uart2_0",
-+ "net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2",
-+ "uart1_0", "uart1_1", "uart2_1", "wm_aurt_1", "wm_aurt_2", "uart0", };
-+static const char *mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", };
-+static const char *mt7981_wdt_groups[] = { "watchdog", "watchdog1", };
-+static const char *mt7981_pcie_groups[] = { "pcie_pereset", "pcie_clk", "pcie_wake", };
-+static const char *mt7981_jtag_groups[] = { "jtag", "wm_jtag_0", "wo0_jtag_0",
-+ "wo0_jtag_1", "wm_jtag_1", };
-+static const char *mt7981_led_groups[] = { "gbe_led0", "gbe_led1", "wf2g_led0",
-+ "wf2g_led1", "wf5g_led0", "wf5g_led1", };
-+static const char *mt7981_pta_groups[] = { "pta_ext_0", "pta_ext_1", };
-+static const char *mt7981_pwm_groups[] = { "pwm2", "pwm0_0", "pwm0_1",
-+ "pwm1_0", "pwm1_1", };
-+static const char *mt7981_spi_groups[] = { "spi1_0", "spi0", "spi0_wp_hold", "spi1_1", "spi2",
-+ "spi2_wp_hold", };
-+static const char *mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1", "u2_phy_i2c",
-+ "sgmii1_phy_i2c", "u3_phy_i2c", "sgmii0_phy_i2c", "i2c0_2", };
-+static const char *mt7981_pcm_groups[] = { "pcm", };
-+static const char *mt7981_udi_groups[] = { "udi", };
-+static const char *mt7981_usb_groups[] = { "drv_vbus", };
-+static const char *mt7981_flash_groups[] = { "emmc_45", "snfi", };
-+static const char *mt7981_ethernet_groups[] = { "smi_mdc_mdio", "gbe_ext_mdc_mdio",
-+ "wf0_mode1", "wf0_mode3", "mt7531_int", };
-+static const char *mt7981_ant_groups[] = { "ant_sel", };
-+
-+static const struct function_desc mt7981_functions[] = {
-+ {"wa_aice", mt7981_wa_aice_groups, ARRAY_SIZE(mt7981_wa_aice_groups)},
-+ {"dfd", mt7981_dfd_groups, ARRAY_SIZE(mt7981_dfd_groups)},
-+ {"jtag", mt7981_jtag_groups, ARRAY_SIZE(mt7981_jtag_groups)},
-+ {"pta", mt7981_pta_groups, ARRAY_SIZE(mt7981_pta_groups)},
-+ {"pcm", mt7981_pcm_groups, ARRAY_SIZE(mt7981_pcm_groups)},
-+ {"udi", mt7981_udi_groups, ARRAY_SIZE(mt7981_udi_groups)},
-+ {"usb", mt7981_usb_groups, ARRAY_SIZE(mt7981_usb_groups)},
-+ {"ant", mt7981_ant_groups, ARRAY_SIZE(mt7981_ant_groups)},
-+ {"eth", mt7981_ethernet_groups, ARRAY_SIZE(mt7981_ethernet_groups)},
-+ {"i2c", mt7981_i2c_groups, ARRAY_SIZE(mt7981_i2c_groups)},
-+ {"led", mt7981_led_groups, ARRAY_SIZE(mt7981_led_groups)},
-+ {"pwm", mt7981_pwm_groups, ARRAY_SIZE(mt7981_pwm_groups)},
-+ {"spi", mt7981_spi_groups, ARRAY_SIZE(mt7981_spi_groups)},
-+ {"uart", mt7981_uart_groups, ARRAY_SIZE(mt7981_uart_groups)},
-+ {"watchdog", mt7981_wdt_groups, ARRAY_SIZE(mt7981_wdt_groups)},
-+ {"flash", mt7981_flash_groups, ARRAY_SIZE(mt7981_flash_groups)},
-+ {"pcie", mt7981_pcie_groups, ARRAY_SIZE(mt7981_pcie_groups)},
-+};
-+
-+static const struct mtk_eint_hw mt7981_eint_hw = {
-+ .port_mask = 7,
-+ .ports = 7,
-+ .ap_num = ARRAY_SIZE(mt7981_pins),
-+ .db_cnt = 16,
-+};
-+
-+static const char * const mt7981_pinctrl_register_base_names[] = {
-+ "gpio", "iocfg_rt", "iocfg_rm", "iocfg_rb",
-+ "iocfg_lb", "iocfg_bl", "iocfg_tm", "iocfg_tl",
-+};
-+
-+static struct mtk_pin_soc mt7981_data = {
-+ .reg_cal = mt7981_reg_cals,
-+ .pins = mt7981_pins,
-+ .npins = ARRAY_SIZE(mt7981_pins),
-+ .grps = mt7981_groups,
-+ .ngrps = ARRAY_SIZE(mt7981_groups),
-+ .funcs = mt7981_functions,
-+ .nfuncs = ARRAY_SIZE(mt7981_functions),
-+ .eint_hw = &mt7981_eint_hw,
-+ .gpio_m = 0,
-+ .ies_present = false,
-+ .base_names = mt7981_pinctrl_register_base_names,
-+ .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
-+ .pull_type = mt7981_pull_type,
-+ .bias_set_combo = mtk_pinconf_bias_set_combo,
-+ .bias_get_combo = mtk_pinconf_bias_get_combo,
-+ .drive_set = mtk_pinconf_drive_set_rev1,
-+ .drive_get = mtk_pinconf_drive_get_rev1,
-+ .adv_pull_get = mtk_pinconf_adv_pull_get,
-+ .adv_pull_set = mtk_pinconf_adv_pull_set,
-+};
-+
-+static const struct of_device_id mt7981_pinctrl_of_match[] = {
-+ { .compatible = "mediatek,mt7981-pinctrl", },
-+ {}
-+};
-+
-+static int mt7981_pinctrl_probe(struct platform_device *pdev)
-+{
-+ return mtk_moore_pinctrl_probe(pdev, &mt7981_data);
-+}
-+
-+static struct platform_driver mt7981_pinctrl_driver = {
-+ .driver = {
-+ .name = "mt7981-pinctrl",
-+ .of_match_table = mt7981_pinctrl_of_match,
-+ },
-+ .probe = mt7981_pinctrl_probe,
-+};
-+
-+static int __init mt7981_pinctrl_init(void)
-+{
-+ return platform_driver_register(&mt7981_pinctrl_driver);
-+}
-+arch_initcall(mt7981_pinctrl_init);
+++ /dev/null
-From c0ad453e94e5c404efbcf668648d07eaa1a71ed7 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, 18 Feb 2023 09:51:06 +0300
-Subject: [PATCH] pinctrl: mediatek: add missing options to PINCTRL_MT7981
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There are options missing from PINCTRL_MT7981 whilst being on every other
-pin controller. Add them.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/20230218065108.8958-1-arinc.unal@arinc9.com
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/mediatek/Kconfig | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/pinctrl/mediatek/Kconfig
-+++ b/drivers/pinctrl/mediatek/Kconfig
-@@ -130,6 +130,8 @@ config PINCTRL_MT7622
- config PINCTRL_MT7981
- bool "Mediatek MT7981 pin control"
- depends on OF
-+ depends on ARM64 || COMPILE_TEST
-+ default ARM64 && ARCH_MEDIATEK
- select PINCTRL_MTK_MOORE
-
- config PINCTRL_MT7986
+++ /dev/null
-From 8f6f16fe1553ce63edfb98a39ef9d4754a0c39bf Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 18 Aug 2023 04:02:35 +0100
-Subject: [PATCH] pinctrl: mediatek: fix pull_type data for MT7981
-
-MediaTek has released pull_type data for MT7981 in their SDK.
-Use it and set functions to configure pin bias.
-
-Fixes: 6c83b2d94fcc ("pinctrl: add mt7981 pinctrl driver")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/7bcc8ead25dbfabc7f5a85d066224a926fbb4941.1692327317.git.daniel@makrotopia.org
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/mediatek/pinctrl-mt7981.c | 44 +++++++----------------
- 1 file changed, 13 insertions(+), 31 deletions(-)
-
---- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
-@@ -457,37 +457,15 @@ static const unsigned int mt7981_pull_ty
- MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
- MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
- MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PUPD_R1R0_TYPE,/*63*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
-- MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PU_PD_TYPE,/*69*/
-- MTK_PULL_PU_PD_TYPE,/*70*/ MTK_PULL_PU_PD_TYPE,/*71*/
-- MTK_PULL_PU_PD_TYPE,/*72*/ MTK_PULL_PU_PD_TYPE,/*73*/
-- MTK_PULL_PU_PD_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,/*75*/
-- MTK_PULL_PU_PD_TYPE,/*76*/ MTK_PULL_PU_PD_TYPE,/*77*/
-- MTK_PULL_PU_PD_TYPE,/*78*/ MTK_PULL_PU_PD_TYPE,/*79*/
-- MTK_PULL_PU_PD_TYPE,/*80*/ MTK_PULL_PU_PD_TYPE,/*81*/
-- MTK_PULL_PU_PD_TYPE,/*82*/ MTK_PULL_PU_PD_TYPE,/*83*/
-- MTK_PULL_PU_PD_TYPE,/*84*/ MTK_PULL_PU_PD_TYPE,/*85*/
-- MTK_PULL_PU_PD_TYPE,/*86*/ MTK_PULL_PU_PD_TYPE,/*87*/
-- MTK_PULL_PU_PD_TYPE,/*88*/ MTK_PULL_PU_PD_TYPE,/*89*/
-- MTK_PULL_PU_PD_TYPE,/*90*/ MTK_PULL_PU_PD_TYPE,/*91*/
-- MTK_PULL_PU_PD_TYPE,/*92*/ MTK_PULL_PU_PD_TYPE,/*93*/
-- MTK_PULL_PU_PD_TYPE,/*94*/ MTK_PULL_PU_PD_TYPE,/*95*/
-- MTK_PULL_PU_PD_TYPE,/*96*/ MTK_PULL_PU_PD_TYPE,/*97*/
-- MTK_PULL_PU_PD_TYPE,/*98*/ MTK_PULL_PU_PD_TYPE,/*99*/
-- MTK_PULL_PU_PD_TYPE,/*100*/
-+ MTK_PULL_PU_PD_TYPE,/*40*/ MTK_PULL_PU_PD_TYPE,/*41*/
-+ MTK_PULL_PU_PD_TYPE,/*42*/ MTK_PULL_PU_PD_TYPE,/*43*/
-+ MTK_PULL_PU_PD_TYPE,/*44*/ MTK_PULL_PU_PD_TYPE,/*45*/
-+ MTK_PULL_PU_PD_TYPE,/*46*/ MTK_PULL_PU_PD_TYPE,/*47*/
-+ MTK_PULL_PU_PD_TYPE,/*48*/ MTK_PULL_PU_PD_TYPE,/*49*/
-+ MTK_PULL_PU_PD_TYPE,/*50*/ MTK_PULL_PU_PD_TYPE,/*51*/
-+ MTK_PULL_PU_PD_TYPE,/*52*/ MTK_PULL_PU_PD_TYPE,/*53*/
-+ MTK_PULL_PU_PD_TYPE,/*54*/ MTK_PULL_PU_PD_TYPE,/*55*/
-+ MTK_PULL_PU_PD_TYPE,/*56*/
- };
-
- static const struct mtk_pin_reg_calc mt7981_reg_cals[] = {
-@@ -1014,6 +992,10 @@ static struct mtk_pin_soc mt7981_data =
- .ies_present = false,
- .base_names = mt7981_pinctrl_register_base_names,
- .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
-+ .bias_disable_set = mtk_pinconf_bias_disable_set,
-+ .bias_disable_get = mtk_pinconf_bias_disable_get,
-+ .bias_set = mtk_pinconf_bias_set,
-+ .bias_get = mtk_pinconf_bias_get,
- .pull_type = mt7981_pull_type,
- .bias_set_combo = mtk_pinconf_bias_set_combo,
- .bias_get_combo = mtk_pinconf_bias_get_combo,
+++ /dev/null
-From 11db447f257231e08065989100311df57b7f1f1c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 26 Aug 2023 21:06:14 +0100
-Subject: [PATCH] pinctrl: mediatek: mt7981: add additional uart groups
-
-Add uart2_0_tx_rx (pin 4, 5) and uart1_2 (pins 9, 10) groups.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/pinctrl/mediatek/pinctrl-mt7981.c | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
-
---- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
-@@ -611,6 +611,9 @@ static int mt7981_wo0_jtag_1_funcs[] = {
- static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, };
- static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, };
-
-+static int mt7981_uart2_0_tx_rx_pins[] = { 4, 5, };
-+static int mt7981_uart2_0_tx_rx_funcs[] = { 3, 3, };
-+
- /* GBE_LED0 */
- static int mt7981_gbe_led0_pins[] = { 8, };
- static int mt7981_gbe_led0_funcs[] = { 3, };
-@@ -731,6 +734,9 @@ static int mt7981_uart1_0_funcs[] = { 4,
- static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, };
- static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, };
-
-+static int mt7981_uart1_2_pins[] = { 9, 10, };
-+static int mt7981_uart1_2_funcs[] = { 2, 2, };
-+
- /* UART2 */
- static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, };
- static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, };
-@@ -805,6 +811,8 @@ static const struct group_desc mt7981_gr
- PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0),
- /* @GPIO(4,7) WM_JTAG(3) */
- PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0),
-+ /* @GPIO(4,5) WM_JTAG(4) */
-+ PINCTRL_PIN_GROUP("uart2_0_tx_rx", mt7981_uart2_0_tx_rx),
- /* @GPIO(8) GBE_LED0(3) */
- PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0),
- /* @GPIO(4,6) PTA_EXT(4) */
-@@ -861,6 +869,8 @@ static const struct group_desc mt7981_gr
- PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0),
- /* @GPIO(26,29): UART1(2) */
- PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1),
-+ /* @GPIO(9,10): UART1(2) */
-+ PINCTRL_PIN_GROUP("uart1_2", mt7981_uart1_2),
- /* @GPIO(22,25): UART1(3) */
- PINCTRL_PIN_GROUP("uart2_1", mt7981_uart2_1),
- /* @GPIO(22,24) PTA_EXT(4) */
-@@ -922,9 +932,9 @@ static const struct group_desc mt7981_gr
- */
- static const char *mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", "wm_aice1_1",
- "wa_aice3", "wm_aice1_2", };
--static const char *mt7981_uart_groups[] = { "wm_uart_0", "uart2_0",
-- "net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2",
-- "uart1_0", "uart1_1", "uart2_1", "wm_aurt_1", "wm_aurt_2", "uart0", };
-+static const char *mt7981_uart_groups[] = { "net_wo0_uart_txd_0", "net_wo0_uart_txd_1",
-+ "net_wo0_uart_txd_2", "uart0", "uart1_0", "uart1_1", "uart1_2", "uart2_0",
-+ "uart2_0_tx_rx", "uart2_1", "wm_uart_0", "wm_aurt_1", "wm_aurt_2", };
- static const char *mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", };
- static const char *mt7981_wdt_groups[] = { "watchdog", "watchdog1", };
- static const char *mt7981_pcie_groups[] = { "pcie_pereset", "pcie_clk", "pcie_wake", };
+++ /dev/null
-From 0d8387fba9f151220e48dc3dcdc2335539708f13 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 18 Aug 2023 04:03:26 +0100
-Subject: [PATCH] pinctrl: mediatek: assign functions to configure pin bias on
- MT7986
-
-Assign bias_disable_get/set and bias_get/set functions to allow
-configuring pin bias on MT7986.
-
-Fixes: 2c58d8dc9cd0 ("pinctrl: mediatek: add pull_type attribute for mediatek MT7986 SoC")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/47f72372354312a839b9337e09476aadcc206e8b.1692327317.git.daniel@makrotopia.org
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/mediatek/pinctrl-mt7986.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
-@@ -922,6 +922,10 @@ static struct mtk_pin_soc mt7986a_data =
- .ies_present = false,
- .base_names = mt7986_pinctrl_register_base_names,
- .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
-+ .bias_disable_set = mtk_pinconf_bias_disable_set,
-+ .bias_disable_get = mtk_pinconf_bias_disable_get,
-+ .bias_set = mtk_pinconf_bias_set,
-+ .bias_get = mtk_pinconf_bias_get,
- .pull_type = mt7986_pull_type,
- .bias_set_combo = mtk_pinconf_bias_set_combo,
- .bias_get_combo = mtk_pinconf_bias_get_combo,
-@@ -944,6 +948,10 @@ static struct mtk_pin_soc mt7986b_data =
- .ies_present = false,
- .base_names = mt7986_pinctrl_register_base_names,
- .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
-+ .bias_disable_set = mtk_pinconf_bias_disable_set,
-+ .bias_disable_get = mtk_pinconf_bias_disable_get,
-+ .bias_set = mtk_pinconf_bias_set,
-+ .bias_get = mtk_pinconf_bias_get,
- .pull_type = mt7986_pull_type,
- .bias_set_combo = mtk_pinconf_bias_set_combo,
- .bias_get_combo = mtk_pinconf_bias_get_combo,
+++ /dev/null
-From fe5c8d03f3de89ae058e365b783f8c1314f47490 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Fri, 20 Jan 2023 10:20:33 +0100
-Subject: [PATCH 01/15] clk: mediatek: clk-gate: Propagate struct device with
- mtk_clk_register_gates()
-
-Commit e4c23e19aa2a ("clk: mediatek: Register clock gate with device")
-introduces a helper function for the sole purpose of propagating a
-struct device pointer to the clk API when registering the mtk-gate
-clocks to take advantage of Runtime PM when/where needed and where
-a power domain is defined in devicetree.
-
-Function mtk_clk_register_gates() then becomes a wrapper around the
-new mtk_clk_register_gates_with_dev() function that will simply pass
-NULL as struct device: this is essential when registering drivers
-with CLK_OF_DECLARE instead of as a platform device, as there will
-be no struct device to pass... but we can as well simply have only
-one function that always takes such pointer as a param and pass NULL
-when unavoidable.
-
-This commit removes the mtk_clk_register_gates() wrapper and renames
-mtk_clk_register_gates_with_dev() to the former and all of the calls
-to either of the two functions were fixed in all drivers in order to
-reflect this change; also, to improve consistency with other kernel
-functions, the pointer to struct device was moved as the first param.
-
-Since a lot of MediaTek clock drivers are actually registering as a
-platform device, but were still registering the mtk-gate clocks
-without passing any struct device to the clock framework, they've
-been changed to pass a valid one now, as to make all those platforms
-able to use runtime power management where available.
-
-While at it, some much needed indentation changes were also done.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
-Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
-Tested-by: Miles Chen <miles.chen@mediatek.com>
-Link: https://lore.kernel.org/r/20230120092053.182923-4-angelogioacchino.delregno@collabora.com
-Tested-by: Mingming Su <mingming.su@mediatek.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-
-[daniel@makrotopia.org: dropped parts not relevant for OpenWrt]
----
- drivers/clk/mediatek/clk-gate.c | 23 +++++++---------------
- drivers/clk/mediatek/clk-gate.h | 7 +------
- drivers/clk/mediatek/clk-mt2701-aud.c | 4 ++--
- drivers/clk/mediatek/clk-mt2701-eth.c | 4 ++--
- drivers/clk/mediatek/clk-mt2701-g3d.c | 2 +-
- drivers/clk/mediatek/clk-mt2701-hif.c | 4 ++--
- drivers/clk/mediatek/clk-mt2701-mm.c | 4 ++--
- drivers/clk/mediatek/clk-mt2701.c | 12 +++++------
- drivers/clk/mediatek/clk-mt2712-mm.c | 4 ++--
- drivers/clk/mediatek/clk-mt2712.c | 12 +++++------
- drivers/clk/mediatek/clk-mt7622-aud.c | 4 ++--
- drivers/clk/mediatek/clk-mt7622-eth.c | 8 ++++----
- drivers/clk/mediatek/clk-mt7622-hif.c | 8 ++++----
- drivers/clk/mediatek/clk-mt7622.c | 14 ++++++-------
- drivers/clk/mediatek/clk-mt7629-eth.c | 7 ++++---
- drivers/clk/mediatek/clk-mt7629-hif.c | 8 ++++----
- drivers/clk/mediatek/clk-mt7629.c | 10 +++++-----
- drivers/clk/mediatek/clk-mt7986-eth.c | 10 +++++-----
- drivers/clk/mediatek/clk-mt7986-infracfg.c | 4 ++--
- 19 files changed, 68 insertions(+), 81 deletions(-)
-
---- a/drivers/clk/mediatek/clk-gate.c
-+++ b/drivers/clk/mediatek/clk-gate.c
-@@ -152,12 +152,12 @@ const struct clk_ops mtk_clk_gate_ops_no
- };
- EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv);
-
--static struct clk_hw *mtk_clk_register_gate(const char *name,
-+static struct clk_hw *mtk_clk_register_gate(struct device *dev, const char *name,
- const char *parent_name,
- struct regmap *regmap, int set_ofs,
- int clr_ofs, int sta_ofs, u8 bit,
- const struct clk_ops *ops,
-- unsigned long flags, struct device *dev)
-+ unsigned long flags)
- {
- struct mtk_clk_gate *cg;
- int ret;
-@@ -202,10 +202,9 @@ static void mtk_clk_unregister_gate(stru
- kfree(cg);
- }
-
--int mtk_clk_register_gates_with_dev(struct device_node *node,
-- const struct mtk_gate *clks, int num,
-- struct clk_hw_onecell_data *clk_data,
-- struct device *dev)
-+int mtk_clk_register_gates(struct device *dev, struct device_node *node,
-+ const struct mtk_gate *clks, int num,
-+ struct clk_hw_onecell_data *clk_data)
- {
- int i;
- struct clk_hw *hw;
-@@ -229,13 +228,13 @@ int mtk_clk_register_gates_with_dev(stru
- continue;
- }
-
-- hw = mtk_clk_register_gate(gate->name, gate->parent_name,
-+ hw = mtk_clk_register_gate(dev, gate->name, gate->parent_name,
- regmap,
- gate->regs->set_ofs,
- gate->regs->clr_ofs,
- gate->regs->sta_ofs,
- gate->shift, gate->ops,
-- gate->flags, dev);
-+ gate->flags);
-
- if (IS_ERR(hw)) {
- pr_err("Failed to register clk %s: %pe\n", gate->name,
-@@ -261,14 +260,6 @@ err:
-
- return PTR_ERR(hw);
- }
--EXPORT_SYMBOL_GPL(mtk_clk_register_gates_with_dev);
--
--int mtk_clk_register_gates(struct device_node *node,
-- const struct mtk_gate *clks, int num,
-- struct clk_hw_onecell_data *clk_data)
--{
-- return mtk_clk_register_gates_with_dev(node, clks, num, clk_data, NULL);
--}
- EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
-
- void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
---- a/drivers/clk/mediatek/clk-gate.h
-+++ b/drivers/clk/mediatek/clk-gate.h
-@@ -50,15 +50,10 @@ struct mtk_gate {
- #define GATE_MTK(_id, _name, _parent, _regs, _shift, _ops) \
- GATE_MTK_FLAGS(_id, _name, _parent, _regs, _shift, _ops, 0)
-
--int mtk_clk_register_gates(struct device_node *node,
-+int mtk_clk_register_gates(struct device *dev, struct device_node *node,
- const struct mtk_gate *clks, int num,
- struct clk_hw_onecell_data *clk_data);
-
--int mtk_clk_register_gates_with_dev(struct device_node *node,
-- const struct mtk_gate *clks, int num,
-- struct clk_hw_onecell_data *clk_data,
-- struct device *dev);
--
- void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
- struct clk_hw_onecell_data *clk_data);
-
---- a/drivers/clk/mediatek/clk-mt2701-aud.c
-+++ b/drivers/clk/mediatek/clk-mt2701-aud.c
-@@ -127,8 +127,8 @@ static int clk_mt2701_aud_probe(struct p
-
- clk_data = mtk_alloc_clk_data(CLK_AUD_NR);
-
-- mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, audio_clks,
-+ ARRAY_SIZE(audio_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r) {
---- a/drivers/clk/mediatek/clk-mt2701-eth.c
-+++ b/drivers/clk/mediatek/clk-mt2701-eth.c
-@@ -51,8 +51,8 @@ static int clk_mt2701_eth_probe(struct p
-
- clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
-
-- mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, eth_clks,
-+ ARRAY_SIZE(eth_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
---- a/drivers/clk/mediatek/clk-mt2701-g3d.c
-+++ b/drivers/clk/mediatek/clk-mt2701-g3d.c
-@@ -45,7 +45,7 @@ static int clk_mt2701_g3dsys_init(struct
-
- clk_data = mtk_alloc_clk_data(CLK_G3DSYS_NR);
-
-- mtk_clk_register_gates(node, g3d_clks, ARRAY_SIZE(g3d_clks),
-+ mtk_clk_register_gates(&pdev->dev, node, g3d_clks, ARRAY_SIZE(g3d_clks),
- clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
---- a/drivers/clk/mediatek/clk-mt2701-hif.c
-+++ b/drivers/clk/mediatek/clk-mt2701-hif.c
-@@ -48,8 +48,8 @@ static int clk_mt2701_hif_probe(struct p
-
- clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
-
-- mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, hif_clks,
-+ ARRAY_SIZE(hif_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r) {
---- a/drivers/clk/mediatek/clk-mt2701-mm.c
-+++ b/drivers/clk/mediatek/clk-mt2701-mm.c
-@@ -76,8 +76,8 @@ static int clk_mt2701_mm_probe(struct pl
-
- clk_data = mtk_alloc_clk_data(CLK_MM_NR);
-
-- mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, mm_clks,
-+ ARRAY_SIZE(mm_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -685,8 +685,8 @@ static int mtk_topckgen_init(struct plat
- mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
- base, &mt2701_clk_lock, clk_data);
-
-- mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, top_clks,
-+ ARRAY_SIZE(top_clks), clk_data);
-
- return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- }
-@@ -789,8 +789,8 @@ static int mtk_infrasys_init(struct plat
- }
- }
-
-- mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
-- infra_clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, infra_clks,
-+ ARRAY_SIZE(infra_clks), infra_clk_data);
- mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
- infra_clk_data);
-
-@@ -902,8 +902,8 @@ static int mtk_pericfg_init(struct platf
- if (!clk_data)
- return -ENOMEM;
-
-- mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, peri_clks,
-+ ARRAY_SIZE(peri_clks), clk_data);
-
- mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
- &mt2701_clk_lock, clk_data);
---- a/drivers/clk/mediatek/clk-mt2712-mm.c
-+++ b/drivers/clk/mediatek/clk-mt2712-mm.c
-@@ -117,8 +117,8 @@ static int clk_mt2712_mm_probe(struct pl
-
- clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
-
-- mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, mm_clks,
-+ ARRAY_SIZE(mm_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
---- a/drivers/clk/mediatek/clk-mt2712.c
-+++ b/drivers/clk/mediatek/clk-mt2712.c
-@@ -1324,8 +1324,8 @@ static int clk_mt2712_top_probe(struct p
- &mt2712_clk_lock, top_clk_data);
- mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
- &mt2712_clk_lock, top_clk_data);
-- mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
-- top_clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, top_clks,
-+ ARRAY_SIZE(top_clks), top_clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, top_clk_data);
-
-@@ -1344,8 +1344,8 @@ static int clk_mt2712_infra_probe(struct
-
- clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
-
-- mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, infra_clks,
-+ ARRAY_SIZE(infra_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-@@ -1366,8 +1366,8 @@ static int clk_mt2712_peri_probe(struct
-
- clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
-
-- mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, peri_clks,
-+ ARRAY_SIZE(peri_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
---- a/drivers/clk/mediatek/clk-mt7622-aud.c
-+++ b/drivers/clk/mediatek/clk-mt7622-aud.c
-@@ -114,8 +114,8 @@ static int clk_mt7622_audiosys_init(stru
-
- clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
-
-- mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, audio_clks,
-+ ARRAY_SIZE(audio_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r) {
---- a/drivers/clk/mediatek/clk-mt7622-eth.c
-+++ b/drivers/clk/mediatek/clk-mt7622-eth.c
-@@ -69,8 +69,8 @@ static int clk_mt7622_ethsys_init(struct
-
- clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK);
-
-- mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, eth_clks,
-+ ARRAY_SIZE(eth_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
-@@ -91,8 +91,8 @@ static int clk_mt7622_sgmiisys_init(stru
-
- clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK);
-
-- mtk_clk_register_gates(node, sgmii_clks, ARRAY_SIZE(sgmii_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, sgmii_clks,
-+ ARRAY_SIZE(sgmii_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
---- a/drivers/clk/mediatek/clk-mt7622-hif.c
-+++ b/drivers/clk/mediatek/clk-mt7622-hif.c
-@@ -80,8 +80,8 @@ static int clk_mt7622_ssusbsys_init(stru
-
- clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK);
-
-- mtk_clk_register_gates(node, ssusb_clks, ARRAY_SIZE(ssusb_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, ssusb_clks,
-+ ARRAY_SIZE(ssusb_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
-@@ -102,8 +102,8 @@ static int clk_mt7622_pciesys_init(struc
-
- clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK);
-
-- mtk_clk_register_gates(node, pcie_clks, ARRAY_SIZE(pcie_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, pcie_clks,
-+ ARRAY_SIZE(pcie_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
---- a/drivers/clk/mediatek/clk-mt7622.c
-+++ b/drivers/clk/mediatek/clk-mt7622.c
-@@ -621,8 +621,8 @@ static int mtk_topckgen_init(struct plat
- mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
- base, &mt7622_clk_lock, clk_data);
-
-- mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, top_clks,
-+ ARRAY_SIZE(top_clks), clk_data);
-
- return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- }
-@@ -635,8 +635,8 @@ static int mtk_infrasys_init(struct plat
-
- clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
-
-- mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, infra_clks,
-+ ARRAY_SIZE(infra_clks), clk_data);
-
- mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
- clk_data);
-@@ -663,7 +663,7 @@ static int mtk_apmixedsys_init(struct pl
- mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls),
- clk_data);
-
-- mtk_clk_register_gates(node, apmixed_clks,
-+ mtk_clk_register_gates(&pdev->dev, node, apmixed_clks,
- ARRAY_SIZE(apmixed_clks), clk_data);
-
- return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-@@ -682,8 +682,8 @@ static int mtk_pericfg_init(struct platf
-
- clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
-
-- mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, peri_clks,
-+ ARRAY_SIZE(peri_clks), clk_data);
-
- mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
- &mt7622_clk_lock, clk_data);
---- a/drivers/clk/mediatek/clk-mt7629-eth.c
-+++ b/drivers/clk/mediatek/clk-mt7629-eth.c
-@@ -82,7 +82,8 @@ static int clk_mt7629_ethsys_init(struct
- if (!clk_data)
- return -ENOMEM;
-
-- mtk_clk_register_gates(node, eth_clks, CLK_ETH_NR_CLK, clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, eth_clks,
-+ CLK_ETH_NR_CLK, clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
-@@ -106,8 +107,8 @@ static int clk_mt7629_sgmiisys_init(stru
- if (!clk_data)
- return -ENOMEM;
-
-- mtk_clk_register_gates(node, sgmii_clks[id++], CLK_SGMII_NR_CLK,
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, sgmii_clks[id++],
-+ CLK_SGMII_NR_CLK, clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
---- a/drivers/clk/mediatek/clk-mt7629-hif.c
-+++ b/drivers/clk/mediatek/clk-mt7629-hif.c
-@@ -75,8 +75,8 @@ static int clk_mt7629_ssusbsys_init(stru
-
- clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK);
-
-- mtk_clk_register_gates(node, ssusb_clks, ARRAY_SIZE(ssusb_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, ssusb_clks,
-+ ARRAY_SIZE(ssusb_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
-@@ -97,8 +97,8 @@ static int clk_mt7629_pciesys_init(struc
-
- clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK);
-
-- mtk_clk_register_gates(node, pcie_clks, ARRAY_SIZE(pcie_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, pcie_clks,
-+ ARRAY_SIZE(pcie_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
---- a/drivers/clk/mediatek/clk-mt7629.c
-+++ b/drivers/clk/mediatek/clk-mt7629.c
-@@ -585,8 +585,8 @@ static int mtk_infrasys_init(struct plat
- if (!clk_data)
- return -ENOMEM;
-
-- mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, infra_clks,
-+ ARRAY_SIZE(infra_clks), clk_data);
-
- mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
- clk_data);
-@@ -610,8 +610,8 @@ static int mtk_pericfg_init(struct platf
- if (!clk_data)
- return -ENOMEM;
-
-- mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, peri_clks,
-+ ARRAY_SIZE(peri_clks), clk_data);
-
- mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
- &mt7629_clk_lock, clk_data);
-@@ -637,7 +637,7 @@ static int mtk_apmixedsys_init(struct pl
- mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls),
- clk_data);
-
-- mtk_clk_register_gates(node, apmixed_clks,
-+ mtk_clk_register_gates(&pdev->dev, node, apmixed_clks,
- ARRAY_SIZE(apmixed_clks), clk_data);
-
- clk_prepare_enable(clk_data->hws[CLK_APMIXED_ARMPLL]->clk);
---- a/drivers/clk/mediatek/clk-mt7986-eth.c
-+++ b/drivers/clk/mediatek/clk-mt7986-eth.c
-@@ -72,8 +72,8 @@ static void __init mtk_sgmiisys_0_init(s
-
- clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks));
-
-- mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks),
-- clk_data);
-+ mtk_clk_register_gates(NULL, node, sgmii0_clks,
-+ ARRAY_SIZE(sgmii0_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
-@@ -90,8 +90,8 @@ static void __init mtk_sgmiisys_1_init(s
-
- clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks));
-
-- mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks),
-- clk_data);
-+ mtk_clk_register_gates(NULL, node, sgmii1_clks,
-+ ARRAY_SIZE(sgmii1_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
-@@ -109,7 +109,7 @@ static void __init mtk_ethsys_init(struc
-
- clk_data = mtk_alloc_clk_data(ARRAY_SIZE(eth_clks));
-
-- mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), clk_data);
-+ mtk_clk_register_gates(NULL, node, eth_clks, ARRAY_SIZE(eth_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
---- a/drivers/clk/mediatek/clk-mt7986-infracfg.c
-+++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
-@@ -180,8 +180,8 @@ static int clk_mt7986_infracfg_probe(str
- mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
- mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
- &mt7986_clk_lock, clk_data);
-- mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
-- clk_data);
-+ mtk_clk_register_gates(&pdev->dev, node, infra_clks,
-+ ARRAY_SIZE(infra_clks), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r) {
---- a/drivers/clk/mediatek/clk-mtk.c
-+++ b/drivers/clk/mediatek/clk-mtk.c
-@@ -459,8 +459,8 @@ int mtk_clk_simple_probe(struct platform
- if (!clk_data)
- return -ENOMEM;
-
-- r = mtk_clk_register_gates_with_dev(node, mcd->clks, mcd->num_clks,
-- clk_data, &pdev->dev);
-+ r = mtk_clk_register_gates(&pdev->dev, node, mcd->clks, mcd->num_clks,
-+ clk_data);
- if (r)
- goto free_data;
-
+++ /dev/null
-From b888303c7d23d7bd0c8667cfc657669e5d153fea Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Fri, 20 Jan 2023 10:20:34 +0100
-Subject: [PATCH 02/15] clk: mediatek: cpumux: Propagate struct device where
- possible
-
-Take a pointer to a struct device in mtk_clk_register_cpumuxes() and
-propagate the same to mtk_clk_register_cpumux() => clk_hw_register().
-Even though runtime pm is unlikely to be used with CPU muxes, this
-helps with code consistency and possibly opens to commonization of
-some mtk_clk_register_(x) functions.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
-Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
-Tested-by: Miles Chen <miles.chen@mediatek.com>
-Link: https://lore.kernel.org/r/20230120092053.182923-5-angelogioacchino.delregno@collabora.com
-Tested-by: Mingming Su <mingming.su@mediatek.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/mediatek/clk-cpumux.c | 8 ++++----
- drivers/clk/mediatek/clk-cpumux.h | 2 +-
- drivers/clk/mediatek/clk-mt2701.c | 2 +-
- drivers/clk/mediatek/clk-mt6795-infracfg.c | 3 ++-
- drivers/clk/mediatek/clk-mt7622.c | 4 ++--
- drivers/clk/mediatek/clk-mt7629.c | 4 ++--
- drivers/clk/mediatek/clk-mt8173.c | 4 ++--
- 7 files changed, 14 insertions(+), 13 deletions(-)
-
---- a/drivers/clk/mediatek/clk-cpumux.c
-+++ b/drivers/clk/mediatek/clk-cpumux.c
-@@ -58,7 +58,7 @@ static const struct clk_ops clk_cpumux_o
- };
-
- static struct clk_hw *
--mtk_clk_register_cpumux(const struct mtk_composite *mux,
-+mtk_clk_register_cpumux(struct device *dev, const struct mtk_composite *mux,
- struct regmap *regmap)
- {
- struct mtk_clk_cpumux *cpumux;
-@@ -81,7 +81,7 @@ mtk_clk_register_cpumux(const struct mtk
- cpumux->regmap = regmap;
- cpumux->hw.init = &init;
-
-- ret = clk_hw_register(NULL, &cpumux->hw);
-+ ret = clk_hw_register(dev, &cpumux->hw);
- if (ret) {
- kfree(cpumux);
- return ERR_PTR(ret);
-@@ -102,7 +102,7 @@ static void mtk_clk_unregister_cpumux(st
- kfree(cpumux);
- }
-
--int mtk_clk_register_cpumuxes(struct device_node *node,
-+int mtk_clk_register_cpumuxes(struct device *dev, struct device_node *node,
- const struct mtk_composite *clks, int num,
- struct clk_hw_onecell_data *clk_data)
- {
-@@ -125,7 +125,7 @@ int mtk_clk_register_cpumuxes(struct dev
- continue;
- }
-
-- hw = mtk_clk_register_cpumux(mux, regmap);
-+ hw = mtk_clk_register_cpumux(dev, mux, regmap);
- if (IS_ERR(hw)) {
- pr_err("Failed to register clk %s: %pe\n", mux->name,
- hw);
---- a/drivers/clk/mediatek/clk-cpumux.h
-+++ b/drivers/clk/mediatek/clk-cpumux.h
-@@ -11,7 +11,7 @@ struct clk_hw_onecell_data;
- struct device_node;
- struct mtk_composite;
-
--int mtk_clk_register_cpumuxes(struct device_node *node,
-+int mtk_clk_register_cpumuxes(struct device *dev, struct device_node *node,
- const struct mtk_composite *clks, int num,
- struct clk_hw_onecell_data *clk_data);
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -761,7 +761,7 @@ static void __init mtk_infrasys_init_ear
- mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
- infra_clk_data);
-
-- mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
-+ mtk_clk_register_cpumuxes(NULL, node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
- infra_clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
---- a/drivers/clk/mediatek/clk-mt6795-infracfg.c
-+++ b/drivers/clk/mediatek/clk-mt6795-infracfg.c
-@@ -105,7 +105,8 @@ static int clk_mt6795_infracfg_probe(str
- if (ret)
- goto free_clk_data;
-
-- ret = mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes), clk_data);
-+ ret = mtk_clk_register_cpumuxes(&pdev->dev, node, cpu_muxes,
-+ ARRAY_SIZE(cpu_muxes), clk_data);
- if (ret)
- goto unregister_gates;
-
---- a/drivers/clk/mediatek/clk-mt7622.c
-+++ b/drivers/clk/mediatek/clk-mt7622.c
-@@ -638,8 +638,8 @@ static int mtk_infrasys_init(struct plat
- mtk_clk_register_gates(&pdev->dev, node, infra_clks,
- ARRAY_SIZE(infra_clks), clk_data);
-
-- mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
-- clk_data);
-+ mtk_clk_register_cpumuxes(&pdev->dev, node, infra_muxes,
-+ ARRAY_SIZE(infra_muxes), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
- clk_data);
---- a/drivers/clk/mediatek/clk-mt7629.c
-+++ b/drivers/clk/mediatek/clk-mt7629.c
-@@ -588,8 +588,8 @@ static int mtk_infrasys_init(struct plat
- mtk_clk_register_gates(&pdev->dev, node, infra_clks,
- ARRAY_SIZE(infra_clks), clk_data);
-
-- mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
-- clk_data);
-+ mtk_clk_register_cpumuxes(&pdev->dev, node, infra_muxes,
-+ ARRAY_SIZE(infra_muxes), clk_data);
-
- return of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
- clk_data);
---- a/drivers/clk/mediatek/clk-mt8173.c
-+++ b/drivers/clk/mediatek/clk-mt8173.c
-@@ -892,8 +892,8 @@ static void __init mtk_infrasys_init(str
- clk_data);
- mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
-
-- mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
-- clk_data);
-+ mtk_clk_register_cpumuxes(NULL, node, cpu_muxes,
-+ ARRAY_SIZE(cpu_muxes), clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
+++ /dev/null
-From f23375db001ec0fe9f565be75eff43adde15407e Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Fri, 20 Jan 2023 10:20:35 +0100
-Subject: [PATCH 03/15] clk: mediatek: clk-mtk: Propagate struct device for
- composites
-
-Like done for cpumux clocks, propagate struct device for composite
-clocks registered through clk-mtk helpers to be able to get runtime
-pm support for MTK clocks.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Tested-by: Miles Chen <miles.chen@mediatek.com>
-Link: https://lore.kernel.org/r/20230120092053.182923-6-angelogioacchino.delregno@collabora.com
-Tested-by: Mingming Su <mingming.su@mediatek.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-
-[daniel@makrotopia.org: remove parts not relevant for OpenWrt]
----
- drivers/clk/mediatek/clk-mt2701.c | 10 ++++++----
- drivers/clk/mediatek/clk-mt2712.c | 12 ++++++++----
- drivers/clk/mediatek/clk-mt7622.c | 8 +++++---
- drivers/clk/mediatek/clk-mt7629.c | 8 +++++---
- drivers/clk/mediatek/clk-mtk.c | 11 ++++++-----
- drivers/clk/mediatek/clk-mtk.h | 3 ++-
- 6 files changed, 32 insertions(+), 20 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -679,8 +679,9 @@ static int mtk_topckgen_init(struct plat
- mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
- clk_data);
-
-- mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
-- base, &mt2701_clk_lock, clk_data);
-+ mtk_clk_register_composites(&pdev->dev, top_muxes,
-+ ARRAY_SIZE(top_muxes), base,
-+ &mt2701_clk_lock, clk_data);
-
- mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
- base, &mt2701_clk_lock, clk_data);
-@@ -905,8 +906,9 @@ static int mtk_pericfg_init(struct platf
- mtk_clk_register_gates(&pdev->dev, node, peri_clks,
- ARRAY_SIZE(peri_clks), clk_data);
-
-- mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
-- &mt2701_clk_lock, clk_data);
-+ mtk_clk_register_composites(&pdev->dev, peri_muxs,
-+ ARRAY_SIZE(peri_muxs), base,
-+ &mt2701_clk_lock, clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
---- a/drivers/clk/mediatek/clk-mt2712.c
-+++ b/drivers/clk/mediatek/clk-mt2712.c
-@@ -1320,8 +1320,9 @@ static int clk_mt2712_top_probe(struct p
- mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
- top_clk_data);
- mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
-- mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
-- &mt2712_clk_lock, top_clk_data);
-+ mtk_clk_register_composites(&pdev->dev, top_muxes,
-+ ARRAY_SIZE(top_muxes), base,
-+ &mt2712_clk_lock, top_clk_data);
- mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
- &mt2712_clk_lock, top_clk_data);
- mtk_clk_register_gates(&pdev->dev, node, top_clks,
-@@ -1395,8 +1396,11 @@ static int clk_mt2712_mcu_probe(struct p
-
- clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK);
-
-- mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
-- &mt2712_clk_lock, clk_data);
-+ r = mtk_clk_register_composites(&pdev->dev, mcu_muxes,
-+ ARRAY_SIZE(mcu_muxes), base,
-+ &mt2712_clk_lock, clk_data);
-+ if (r)
-+ dev_err(&pdev->dev, "Could not register composites: %d\n", r);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
---- a/drivers/clk/mediatek/clk-mt7622.c
-+++ b/drivers/clk/mediatek/clk-mt7622.c
-@@ -615,8 +615,9 @@ static int mtk_topckgen_init(struct plat
- mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
- clk_data);
-
-- mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
-- base, &mt7622_clk_lock, clk_data);
-+ mtk_clk_register_composites(&pdev->dev, top_muxes,
-+ ARRAY_SIZE(top_muxes), base,
-+ &mt7622_clk_lock, clk_data);
-
- mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
- base, &mt7622_clk_lock, clk_data);
-@@ -685,7 +686,8 @@ static int mtk_pericfg_init(struct platf
- mtk_clk_register_gates(&pdev->dev, node, peri_clks,
- ARRAY_SIZE(peri_clks), clk_data);
-
-- mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
-+ mtk_clk_register_composites(&pdev->dev, peri_muxes,
-+ ARRAY_SIZE(peri_muxes), base,
- &mt7622_clk_lock, clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
---- a/drivers/clk/mediatek/clk-mt7629.c
-+++ b/drivers/clk/mediatek/clk-mt7629.c
-@@ -566,8 +566,9 @@ static int mtk_topckgen_init(struct plat
- mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
- clk_data);
-
-- mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
-- base, &mt7629_clk_lock, clk_data);
-+ mtk_clk_register_composites(&pdev->dev, top_muxes,
-+ ARRAY_SIZE(top_muxes), base,
-+ &mt7629_clk_lock, clk_data);
-
- clk_prepare_enable(clk_data->hws[CLK_TOP_AXI_SEL]->clk);
- clk_prepare_enable(clk_data->hws[CLK_TOP_MEM_SEL]->clk);
-@@ -613,7 +614,8 @@ static int mtk_pericfg_init(struct platf
- mtk_clk_register_gates(&pdev->dev, node, peri_clks,
- ARRAY_SIZE(peri_clks), clk_data);
-
-- mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
-+ mtk_clk_register_composites(&pdev->dev, peri_muxes,
-+ ARRAY_SIZE(peri_muxes), base,
- &mt7629_clk_lock, clk_data);
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
---- a/drivers/clk/mediatek/clk-mtk.c
-+++ b/drivers/clk/mediatek/clk-mtk.c
-@@ -197,8 +197,8 @@ void mtk_clk_unregister_factors(const st
- }
- EXPORT_SYMBOL_GPL(mtk_clk_unregister_factors);
-
--static struct clk_hw *mtk_clk_register_composite(const struct mtk_composite *mc,
-- void __iomem *base, spinlock_t *lock)
-+static struct clk_hw *mtk_clk_register_composite(struct device *dev,
-+ const struct mtk_composite *mc, void __iomem *base, spinlock_t *lock)
- {
- struct clk_hw *hw;
- struct clk_mux *mux = NULL;
-@@ -264,7 +264,7 @@ static struct clk_hw *mtk_clk_register_c
- div_ops = &clk_divider_ops;
- }
-
-- hw = clk_hw_register_composite(NULL, mc->name, parent_names, num_parents,
-+ hw = clk_hw_register_composite(dev, mc->name, parent_names, num_parents,
- mux_hw, mux_ops,
- div_hw, div_ops,
- gate_hw, gate_ops,
-@@ -308,7 +308,8 @@ static void mtk_clk_unregister_composite
- kfree(mux);
- }
-
--int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
-+int mtk_clk_register_composites(struct device *dev,
-+ const struct mtk_composite *mcs, int num,
- void __iomem *base, spinlock_t *lock,
- struct clk_hw_onecell_data *clk_data)
- {
-@@ -327,7 +328,7 @@ int mtk_clk_register_composites(const st
- continue;
- }
-
-- hw = mtk_clk_register_composite(mc, base, lock);
-+ hw = mtk_clk_register_composite(dev, mc, base, lock);
-
- if (IS_ERR(hw)) {
- pr_err("Failed to register clk %s: %pe\n", mc->name,
---- a/drivers/clk/mediatek/clk-mtk.h
-+++ b/drivers/clk/mediatek/clk-mtk.h
-@@ -149,7 +149,8 @@ struct mtk_composite {
- .flags = 0, \
- }
-
--int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
-+int mtk_clk_register_composites(struct device *dev,
-+ const struct mtk_composite *mcs, int num,
- void __iomem *base, spinlock_t *lock,
- struct clk_hw_onecell_data *clk_data);
- void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
+++ /dev/null
-From 5d911479e4c732729bfa798e4a9e3e5aec3e30a7 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Fri, 20 Jan 2023 10:20:36 +0100
-Subject: [PATCH 04/15] clk: mediatek: clk-mux: Propagate struct device for
- mtk-mux
-
-Like done for other clocks, propagate struct device for mtk mux clocks
-registered through clk-mux helpers to enable runtime pm support.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Tested-by: Miles Chen <miles.chen@mediatek.com>
-Link: https://lore.kernel.org/r/20230120092053.182923-7-angelogioacchino.delregno@collabora.com
-Tested-by: Mingming Su <mingming.su@mediatek.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-
-[daniel@makrotopia.org: removed parts not relevant for OpenWrt]
----
- drivers/clk/mediatek/clk-mt7986-infracfg.c | 3 ++-
- drivers/clk/mediatek/clk-mt7986-topckgen.c | 3 ++-
- drivers/clk/mediatek/clk-mux.c | 14 ++++++++------
- drivers/clk/mediatek/clk-mux.h | 3 ++-
- 4 files changed, 14 insertions(+), 9 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mt7986-infracfg.c
-+++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
-@@ -178,7 +178,8 @@ static int clk_mt7986_infracfg_probe(str
- return -ENOMEM;
-
- mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
-- mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
-+ mtk_clk_register_muxes(&pdev->dev, infra_muxes,
-+ ARRAY_SIZE(infra_muxes), node,
- &mt7986_clk_lock, clk_data);
- mtk_clk_register_gates(&pdev->dev, node, infra_clks,
- ARRAY_SIZE(infra_clks), clk_data);
---- a/drivers/clk/mediatek/clk-mt7986-topckgen.c
-+++ b/drivers/clk/mediatek/clk-mt7986-topckgen.c
-@@ -303,7 +303,8 @@ static int clk_mt7986_topckgen_probe(str
- mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
- clk_data);
- mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
-- mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
-+ mtk_clk_register_muxes(&pdev->dev, top_muxes,
-+ ARRAY_SIZE(top_muxes), node,
- &mt7986_clk_lock, clk_data);
-
- clk_prepare_enable(clk_data->hws[CLK_TOP_SYSAXI_SEL]->clk);
---- a/drivers/clk/mediatek/clk-mux.c
-+++ b/drivers/clk/mediatek/clk-mux.c
-@@ -154,9 +154,10 @@ const struct clk_ops mtk_mux_gate_clr_se
- };
- EXPORT_SYMBOL_GPL(mtk_mux_gate_clr_set_upd_ops);
-
--static struct clk_hw *mtk_clk_register_mux(const struct mtk_mux *mux,
-- struct regmap *regmap,
-- spinlock_t *lock)
-+static struct clk_hw *mtk_clk_register_mux(struct device *dev,
-+ const struct mtk_mux *mux,
-+ struct regmap *regmap,
-+ spinlock_t *lock)
- {
- struct mtk_clk_mux *clk_mux;
- struct clk_init_data init = {};
-@@ -177,7 +178,7 @@ static struct clk_hw *mtk_clk_register_m
- clk_mux->lock = lock;
- clk_mux->hw.init = &init;
-
-- ret = clk_hw_register(NULL, &clk_mux->hw);
-+ ret = clk_hw_register(dev, &clk_mux->hw);
- if (ret) {
- kfree(clk_mux);
- return ERR_PTR(ret);
-@@ -198,7 +199,8 @@ static void mtk_clk_unregister_mux(struc
- kfree(mux);
- }
-
--int mtk_clk_register_muxes(const struct mtk_mux *muxes,
-+int mtk_clk_register_muxes(struct device *dev,
-+ const struct mtk_mux *muxes,
- int num, struct device_node *node,
- spinlock_t *lock,
- struct clk_hw_onecell_data *clk_data)
-@@ -222,7 +224,7 @@ int mtk_clk_register_muxes(const struct
- continue;
- }
-
-- hw = mtk_clk_register_mux(mux, regmap, lock);
-+ hw = mtk_clk_register_mux(dev, mux, regmap, lock);
-
- if (IS_ERR(hw)) {
- pr_err("Failed to register clk %s: %pe\n", mux->name,
---- a/drivers/clk/mediatek/clk-mux.h
-+++ b/drivers/clk/mediatek/clk-mux.h
-@@ -83,7 +83,8 @@ extern const struct clk_ops mtk_mux_gate
- 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \
- mtk_mux_clr_set_upd_ops)
-
--int mtk_clk_register_muxes(const struct mtk_mux *muxes,
-+int mtk_clk_register_muxes(struct device *dev,
-+ const struct mtk_mux *muxes,
- int num, struct device_node *node,
- spinlock_t *lock,
- struct clk_hw_onecell_data *clk_data);
+++ /dev/null
-From b8eb1081d267708ba976525a1fe2162901b34f3a Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Fri, 20 Jan 2023 10:20:37 +0100
-Subject: [PATCH] clk: mediatek: clk-mtk: Add dummy clock ops
-
-In order to migrate some (few) old clock drivers to the common
-mtk_clk_simple_probe() function, add dummy clock ops to be able
-to insert a dummy clock with ID 0 at the beginning of the list.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Miles Chen <miles.chen@mediatek.com>
-Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
-Tested-by: Miles Chen <miles.chen@mediatek.com>
-Link: https://lore.kernel.org/r/20230120092053.182923-8-angelogioacchino.delregno@collabora.com
-Tested-by: Mingming Su <mingming.su@mediatek.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/mediatek/clk-mtk.c | 16 ++++++++++++++++
- drivers/clk/mediatek/clk-mtk.h | 19 +++++++++++++++++++
- 2 files changed, 35 insertions(+)
-
---- a/drivers/clk/mediatek/clk-mtk.c
-+++ b/drivers/clk/mediatek/clk-mtk.c
-@@ -18,6 +18,22 @@
- #include "clk-mtk.h"
- #include "clk-gate.h"
-
-+const struct mtk_gate_regs cg_regs_dummy = { 0, 0, 0 };
-+EXPORT_SYMBOL_GPL(cg_regs_dummy);
-+
-+static int mtk_clk_dummy_enable(struct clk_hw *hw)
-+{
-+ return 0;
-+}
-+
-+static void mtk_clk_dummy_disable(struct clk_hw *hw) { }
-+
-+const struct clk_ops mtk_clk_dummy_ops = {
-+ .enable = mtk_clk_dummy_enable,
-+ .disable = mtk_clk_dummy_disable,
-+};
-+EXPORT_SYMBOL_GPL(mtk_clk_dummy_ops);
-+
- static void mtk_init_clk_data(struct clk_hw_onecell_data *clk_data,
- unsigned int clk_num)
- {
---- a/drivers/clk/mediatek/clk-mtk.h
-+++ b/drivers/clk/mediatek/clk-mtk.h
-@@ -22,6 +22,25 @@
-
- struct platform_device;
-
-+/*
-+ * We need the clock IDs to start from zero but to maintain devicetree
-+ * backwards compatibility we can't change bindings to start from zero.
-+ * Only a few platforms are affected, so we solve issues given by the
-+ * commonized MTK clocks probe function(s) by adding a dummy clock at
-+ * the beginning where needed.
-+ */
-+#define CLK_DUMMY 0
-+
-+extern const struct clk_ops mtk_clk_dummy_ops;
-+extern const struct mtk_gate_regs cg_regs_dummy;
-+
-+#define GATE_DUMMY(_id, _name) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .regs = &cg_regs_dummy, \
-+ .ops = &mtk_clk_dummy_ops, \
-+ }
-+
- struct mtk_fixed_clk {
- int id;
- const char *name;
+++ /dev/null
-From c26e28015b74af73e0b299f6ad3ff22931e600b4 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Fri, 20 Jan 2023 10:20:41 +0100
-Subject: [PATCH 05/15] clk: mediatek: Switch to mtk_clk_simple_probe() where
- possible
-
-mtk_clk_simple_probe() is a function that registers mtk gate clocks
-and, if reset data is present, a reset controller and across all of
-the MTK clock drivers, such a function is duplicated many times:
-switch to the common mtk_clk_simple_probe() function for all of the
-clock drivers that are registering as platform drivers.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Miles Chen <miles.chen@mediatek.com>
-Tested-by: Miles Chen <miles.chen@mediatek.com>
-Link: https://lore.kernel.org/r/20230120092053.182923-12-angelogioacchino.delregno@collabora.com
-Tested-by: Mingming Su <mingming.su@mediatek.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-
-[daniel@makrotopia.org: removed parts not relevant for OpenWrt]
----
- drivers/clk/mediatek/clk-mt2701-aud.c | 31 ++++++----
- drivers/clk/mediatek/clk-mt2701-eth.c | 36 ++++--------
- drivers/clk/mediatek/clk-mt2701-g3d.c | 56 ++++--------------
- drivers/clk/mediatek/clk-mt2701-hif.c | 38 ++++--------
- drivers/clk/mediatek/clk-mt2712.c | 83 ++++++++++----------------
- drivers/clk/mediatek/clk-mt7622-aud.c | 54 ++++++-----------
- drivers/clk/mediatek/clk-mt7622-eth.c | 82 +++++---------------------
- drivers/clk/mediatek/clk-mt7622-hif.c | 85 +++++----------------------
- drivers/clk/mediatek/clk-mt7629-hif.c | 85 +++++----------------------
- 9 files changed, 144 insertions(+), 406 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mt2701-aud.c
-+++ b/drivers/clk/mediatek/clk-mt2701-aud.c
-@@ -52,6 +52,7 @@ static const struct mtk_gate_regs audio3
- };
-
- static const struct mtk_gate audio_clks[] = {
-+ GATE_DUMMY(CLK_DUMMY, "aud_dummy"),
- /* AUDIO0 */
- GATE_AUDIO0(CLK_AUD_AFE, "audio_afe", "aud_intbus_sel", 2),
- GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi", "audpll_sel", 20),
-@@ -114,29 +115,27 @@ static const struct mtk_gate audio_clks[
- GATE_AUDIO3(CLK_AUD_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14),
- };
-
-+static const struct mtk_clk_desc audio_desc = {
-+ .clks = audio_clks,
-+ .num_clks = ARRAY_SIZE(audio_clks),
-+};
-+
- static const struct of_device_id of_match_clk_mt2701_aud[] = {
-- { .compatible = "mediatek,mt2701-audsys", },
-- {}
-+ { .compatible = "mediatek,mt2701-audsys", .data = &audio_desc },
-+ { /* sentinel */ }
- };
-
- static int clk_mt2701_aud_probe(struct platform_device *pdev)
- {
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
- int r;
-
-- clk_data = mtk_alloc_clk_data(CLK_AUD_NR);
--
-- mtk_clk_register_gates(&pdev->dev, node, audio_clks,
-- ARRAY_SIZE(audio_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-+ r = mtk_clk_simple_probe(pdev);
- if (r) {
- dev_err(&pdev->dev,
- "could not register clock provider: %s: %d\n",
- pdev->name, r);
-
-- goto err_clk_provider;
-+ return r;
- }
-
- r = devm_of_platform_populate(&pdev->dev);
-@@ -146,13 +145,19 @@ static int clk_mt2701_aud_probe(struct p
- return 0;
-
- err_plat_populate:
-- of_clk_del_provider(node);
--err_clk_provider:
-+ mtk_clk_simple_remove(pdev);
- return r;
- }
-
-+static int clk_mt2701_aud_remove(struct platform_device *pdev)
-+{
-+ of_platform_depopulate(&pdev->dev);
-+ return mtk_clk_simple_remove(pdev);
-+}
-+
- static struct platform_driver clk_mt2701_aud_drv = {
- .probe = clk_mt2701_aud_probe,
-+ .remove = clk_mt2701_aud_remove,
- .driver = {
- .name = "clk-mt2701-aud",
- .of_match_table = of_match_clk_mt2701_aud,
---- a/drivers/clk/mediatek/clk-mt2701-eth.c
-+++ b/drivers/clk/mediatek/clk-mt2701-eth.c
-@@ -20,6 +20,7 @@ static const struct mtk_gate_regs eth_cg
- GATE_MTK(_id, _name, _parent, ð_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
-
- static const struct mtk_gate eth_clks[] = {
-+ GATE_DUMMY(CLK_DUMMY, "eth_dummy"),
- GATE_ETH(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
- GATE_ETH(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
- GATE_ETH(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
-@@ -38,35 +39,20 @@ static const struct mtk_clk_rst_desc clk
- .rst_bank_nr = ARRAY_SIZE(rst_ofs),
- };
-
--static const struct of_device_id of_match_clk_mt2701_eth[] = {
-- { .compatible = "mediatek,mt2701-ethsys", },
-- {}
-+static const struct mtk_clk_desc eth_desc = {
-+ .clks = eth_clks,
-+ .num_clks = ARRAY_SIZE(eth_clks),
-+ .rst_desc = &clk_rst_desc,
- };
-
--static int clk_mt2701_eth_probe(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- int r;
-- struct device_node *node = pdev->dev.of_node;
--
-- clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
--
-- mtk_clk_register_gates(&pdev->dev, node, eth_clks,
-- ARRAY_SIZE(eth_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
--
-- return r;
--}
-+static const struct of_device_id of_match_clk_mt2701_eth[] = {
-+ { .compatible = "mediatek,mt2701-ethsys", .data = ð_desc },
-+ { /* sentinel */ }
-+};
-
- static struct platform_driver clk_mt2701_eth_drv = {
-- .probe = clk_mt2701_eth_probe,
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
- .driver = {
- .name = "clk-mt2701-eth",
- .of_match_table = of_match_clk_mt2701_eth,
---- a/drivers/clk/mediatek/clk-mt2701-g3d.c
-+++ b/drivers/clk/mediatek/clk-mt2701-g3d.c
-@@ -26,6 +26,7 @@ static const struct mtk_gate_regs g3d_cg
- };
-
- static const struct mtk_gate g3d_clks[] = {
-+ GATE_DUMMY(CLK_DUMMY, "g3d_dummy"),
- GATE_G3D(CLK_G3DSYS_CORE, "g3d_core", "mfg_sel", 0),
- };
-
-@@ -37,57 +38,20 @@ static const struct mtk_clk_rst_desc clk
- .rst_bank_nr = ARRAY_SIZE(rst_ofs),
- };
-
--static int clk_mt2701_g3dsys_init(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
-- int r;
--
-- clk_data = mtk_alloc_clk_data(CLK_G3DSYS_NR);
--
-- mtk_clk_register_gates(&pdev->dev, node, g3d_clks, ARRAY_SIZE(g3d_clks),
-- clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
--
-- return r;
--}
-+static const struct mtk_clk_desc g3d_desc = {
-+ .clks = g3d_clks,
-+ .num_clks = ARRAY_SIZE(g3d_clks),
-+ .rst_desc = &clk_rst_desc,
-+};
-
- static const struct of_device_id of_match_clk_mt2701_g3d[] = {
-- {
-- .compatible = "mediatek,mt2701-g3dsys",
-- .data = clk_mt2701_g3dsys_init,
-- }, {
-- /* sentinel */
-- }
-+ { .compatible = "mediatek,mt2701-g3dsys", .data = &g3d_desc },
-+ { /* sentinel */ }
- };
-
--static int clk_mt2701_g3d_probe(struct platform_device *pdev)
--{
-- int (*clk_init)(struct platform_device *);
-- int r;
--
-- clk_init = of_device_get_match_data(&pdev->dev);
-- if (!clk_init)
-- return -EINVAL;
--
-- r = clk_init(pdev);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- return r;
--}
--
- static struct platform_driver clk_mt2701_g3d_drv = {
-- .probe = clk_mt2701_g3d_probe,
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
- .driver = {
- .name = "clk-mt2701-g3d",
- .of_match_table = of_match_clk_mt2701_g3d,
---- a/drivers/clk/mediatek/clk-mt2701-hif.c
-+++ b/drivers/clk/mediatek/clk-mt2701-hif.c
-@@ -20,6 +20,7 @@ static const struct mtk_gate_regs hif_cg
- GATE_MTK(_id, _name, _parent, &hif_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
-
- static const struct mtk_gate hif_clks[] = {
-+ GATE_DUMMY(CLK_DUMMY, "hif_dummy"),
- GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21),
- GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22),
- GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24),
-@@ -35,37 +36,20 @@ static const struct mtk_clk_rst_desc clk
- .rst_bank_nr = ARRAY_SIZE(rst_ofs),
- };
-
--static const struct of_device_id of_match_clk_mt2701_hif[] = {
-- { .compatible = "mediatek,mt2701-hifsys", },
-- {}
-+static const struct mtk_clk_desc hif_desc = {
-+ .clks = hif_clks,
-+ .num_clks = ARRAY_SIZE(hif_clks),
-+ .rst_desc = &clk_rst_desc,
- };
-
--static int clk_mt2701_hif_probe(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- int r;
-- struct device_node *node = pdev->dev.of_node;
--
-- clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
--
-- mtk_clk_register_gates(&pdev->dev, node, hif_clks,
-- ARRAY_SIZE(hif_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-- if (r) {
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
-- return r;
-- }
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
--
-- return 0;
--}
-+static const struct of_device_id of_match_clk_mt2701_hif[] = {
-+ { .compatible = "mediatek,mt2701-hifsys", .data = &hif_desc },
-+ { /* sentinel */ }
-+};
-
- static struct platform_driver clk_mt2701_hif_drv = {
-- .probe = clk_mt2701_hif_probe,
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
- .driver = {
- .name = "clk-mt2701-hif",
- .of_match_table = of_match_clk_mt2701_hif,
---- a/drivers/clk/mediatek/clk-mt2712.c
-+++ b/drivers/clk/mediatek/clk-mt2712.c
-@@ -1337,50 +1337,6 @@ static int clk_mt2712_top_probe(struct p
- return r;
- }
-
--static int clk_mt2712_infra_probe(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- int r;
-- struct device_node *node = pdev->dev.of_node;
--
-- clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
--
-- mtk_clk_register_gates(&pdev->dev, node, infra_clks,
-- ARRAY_SIZE(infra_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
--
-- if (r != 0)
-- pr_err("%s(): could not register clock provider: %d\n",
-- __func__, r);
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc[0]);
--
-- return r;
--}
--
--static int clk_mt2712_peri_probe(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- int r;
-- struct device_node *node = pdev->dev.of_node;
--
-- clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
--
-- mtk_clk_register_gates(&pdev->dev, node, peri_clks,
-- ARRAY_SIZE(peri_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
--
-- if (r != 0)
-- pr_err("%s(): could not register clock provider: %d\n",
-- __func__, r);
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc[1]);
--
-- return r;
--}
--
- static int clk_mt2712_mcu_probe(struct platform_device *pdev)
- {
- struct clk_hw_onecell_data *clk_data;
-@@ -1419,12 +1375,6 @@ static const struct of_device_id of_matc
- .compatible = "mediatek,mt2712-topckgen",
- .data = clk_mt2712_top_probe,
- }, {
-- .compatible = "mediatek,mt2712-infracfg",
-- .data = clk_mt2712_infra_probe,
-- }, {
-- .compatible = "mediatek,mt2712-pericfg",
-- .data = clk_mt2712_peri_probe,
-- }, {
- .compatible = "mediatek,mt2712-mcucfg",
- .data = clk_mt2712_mcu_probe,
- }, {
-@@ -1450,6 +1400,33 @@ static int clk_mt2712_probe(struct platf
- return r;
- }
-
-+static const struct mtk_clk_desc infra_desc = {
-+ .clks = infra_clks,
-+ .num_clks = ARRAY_SIZE(infra_clks),
-+ .rst_desc = &clk_rst_desc[0],
-+};
-+
-+static const struct mtk_clk_desc peri_desc = {
-+ .clks = peri_clks,
-+ .num_clks = ARRAY_SIZE(peri_clks),
-+ .rst_desc = &clk_rst_desc[1],
-+};
-+
-+static const struct of_device_id of_match_clk_mt2712_simple[] = {
-+ { .compatible = "mediatek,mt2712-infracfg", .data = &infra_desc },
-+ { .compatible = "mediatek,mt2712-pericfg", .data = &peri_desc, },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver clk_mt2712_simple_drv = {
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
-+ .driver = {
-+ .name = "clk-mt2712-simple",
-+ .of_match_table = of_match_clk_mt2712_simple,
-+ },
-+};
-+
- static struct platform_driver clk_mt2712_drv = {
- .probe = clk_mt2712_probe,
- .driver = {
-@@ -1460,7 +1437,11 @@ static struct platform_driver clk_mt2712
-
- static int __init clk_mt2712_init(void)
- {
-- return platform_driver_register(&clk_mt2712_drv);
-+ int ret = platform_driver_register(&clk_mt2712_drv);
-+
-+ if (ret)
-+ return ret;
-+ return platform_driver_register(&clk_mt2712_simple_drv);
- }
-
- arch_initcall(clk_mt2712_init);
---- a/drivers/clk/mediatek/clk-mt7622-aud.c
-+++ b/drivers/clk/mediatek/clk-mt7622-aud.c
-@@ -106,24 +106,22 @@ static const struct mtk_gate audio_clks[
- GATE_AUDIO3(CLK_AUDIO_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14),
- };
-
--static int clk_mt7622_audiosys_init(struct platform_device *pdev)
-+static const struct mtk_clk_desc audio_desc = {
-+ .clks = audio_clks,
-+ .num_clks = ARRAY_SIZE(audio_clks),
-+};
-+
-+static int clk_mt7622_aud_probe(struct platform_device *pdev)
- {
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
- int r;
-
-- clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
--
-- mtk_clk_register_gates(&pdev->dev, node, audio_clks,
-- ARRAY_SIZE(audio_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-+ r = mtk_clk_simple_probe(pdev);
- if (r) {
- dev_err(&pdev->dev,
- "could not register clock provider: %s: %d\n",
- pdev->name, r);
-
-- goto err_clk_provider;
-+ return r;
- }
-
- r = devm_of_platform_populate(&pdev->dev);
-@@ -133,40 +131,24 @@ static int clk_mt7622_audiosys_init(stru
- return 0;
-
- err_plat_populate:
-- of_clk_del_provider(node);
--err_clk_provider:
-+ mtk_clk_simple_remove(pdev);
- return r;
- }
-
--static const struct of_device_id of_match_clk_mt7622_aud[] = {
-- {
-- .compatible = "mediatek,mt7622-audsys",
-- .data = clk_mt7622_audiosys_init,
-- }, {
-- /* sentinel */
-- }
--};
--
--static int clk_mt7622_aud_probe(struct platform_device *pdev)
-+static int clk_mt7622_aud_remove(struct platform_device *pdev)
- {
-- int (*clk_init)(struct platform_device *);
-- int r;
--
-- clk_init = of_device_get_match_data(&pdev->dev);
-- if (!clk_init)
-- return -EINVAL;
--
-- r = clk_init(pdev);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- return r;
-+ of_platform_depopulate(&pdev->dev);
-+ return mtk_clk_simple_remove(pdev);
- }
-
-+static const struct of_device_id of_match_clk_mt7622_aud[] = {
-+ { .compatible = "mediatek,mt7622-audsys", .data = &audio_desc },
-+ { /* sentinel */ }
-+};
-+
- static struct platform_driver clk_mt7622_aud_drv = {
- .probe = clk_mt7622_aud_probe,
-+ .remove = clk_mt7622_aud_remove,
- .driver = {
- .name = "clk-mt7622-aud",
- .of_match_table = of_match_clk_mt7622_aud,
---- a/drivers/clk/mediatek/clk-mt7622-eth.c
-+++ b/drivers/clk/mediatek/clk-mt7622-eth.c
-@@ -61,80 +61,26 @@ static const struct mtk_clk_rst_desc clk
- .rst_bank_nr = ARRAY_SIZE(rst_ofs),
- };
-
--static int clk_mt7622_ethsys_init(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
-- int r;
--
-- clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK);
--
-- mtk_clk_register_gates(&pdev->dev, node, eth_clks,
-- ARRAY_SIZE(eth_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
--
-- return r;
--}
--
--static int clk_mt7622_sgmiisys_init(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
-- int r;
--
-- clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK);
--
-- mtk_clk_register_gates(&pdev->dev, node, sgmii_clks,
-- ARRAY_SIZE(sgmii_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
-+static const struct mtk_clk_desc eth_desc = {
-+ .clks = eth_clks,
-+ .num_clks = ARRAY_SIZE(eth_clks),
-+ .rst_desc = &clk_rst_desc,
-+};
-
-- return r;
--}
-+static const struct mtk_clk_desc sgmii_desc = {
-+ .clks = sgmii_clks,
-+ .num_clks = ARRAY_SIZE(sgmii_clks),
-+};
-
- static const struct of_device_id of_match_clk_mt7622_eth[] = {
-- {
-- .compatible = "mediatek,mt7622-ethsys",
-- .data = clk_mt7622_ethsys_init,
-- }, {
-- .compatible = "mediatek,mt7622-sgmiisys",
-- .data = clk_mt7622_sgmiisys_init,
-- }, {
-- /* sentinel */
-- }
-+ { .compatible = "mediatek,mt7622-ethsys", .data = ð_desc },
-+ { .compatible = "mediatek,mt7622-sgmiisys", .data = &sgmii_desc },
-+ { /* sentinel */ }
- };
-
--static int clk_mt7622_eth_probe(struct platform_device *pdev)
--{
-- int (*clk_init)(struct platform_device *);
-- int r;
--
-- clk_init = of_device_get_match_data(&pdev->dev);
-- if (!clk_init)
-- return -EINVAL;
--
-- r = clk_init(pdev);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- return r;
--}
--
- static struct platform_driver clk_mt7622_eth_drv = {
-- .probe = clk_mt7622_eth_probe,
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
- .driver = {
- .name = "clk-mt7622-eth",
- .of_match_table = of_match_clk_mt7622_eth,
---- a/drivers/clk/mediatek/clk-mt7622-hif.c
-+++ b/drivers/clk/mediatek/clk-mt7622-hif.c
-@@ -72,82 +72,27 @@ static const struct mtk_clk_rst_desc clk
- .rst_bank_nr = ARRAY_SIZE(rst_ofs),
- };
-
--static int clk_mt7622_ssusbsys_init(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
-- int r;
--
-- clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK);
--
-- mtk_clk_register_gates(&pdev->dev, node, ssusb_clks,
-- ARRAY_SIZE(ssusb_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
--
-- return r;
--}
--
--static int clk_mt7622_pciesys_init(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
-- int r;
--
-- clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK);
--
-- mtk_clk_register_gates(&pdev->dev, node, pcie_clks,
-- ARRAY_SIZE(pcie_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
-+static const struct mtk_clk_desc ssusb_desc = {
-+ .clks = ssusb_clks,
-+ .num_clks = ARRAY_SIZE(ssusb_clks),
-+ .rst_desc = &clk_rst_desc,
-+};
-
-- return r;
--}
-+static const struct mtk_clk_desc pcie_desc = {
-+ .clks = pcie_clks,
-+ .num_clks = ARRAY_SIZE(pcie_clks),
-+ .rst_desc = &clk_rst_desc,
-+};
-
- static const struct of_device_id of_match_clk_mt7622_hif[] = {
-- {
-- .compatible = "mediatek,mt7622-pciesys",
-- .data = clk_mt7622_pciesys_init,
-- }, {
-- .compatible = "mediatek,mt7622-ssusbsys",
-- .data = clk_mt7622_ssusbsys_init,
-- }, {
-- /* sentinel */
-- }
-+ { .compatible = "mediatek,mt7622-pciesys", .data = &pcie_desc },
-+ { .compatible = "mediatek,mt7622-ssusbsys", .data = &ssusb_desc },
-+ { /* sentinel */ }
- };
-
--static int clk_mt7622_hif_probe(struct platform_device *pdev)
--{
-- int (*clk_init)(struct platform_device *);
-- int r;
--
-- clk_init = of_device_get_match_data(&pdev->dev);
-- if (!clk_init)
-- return -EINVAL;
--
-- r = clk_init(pdev);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- return r;
--}
--
- static struct platform_driver clk_mt7622_hif_drv = {
-- .probe = clk_mt7622_hif_probe,
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
- .driver = {
- .name = "clk-mt7622-hif",
- .of_match_table = of_match_clk_mt7622_hif,
---- a/drivers/clk/mediatek/clk-mt7629-hif.c
-+++ b/drivers/clk/mediatek/clk-mt7629-hif.c
-@@ -67,82 +67,27 @@ static const struct mtk_clk_rst_desc clk
- .rst_bank_nr = ARRAY_SIZE(rst_ofs),
- };
-
--static int clk_mt7629_ssusbsys_init(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
-- int r;
--
-- clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK);
--
-- mtk_clk_register_gates(&pdev->dev, node, ssusb_clks,
-- ARRAY_SIZE(ssusb_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
--
-- return r;
--}
--
--static int clk_mt7629_pciesys_init(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
-- int r;
--
-- clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK);
--
-- mtk_clk_register_gates(&pdev->dev, node, pcie_clks,
-- ARRAY_SIZE(pcie_clks), clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
-+static const struct mtk_clk_desc ssusb_desc = {
-+ .clks = ssusb_clks,
-+ .num_clks = ARRAY_SIZE(ssusb_clks),
-+ .rst_desc = &clk_rst_desc,
-+};
-
-- return r;
--}
-+static const struct mtk_clk_desc pcie_desc = {
-+ .clks = pcie_clks,
-+ .num_clks = ARRAY_SIZE(pcie_clks),
-+ .rst_desc = &clk_rst_desc,
-+};
-
- static const struct of_device_id of_match_clk_mt7629_hif[] = {
-- {
-- .compatible = "mediatek,mt7629-pciesys",
-- .data = clk_mt7629_pciesys_init,
-- }, {
-- .compatible = "mediatek,mt7629-ssusbsys",
-- .data = clk_mt7629_ssusbsys_init,
-- }, {
-- /* sentinel */
-- }
-+ { .compatible = "mediatek,mt7629-pciesys", .data = &pcie_desc },
-+ { .compatible = "mediatek,mt7629-ssusbsys", .data = &ssusb_desc },
-+ { /* sentinel */ }
- };
-
--static int clk_mt7629_hif_probe(struct platform_device *pdev)
--{
-- int (*clk_init)(struct platform_device *);
-- int r;
--
-- clk_init = of_device_get_match_data(&pdev->dev);
-- if (!clk_init)
-- return -EINVAL;
--
-- r = clk_init(pdev);
-- if (r)
-- dev_err(&pdev->dev,
-- "could not register clock provider: %s: %d\n",
-- pdev->name, r);
--
-- return r;
--}
--
- static struct platform_driver clk_mt7629_hif_drv = {
-- .probe = clk_mt7629_hif_probe,
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
- .driver = {
- .name = "clk-mt7629-hif",
- .of_match_table = of_match_clk_mt7629_hif,
+++ /dev/null
-From 7b6183108c8ccf0dc295f39cdf78bd8078455636 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Fri, 20 Jan 2023 10:20:42 +0100
-Subject: [PATCH] clk: mediatek: clk-mtk: Extend mtk_clk_simple_probe()
-
-As a preparation to increase probe functions commonization across
-various MediaTek SoC clock controller drivers, extend function
-mtk_clk_simple_probe() to be able to register not only gates, but
-also fixed clocks, factors, muxes and composites.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Miles Chen <miles.chen@mediatek.com>
-Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
-Tested-by: Miles Chen <miles.chen@mediatek.com>
-Link: https://lore.kernel.org/r/20230120092053.182923-13-angelogioacchino.delregno@collabora.com
-Tested-by: Mingming Su <mingming.su@mediatek.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/mediatek/clk-mtk.c | 101 ++++++++++++++++++++++++++++++---
- drivers/clk/mediatek/clk-mtk.h | 10 ++++
- 2 files changed, 103 insertions(+), 8 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mtk.c
-+++ b/drivers/clk/mediatek/clk-mtk.c
-@@ -11,12 +11,14 @@
- #include <linux/mfd/syscon.h>
- #include <linux/module.h>
- #include <linux/of.h>
-+#include <linux/of_address.h>
- #include <linux/of_device.h>
- #include <linux/platform_device.h>
- #include <linux/slab.h>
-
- #include "clk-mtk.h"
- #include "clk-gate.h"
-+#include "clk-mux.h"
-
- const struct mtk_gate_regs cg_regs_dummy = { 0, 0, 0 };
- EXPORT_SYMBOL_GPL(cg_regs_dummy);
-@@ -466,20 +468,71 @@ int mtk_clk_simple_probe(struct platform
- const struct mtk_clk_desc *mcd;
- struct clk_hw_onecell_data *clk_data;
- struct device_node *node = pdev->dev.of_node;
-- int r;
-+ void __iomem *base;
-+ int num_clks, r;
-
- mcd = of_device_get_match_data(&pdev->dev);
- if (!mcd)
- return -EINVAL;
-
-- clk_data = mtk_alloc_clk_data(mcd->num_clks);
-+ /* Composite clocks needs us to pass iomem pointer */
-+ if (mcd->composite_clks) {
-+ if (!mcd->shared_io)
-+ base = devm_platform_ioremap_resource(pdev, 0);
-+ else
-+ base = of_iomap(node, 0);
-+
-+ if (IS_ERR_OR_NULL(base))
-+ return IS_ERR(base) ? PTR_ERR(base) : -ENOMEM;
-+ }
-+
-+ /* Calculate how many clk_hw_onecell_data entries to allocate */
-+ num_clks = mcd->num_clks + mcd->num_composite_clks;
-+ num_clks += mcd->num_fixed_clks + mcd->num_factor_clks;
-+ num_clks += mcd->num_mux_clks;
-+
-+ clk_data = mtk_alloc_clk_data(num_clks);
- if (!clk_data)
- return -ENOMEM;
-
-- r = mtk_clk_register_gates(&pdev->dev, node, mcd->clks, mcd->num_clks,
-- clk_data);
-- if (r)
-- goto free_data;
-+ if (mcd->fixed_clks) {
-+ r = mtk_clk_register_fixed_clks(mcd->fixed_clks,
-+ mcd->num_fixed_clks, clk_data);
-+ if (r)
-+ goto free_data;
-+ }
-+
-+ if (mcd->factor_clks) {
-+ r = mtk_clk_register_factors(mcd->factor_clks,
-+ mcd->num_factor_clks, clk_data);
-+ if (r)
-+ goto unregister_fixed_clks;
-+ }
-+
-+ if (mcd->mux_clks) {
-+ r = mtk_clk_register_muxes(&pdev->dev, mcd->mux_clks,
-+ mcd->num_mux_clks, node,
-+ mcd->clk_lock, clk_data);
-+ if (r)
-+ goto unregister_factors;
-+ };
-+
-+ if (mcd->composite_clks) {
-+ /* We don't check composite_lock because it's optional */
-+ r = mtk_clk_register_composites(&pdev->dev,
-+ mcd->composite_clks,
-+ mcd->num_composite_clks,
-+ base, mcd->clk_lock, clk_data);
-+ if (r)
-+ goto unregister_muxes;
-+ }
-+
-+ if (mcd->clks) {
-+ r = mtk_clk_register_gates(&pdev->dev, node, mcd->clks,
-+ mcd->num_clks, clk_data);
-+ if (r)
-+ goto unregister_composites;
-+ }
-
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r)
-@@ -497,9 +550,28 @@ int mtk_clk_simple_probe(struct platform
- return r;
-
- unregister_clks:
-- mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
-+ if (mcd->clks)
-+ mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
-+unregister_composites:
-+ if (mcd->composite_clks)
-+ mtk_clk_unregister_composites(mcd->composite_clks,
-+ mcd->num_composite_clks, clk_data);
-+unregister_muxes:
-+ if (mcd->mux_clks)
-+ mtk_clk_unregister_muxes(mcd->mux_clks,
-+ mcd->num_mux_clks, clk_data);
-+unregister_factors:
-+ if (mcd->factor_clks)
-+ mtk_clk_unregister_factors(mcd->factor_clks,
-+ mcd->num_factor_clks, clk_data);
-+unregister_fixed_clks:
-+ if (mcd->fixed_clks)
-+ mtk_clk_unregister_fixed_clks(mcd->fixed_clks,
-+ mcd->num_fixed_clks, clk_data);
- free_data:
- mtk_free_clk_data(clk_data);
-+ if (mcd->shared_io && base)
-+ iounmap(base);
- return r;
- }
- EXPORT_SYMBOL_GPL(mtk_clk_simple_probe);
-@@ -511,7 +583,20 @@ int mtk_clk_simple_remove(struct platfor
- struct device_node *node = pdev->dev.of_node;
-
- of_clk_del_provider(node);
-- mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
-+ if (mcd->clks)
-+ mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
-+ if (mcd->composite_clks)
-+ mtk_clk_unregister_composites(mcd->composite_clks,
-+ mcd->num_composite_clks, clk_data);
-+ if (mcd->mux_clks)
-+ mtk_clk_unregister_muxes(mcd->mux_clks,
-+ mcd->num_mux_clks, clk_data);
-+ if (mcd->factor_clks)
-+ mtk_clk_unregister_factors(mcd->factor_clks,
-+ mcd->num_factor_clks, clk_data);
-+ if (mcd->fixed_clks)
-+ mtk_clk_unregister_fixed_clks(mcd->fixed_clks,
-+ mcd->num_fixed_clks, clk_data);
- mtk_free_clk_data(clk_data);
-
- return 0;
---- a/drivers/clk/mediatek/clk-mtk.h
-+++ b/drivers/clk/mediatek/clk-mtk.h
-@@ -215,7 +215,17 @@ void mtk_clk_unregister_ref2usb_tx(struc
- struct mtk_clk_desc {
- const struct mtk_gate *clks;
- size_t num_clks;
-+ const struct mtk_composite *composite_clks;
-+ size_t num_composite_clks;
-+ const struct mtk_fixed_clk *fixed_clks;
-+ size_t num_fixed_clks;
-+ const struct mtk_fixed_factor *factor_clks;
-+ size_t num_factor_clks;
-+ const struct mtk_mux *mux_clks;
-+ size_t num_mux_clks;
- const struct mtk_clk_rst_desc *rst_desc;
-+ spinlock_t *clk_lock;
-+ bool shared_io;
- };
-
- int mtk_clk_simple_probe(struct platform_device *pdev);
+++ /dev/null
-From 3511004225ce917a4aa6e6ac61481ac60f08f401 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Fri, 20 Jan 2023 10:20:52 +0100
-Subject: [PATCH 06/15] clk: mediatek: clk-mt7986-topckgen: Properly keep some
- clocks enabled
-
-Instead of calling clk_prepare_enable() on a bunch of clocks at probe
-time, set the CLK_IS_CRITICAL flag to the same as these are required
-to be always on, and this is the right way of achieving that.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
-Reviewed-by: Miles Chen <miles.chen@mediatek.com>
-Link: https://lore.kernel.org/r/20230120092053.182923-23-angelogioacchino.delregno@collabora.com
-Tested-by: Mingming Su <mingming.su@mediatek.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/mediatek/clk-mt7986-topckgen.c | 46 +++++++++++-----------
- 1 file changed, 24 insertions(+), 22 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mt7986-topckgen.c
-+++ b/drivers/clk/mediatek/clk-mt7986-topckgen.c
-@@ -202,16 +202,23 @@ static const struct mtk_mux top_muxes[]
- MUX_GATE_CLR_SET_UPD(CLK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel",
- f_26m_adc_parents, 0x020, 0x024, 0x028, 16, 1, 23,
- 0x1C0, 10),
-- MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents,
-- 0x020, 0x024, 0x028, 24, 1, 31, 0x1C0, 11),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_SEL, "dramc_sel",
-+ f_26m_adc_parents, 0x020, 0x024, 0x028,
-+ 24, 1, 31, 0x1C0, 11,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
- /* CLK_CFG_3 */
-- MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
-- dramc_md32_parents, 0x030, 0x034, 0x038, 0, 1, 7,
-- 0x1C0, 12),
-- MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents,
-- 0x030, 0x034, 0x038, 8, 2, 15, 0x1C0, 13),
-- MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents,
-- 0x030, 0x034, 0x038, 16, 2, 23, 0x1C0, 14),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
-+ dramc_md32_parents, 0x030, 0x034, 0x038,
-+ 0, 1, 7, 0x1C0, 12,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAXI_SEL, "sysaxi_sel",
-+ sysaxi_parents, 0x030, 0x034, 0x038,
-+ 8, 2, 15, 0x1C0, 13,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAPB_SEL, "sysapb_sel",
-+ sysapb_parents, 0x030, 0x034, 0x038,
-+ 16, 2, 23, 0x1C0, 14,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
- MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
- arm_db_main_parents, 0x030, 0x034, 0x038, 24, 1,
- 31, 0x1C0, 15),
-@@ -234,9 +241,10 @@ static const struct mtk_mux top_muxes[]
- MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
- sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
- 0x1C0, 21),
-- MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel",
-- sgm_reg_parents, 0x050, 0x054, 0x058, 16, 1, 23,
-- 0x1C0, 22),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel",
-+ sgm_reg_parents, 0x050, 0x054, 0x058,
-+ 16, 1, 23, 0x1C0, 22,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
- MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
- 0x050, 0x054, 0x058, 24, 1, 31, 0x1C0, 23),
- /* CLK_CFG_6 */
-@@ -252,9 +260,10 @@ static const struct mtk_mux top_muxes[]
- f_26m_adc_parents, 0x060, 0x064, 0x068, 24, 1, 31,
- 0x1C0, 27),
- /* CLK_CFG_7 */
-- MUX_GATE_CLR_SET_UPD(CLK_TOP_F26M_SEL, "csw_f26m_sel",
-- f_26m_adc_parents, 0x070, 0x074, 0x078, 0, 1, 7,
-- 0x1C0, 28),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_F26M_SEL, "csw_f26m_sel",
-+ f_26m_adc_parents, 0x070, 0x074, 0x078,
-+ 0, 1, 7, 0x1C0, 28,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
- MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
- 0x070, 0x074, 0x078, 8, 2, 15, 0x1C0, 29),
- MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel",
-@@ -307,13 +316,6 @@ static int clk_mt7986_topckgen_probe(str
- ARRAY_SIZE(top_muxes), node,
- &mt7986_clk_lock, clk_data);
-
-- clk_prepare_enable(clk_data->hws[CLK_TOP_SYSAXI_SEL]->clk);
-- clk_prepare_enable(clk_data->hws[CLK_TOP_SYSAPB_SEL]->clk);
-- clk_prepare_enable(clk_data->hws[CLK_TOP_DRAMC_SEL]->clk);
-- clk_prepare_enable(clk_data->hws[CLK_TOP_DRAMC_MD32_SEL]->clk);
-- clk_prepare_enable(clk_data->hws[CLK_TOP_F26M_SEL]->clk);
-- clk_prepare_enable(clk_data->hws[CLK_TOP_SGM_REG_SEL]->clk);
--
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-
- if (r) {
+++ /dev/null
-From 9ce3b4e4719d4eec38b2c8da939c073835573d1d Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Fri, 20 Jan 2023 10:20:53 +0100
-Subject: [PATCH 07/15] clk: mediatek: clk-mt7986-topckgen: Migrate to
- mtk_clk_simple_probe()
-
-There are no more non-common calls in clk_mt7986_topckgen_probe():
-migrate this driver to mtk_clk_simple_probe().
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Miles Chen <miles.chen@mediatek.com>
-Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
-Link: https://lore.kernel.org/r/20230120092053.182923-24-angelogioacchino.delregno@collabora.com
-Tested-by: Mingming Su <mingming.su@mediatek.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/mediatek/clk-mt7986-topckgen.c | 55 +++++-----------------
- 1 file changed, 13 insertions(+), 42 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mt7986-topckgen.c
-+++ b/drivers/clk/mediatek/clk-mt7986-topckgen.c
-@@ -290,53 +290,24 @@ static const struct mtk_mux top_muxes[]
- 0x1C4, 5),
- };
-
--static int clk_mt7986_topckgen_probe(struct platform_device *pdev)
--{
-- struct clk_hw_onecell_data *clk_data;
-- struct device_node *node = pdev->dev.of_node;
-- int r;
-- void __iomem *base;
-- int nr = ARRAY_SIZE(top_fixed_clks) + ARRAY_SIZE(top_divs) +
-- ARRAY_SIZE(top_muxes);
--
-- base = of_iomap(node, 0);
-- if (!base) {
-- pr_err("%s(): ioremap failed\n", __func__);
-- return -ENOMEM;
-- }
--
-- clk_data = mtk_alloc_clk_data(nr);
-- if (!clk_data)
-- return -ENOMEM;
--
-- mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
-- clk_data);
-- mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
-- mtk_clk_register_muxes(&pdev->dev, top_muxes,
-- ARRAY_SIZE(top_muxes), node,
-- &mt7986_clk_lock, clk_data);
--
-- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
--
-- if (r) {
-- pr_err("%s(): could not register clock provider: %d\n",
-- __func__, r);
-- goto free_topckgen_data;
-- }
-- return r;
--
--free_topckgen_data:
-- mtk_free_clk_data(clk_data);
-- return r;
--}
-+static const struct mtk_clk_desc topck_desc = {
-+ .fixed_clks = top_fixed_clks,
-+ .num_fixed_clks = ARRAY_SIZE(top_fixed_clks),
-+ .factor_clks = top_divs,
-+ .num_factor_clks = ARRAY_SIZE(top_divs),
-+ .mux_clks = top_muxes,
-+ .num_mux_clks = ARRAY_SIZE(top_muxes),
-+ .clk_lock = &mt7986_clk_lock,
-+};
-
- static const struct of_device_id of_match_clk_mt7986_topckgen[] = {
-- { .compatible = "mediatek,mt7986-topckgen", },
-- {}
-+ { .compatible = "mediatek,mt7986-topckgen", .data = &topck_desc },
-+ { /* sentinel */ }
- };
-
- static struct platform_driver clk_mt7986_topckgen_drv = {
-- .probe = clk_mt7986_topckgen_probe,
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
- .driver = {
- .name = "clk-mt7986-topckgen",
- .of_match_table = of_match_clk_mt7986_topckgen,
+++ /dev/null
-From 06abdc84080729dc2c54946e1712c5ee1589ca1c Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Mon, 6 Mar 2023 15:05:21 +0100
-Subject: [PATCH 13/15] clk: mediatek: mt7986-apmixed: Use PLL_AO flag to set
- critical clock
-
-Instead of calling clk_prepare_enable() at probe time, add the PLL_AO
-flag to CLK_APMIXED_ARMPLL clock: this will set CLK_IS_CRITICAL.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/20230306140543.1813621-33-angelogioacchino.delregno@collabora.com
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/mediatek/clk-mt7986-apmixed.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mt7986-apmixed.c
-+++ b/drivers/clk/mediatek/clk-mt7986-apmixed.c
-@@ -42,7 +42,7 @@
- "clkxtal")
-
- static const struct mtk_pll_data plls[] = {
-- PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x0, 0, 32,
-+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x0, PLL_AO, 32,
- 0x0200, 4, 0, 0x0204, 0),
- PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x0, 0, 32,
- 0x0210, 4, 0, 0x0214, 0),
-@@ -77,8 +77,6 @@ static int clk_mt7986_apmixed_probe(stru
-
- mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
-
-- clk_prepare_enable(clk_data->hws[CLK_APMIXED_ARMPLL]->clk);
--
- r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
- if (r) {
- pr_err("%s(): could not register clock provider: %d\n",
+++ /dev/null
-From a6473d0f9f07b1196f3a67099826f50a2a4e84e8 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 26 Jan 2023 03:34:05 +0000
-Subject: [PATCH] dt-bindings: clock: mediatek: add mt7981 clock IDs
-
-Add MT7981 clock dt-bindings, include topckgen, apmixedsys,
-infracfg, and ethernet subsystem clocks.
-
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/e353d32b5a4481766519a037afe1ed44e31ece1a.1674703830.git.daniel@makrotopia.org
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- .../dt-bindings/clock/mediatek,mt7981-clk.h | 215 ++++++++++++++++++
- 1 file changed, 215 insertions(+)
- create mode 100644 include/dt-bindings/clock/mediatek,mt7981-clk.h
-
---- /dev/null
-+++ b/include/dt-bindings/clock/mediatek,mt7981-clk.h
-@@ -0,0 +1,215 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (c) 2021 MediaTek Inc.
-+ * Author: Wenzhen.Yu <wenzhen.yu@mediatek.com>
-+ * Author: Jianhui Zhao <zhaojh329@gmail.com>
-+ * Author: Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#ifndef _DT_BINDINGS_CLK_MT7981_H
-+#define _DT_BINDINGS_CLK_MT7981_H
-+
-+/* TOPCKGEN */
-+#define CLK_TOP_CB_CKSQ_40M 0
-+#define CLK_TOP_CB_M_416M 1
-+#define CLK_TOP_CB_M_D2 2
-+#define CLK_TOP_CB_M_D3 3
-+#define CLK_TOP_M_D3_D2 4
-+#define CLK_TOP_CB_M_D4 5
-+#define CLK_TOP_CB_M_D8 6
-+#define CLK_TOP_M_D8_D2 7
-+#define CLK_TOP_CB_MM_720M 8
-+#define CLK_TOP_CB_MM_D2 9
-+#define CLK_TOP_CB_MM_D3 10
-+#define CLK_TOP_CB_MM_D3_D5 11
-+#define CLK_TOP_CB_MM_D4 12
-+#define CLK_TOP_CB_MM_D6 13
-+#define CLK_TOP_MM_D6_D2 14
-+#define CLK_TOP_CB_MM_D8 15
-+#define CLK_TOP_CB_APLL2_196M 16
-+#define CLK_TOP_APLL2_D2 17
-+#define CLK_TOP_APLL2_D4 18
-+#define CLK_TOP_NET1_2500M 19
-+#define CLK_TOP_CB_NET1_D4 20
-+#define CLK_TOP_CB_NET1_D5 21
-+#define CLK_TOP_NET1_D5_D2 22
-+#define CLK_TOP_NET1_D5_D4 23
-+#define CLK_TOP_CB_NET1_D8 24
-+#define CLK_TOP_NET1_D8_D2 25
-+#define CLK_TOP_NET1_D8_D4 26
-+#define CLK_TOP_CB_NET2_800M 27
-+#define CLK_TOP_CB_NET2_D2 28
-+#define CLK_TOP_CB_NET2_D4 29
-+#define CLK_TOP_NET2_D4_D2 30
-+#define CLK_TOP_NET2_D4_D4 31
-+#define CLK_TOP_CB_NET2_D6 32
-+#define CLK_TOP_CB_WEDMCU_208M 33
-+#define CLK_TOP_CB_SGM_325M 34
-+#define CLK_TOP_CKSQ_40M_D2 35
-+#define CLK_TOP_CB_RTC_32K 36
-+#define CLK_TOP_CB_RTC_32P7K 37
-+#define CLK_TOP_USB_TX250M 38
-+#define CLK_TOP_FAUD 39
-+#define CLK_TOP_NFI1X 40
-+#define CLK_TOP_USB_EQ_RX250M 41
-+#define CLK_TOP_USB_CDR_CK 42
-+#define CLK_TOP_USB_LN0_CK 43
-+#define CLK_TOP_SPINFI_BCK 44
-+#define CLK_TOP_SPI 45
-+#define CLK_TOP_SPIM_MST 46
-+#define CLK_TOP_UART_BCK 47
-+#define CLK_TOP_PWM_BCK 48
-+#define CLK_TOP_I2C_BCK 49
-+#define CLK_TOP_PEXTP_TL 50
-+#define CLK_TOP_EMMC_208M 51
-+#define CLK_TOP_EMMC_400M 52
-+#define CLK_TOP_DRAMC_REF 53
-+#define CLK_TOP_DRAMC_MD32 54
-+#define CLK_TOP_SYSAXI 55
-+#define CLK_TOP_SYSAPB 56
-+#define CLK_TOP_ARM_DB_MAIN 57
-+#define CLK_TOP_AP2CNN_HOST 58
-+#define CLK_TOP_NETSYS 59
-+#define CLK_TOP_NETSYS_500M 60
-+#define CLK_TOP_NETSYS_WED_MCU 61
-+#define CLK_TOP_NETSYS_2X 62
-+#define CLK_TOP_SGM_325M 63
-+#define CLK_TOP_SGM_REG 64
-+#define CLK_TOP_F26M 65
-+#define CLK_TOP_EIP97B 66
-+#define CLK_TOP_USB3_PHY 67
-+#define CLK_TOP_AUD 68
-+#define CLK_TOP_A1SYS 69
-+#define CLK_TOP_AUD_L 70
-+#define CLK_TOP_A_TUNER 71
-+#define CLK_TOP_U2U3_REF 72
-+#define CLK_TOP_U2U3_SYS 73
-+#define CLK_TOP_U2U3_XHCI 74
-+#define CLK_TOP_USB_FRMCNT 75
-+#define CLK_TOP_NFI1X_SEL 76
-+#define CLK_TOP_SPINFI_SEL 77
-+#define CLK_TOP_SPI_SEL 78
-+#define CLK_TOP_SPIM_MST_SEL 79
-+#define CLK_TOP_UART_SEL 80
-+#define CLK_TOP_PWM_SEL 81
-+#define CLK_TOP_I2C_SEL 82
-+#define CLK_TOP_PEXTP_TL_SEL 83
-+#define CLK_TOP_EMMC_208M_SEL 84
-+#define CLK_TOP_EMMC_400M_SEL 85
-+#define CLK_TOP_F26M_SEL 86
-+#define CLK_TOP_DRAMC_SEL 87
-+#define CLK_TOP_DRAMC_MD32_SEL 88
-+#define CLK_TOP_SYSAXI_SEL 89
-+#define CLK_TOP_SYSAPB_SEL 90
-+#define CLK_TOP_ARM_DB_MAIN_SEL 91
-+#define CLK_TOP_AP2CNN_HOST_SEL 92
-+#define CLK_TOP_NETSYS_SEL 93
-+#define CLK_TOP_NETSYS_500M_SEL 94
-+#define CLK_TOP_NETSYS_MCU_SEL 95
-+#define CLK_TOP_NETSYS_2X_SEL 96
-+#define CLK_TOP_SGM_325M_SEL 97
-+#define CLK_TOP_SGM_REG_SEL 98
-+#define CLK_TOP_EIP97B_SEL 99
-+#define CLK_TOP_USB3_PHY_SEL 100
-+#define CLK_TOP_AUD_SEL 101
-+#define CLK_TOP_A1SYS_SEL 102
-+#define CLK_TOP_AUD_L_SEL 103
-+#define CLK_TOP_A_TUNER_SEL 104
-+#define CLK_TOP_U2U3_SEL 105
-+#define CLK_TOP_U2U3_SYS_SEL 106
-+#define CLK_TOP_U2U3_XHCI_SEL 107
-+#define CLK_TOP_USB_FRMCNT_SEL 108
-+#define CLK_TOP_AUD_I2S_M 109
-+
-+/* INFRACFG */
-+#define CLK_INFRA_66M_MCK 0
-+#define CLK_INFRA_UART0_SEL 1
-+#define CLK_INFRA_UART1_SEL 2
-+#define CLK_INFRA_UART2_SEL 3
-+#define CLK_INFRA_SPI0_SEL 4
-+#define CLK_INFRA_SPI1_SEL 5
-+#define CLK_INFRA_SPI2_SEL 6
-+#define CLK_INFRA_PWM1_SEL 7
-+#define CLK_INFRA_PWM2_SEL 8
-+#define CLK_INFRA_PWM3_SEL 9
-+#define CLK_INFRA_PWM_BSEL 10
-+#define CLK_INFRA_PCIE_SEL 11
-+#define CLK_INFRA_GPT_STA 12
-+#define CLK_INFRA_PWM_HCK 13
-+#define CLK_INFRA_PWM_STA 14
-+#define CLK_INFRA_PWM1_CK 15
-+#define CLK_INFRA_PWM2_CK 16
-+#define CLK_INFRA_PWM3_CK 17
-+#define CLK_INFRA_CQ_DMA_CK 18
-+#define CLK_INFRA_AUD_BUS_CK 19
-+#define CLK_INFRA_AUD_26M_CK 20
-+#define CLK_INFRA_AUD_L_CK 21
-+#define CLK_INFRA_AUD_AUD_CK 22
-+#define CLK_INFRA_AUD_EG2_CK 23
-+#define CLK_INFRA_DRAMC_26M_CK 24
-+#define CLK_INFRA_DBG_CK 25
-+#define CLK_INFRA_AP_DMA_CK 26
-+#define CLK_INFRA_SEJ_CK 27
-+#define CLK_INFRA_SEJ_13M_CK 28
-+#define CLK_INFRA_THERM_CK 29
-+#define CLK_INFRA_I2C0_CK 30
-+#define CLK_INFRA_UART0_CK 31
-+#define CLK_INFRA_UART1_CK 32
-+#define CLK_INFRA_UART2_CK 33
-+#define CLK_INFRA_SPI2_CK 34
-+#define CLK_INFRA_SPI2_HCK_CK 35
-+#define CLK_INFRA_NFI1_CK 36
-+#define CLK_INFRA_SPINFI1_CK 37
-+#define CLK_INFRA_NFI_HCK_CK 38
-+#define CLK_INFRA_SPI0_CK 39
-+#define CLK_INFRA_SPI1_CK 40
-+#define CLK_INFRA_SPI0_HCK_CK 41
-+#define CLK_INFRA_SPI1_HCK_CK 42
-+#define CLK_INFRA_FRTC_CK 43
-+#define CLK_INFRA_MSDC_CK 44
-+#define CLK_INFRA_MSDC_HCK_CK 45
-+#define CLK_INFRA_MSDC_133M_CK 46
-+#define CLK_INFRA_MSDC_66M_CK 47
-+#define CLK_INFRA_ADC_26M_CK 48
-+#define CLK_INFRA_ADC_FRC_CK 49
-+#define CLK_INFRA_FBIST2FPC_CK 50
-+#define CLK_INFRA_I2C_MCK_CK 51
-+#define CLK_INFRA_I2C_PCK_CK 52
-+#define CLK_INFRA_IUSB_133_CK 53
-+#define CLK_INFRA_IUSB_66M_CK 54
-+#define CLK_INFRA_IUSB_SYS_CK 55
-+#define CLK_INFRA_IUSB_CK 56
-+#define CLK_INFRA_IPCIE_CK 57
-+#define CLK_INFRA_IPCIE_PIPE_CK 58
-+#define CLK_INFRA_IPCIER_CK 59
-+#define CLK_INFRA_IPCIEB_CK 60
-+
-+/* APMIXEDSYS */
-+#define CLK_APMIXED_ARMPLL 0
-+#define CLK_APMIXED_NET2PLL 1
-+#define CLK_APMIXED_MMPLL 2
-+#define CLK_APMIXED_SGMPLL 3
-+#define CLK_APMIXED_WEDMCUPLL 4
-+#define CLK_APMIXED_NET1PLL 5
-+#define CLK_APMIXED_MPLL 6
-+#define CLK_APMIXED_APLL2 7
-+
-+/* SGMIISYS_0 */
-+#define CLK_SGM0_TX_EN 0
-+#define CLK_SGM0_RX_EN 1
-+#define CLK_SGM0_CK0_EN 2
-+#define CLK_SGM0_CDR_CK0_EN 3
-+
-+/* SGMIISYS_1 */
-+#define CLK_SGM1_TX_EN 0
-+#define CLK_SGM1_RX_EN 1
-+#define CLK_SGM1_CK1_EN 2
-+#define CLK_SGM1_CDR_CK1_EN 3
-+
-+/* ETHSYS */
-+#define CLK_ETH_FE_EN 0
-+#define CLK_ETH_GP2_EN 1
-+#define CLK_ETH_GP1_EN 2
-+#define CLK_ETH_WOCPU0_EN 3
-+
-+#endif /* _DT_BINDINGS_CLK_MT7981_H */
+++ /dev/null
-From 8efeeb9c8b4ecf4fb4a74be9403aba951403bbaa Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 26 Jan 2023 03:34:24 +0000
-Subject: [PATCH] clk: mediatek: add MT7981 clock support
-
-Add MT7981 clock support, include topckgen, apmixedsys, infracfg and
-ethernet subsystem clocks.
-
-The drivers are based on clk-mt7981.c which can be found in MediaTek's
-SDK sources. To be fit for upstream inclusion the driver has been split
-into clock domains and the infracfg part has been significantly
-de-bloated by removing all the 1:1 factors (aliases).
-
-Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/8136eb5b2049177bc2f6d3e0f2aefecc342d626f.1674703830.git.daniel@makrotopia.org
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-[sboyd@kernel.org: Add module license]
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/mediatek/Kconfig | 17 +
- drivers/clk/mediatek/Makefile | 4 +
- drivers/clk/mediatek/clk-mt7981-apmixed.c | 102 +++++
- drivers/clk/mediatek/clk-mt7981-eth.c | 118 ++++++
- drivers/clk/mediatek/clk-mt7981-infracfg.c | 207 ++++++++++
- drivers/clk/mediatek/clk-mt7981-topckgen.c | 422 +++++++++++++++++++++
- 6 files changed, 870 insertions(+)
- create mode 100644 drivers/clk/mediatek/clk-mt7981-apmixed.c
- create mode 100644 drivers/clk/mediatek/clk-mt7981-eth.c
- create mode 100644 drivers/clk/mediatek/clk-mt7981-infracfg.c
- create mode 100644 drivers/clk/mediatek/clk-mt7981-topckgen.c
-
---- a/drivers/clk/mediatek/Kconfig
-+++ b/drivers/clk/mediatek/Kconfig
-@@ -381,6 +381,23 @@ config COMMON_CLK_MT7629_HIFSYS
- This driver supports MediaTek MT7629 HIFSYS clocks providing
- to PCI-E and USB.
-
-+config COMMON_CLK_MT7981
-+ bool "Clock driver for MediaTek MT7981"
-+ depends on ARCH_MEDIATEK || COMPILE_TEST
-+ select COMMON_CLK_MEDIATEK
-+ default ARCH_MEDIATEK
-+ help
-+ This driver supports MediaTek MT7981 basic clocks and clocks
-+ required for various peripherals found on this SoC.
-+
-+config COMMON_CLK_MT7981_ETHSYS
-+ tristate "Clock driver for MediaTek MT7981 ETHSYS"
-+ depends on COMMON_CLK_MT7981
-+ default COMMON_CLK_MT7981
-+ help
-+ This driver adds support for clocks for Ethernet and SGMII
-+ required on MediaTek MT7981 SoC.
-+
- config COMMON_CLK_MT7986
- bool "Clock driver for MediaTek MT7986"
- depends on ARCH_MEDIATEK || COMPILE_TEST
---- a/drivers/clk/mediatek/Makefile
-+++ b/drivers/clk/mediatek/Makefile
-@@ -52,6 +52,10 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) +
- obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
- obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
- obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
-+obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-apmixed.o
-+obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-topckgen.o
-+obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-infracfg.o
-+obj-$(CONFIG_COMMON_CLK_MT7981_ETHSYS) += clk-mt7981-eth.o
- obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
- obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
- obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt7981-apmixed.c
-@@ -0,0 +1,102 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2021 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
-+ * Author: Jianhui Zhao <zhaojh329@gmail.com>
-+ * Author: Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+
-+#include "clk-gate.h"
-+#include "clk-mtk.h"
-+#include "clk-mux.h"
-+#include "clk-pll.h"
-+
-+#include <dt-bindings/clock/mediatek,mt7981-clk.h>
-+#include <linux/clk.h>
-+
-+#define MT7981_PLL_FMAX (2500UL * MHZ)
-+#define CON0_MT7981_RST_BAR BIT(27)
-+
-+#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
-+ _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
-+ _div_table, _parent_name) \
-+ { \
-+ .id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg, \
-+ .en_mask = _en_mask, .flags = _flags, \
-+ .rst_bar_mask = CON0_MT7981_RST_BAR, .fmax = MT7981_PLL_FMAX, \
-+ .pcwbits = _pcwbits, .pd_reg = _pd_reg, .pd_shift = _pd_shift, \
-+ .tuner_reg = _tuner_reg, .pcw_reg = _pcw_reg, \
-+ .pcw_shift = _pcw_shift, .div_table = _div_table, \
-+ .parent_name = _parent_name, \
-+ }
-+
-+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
-+ _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) \
-+ PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
-+ _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, NULL, \
-+ "clkxtal")
-+
-+static const struct mtk_pll_data plls[] = {
-+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, PLL_AO,
-+ 32, 0x0200, 4, 0, 0x0204, 0),
-+ PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x00000001, 0, 32,
-+ 0x0210, 4, 0, 0x0214, 0),
-+ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0220, 0x022C, 0x00000001, 0, 32,
-+ 0x0220, 4, 0, 0x0224, 0),
-+ PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0230, 0x023C, 0x00000001, 0, 32,
-+ 0x0230, 4, 0, 0x0234, 0),
-+ PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0240, 0x024C, 0x00000001, 0, 32,
-+ 0x0240, 4, 0, 0x0244, 0),
-+ PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0250, 0x025C, 0x00000001, 0, 32,
-+ 0x0250, 4, 0, 0x0254, 0),
-+ PLL(CLK_APMIXED_MPLL, "mpll", 0x0260, 0x0270, 0x00000001, 0, 32,
-+ 0x0260, 4, 0, 0x0264, 0),
-+ PLL(CLK_APMIXED_APLL2, "apll2", 0x0278, 0x0288, 0x00000001, 0, 32,
-+ 0x0278, 4, 0, 0x027C, 0),
-+};
-+
-+static const struct of_device_id of_match_clk_mt7981_apmixed[] = {
-+ { .compatible = "mediatek,mt7981-apmixedsys", },
-+ { /* sentinel */ }
-+};
-+
-+static int clk_mt7981_apmixed_probe(struct platform_device *pdev)
-+{
-+ struct clk_hw_onecell_data *clk_data;
-+ struct device_node *node = pdev->dev.of_node;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
-+ if (!clk_data)
-+ return -ENOMEM;
-+
-+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
-+
-+ r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-+ if (r) {
-+ pr_err("%s(): could not register clock provider: %d\n",
-+ __func__, r);
-+ goto free_apmixed_data;
-+ }
-+ return r;
-+
-+free_apmixed_data:
-+ mtk_free_clk_data(clk_data);
-+ return r;
-+}
-+
-+static struct platform_driver clk_mt7981_apmixed_drv = {
-+ .probe = clk_mt7981_apmixed_probe,
-+ .driver = {
-+ .name = "clk-mt7981-apmixed",
-+ .of_match_table = of_match_clk_mt7981_apmixed,
-+ },
-+};
-+builtin_platform_driver(clk_mt7981_apmixed_drv);
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt7981-eth.c
-@@ -0,0 +1,118 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2021 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
-+ * Author: Jianhui Zhao <zhaojh329@gmail.com>
-+ * Author: Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+
-+#include "clk-mtk.h"
-+#include "clk-gate.h"
-+
-+#include <dt-bindings/clock/mediatek,mt7981-clk.h>
-+
-+static const struct mtk_gate_regs sgmii0_cg_regs = {
-+ .set_ofs = 0xE4,
-+ .clr_ofs = 0xE4,
-+ .sta_ofs = 0xE4,
-+};
-+
-+#define GATE_SGMII0(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &sgmii0_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate sgmii0_clks[] __initconst = {
-+ GATE_SGMII0(CLK_SGM0_TX_EN, "sgm0_tx_en", "usb_tx250m", 2),
-+ GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", "usb_eq_rx250m", 3),
-+ GATE_SGMII0(CLK_SGM0_CK0_EN, "sgm0_ck0_en", "usb_ln0", 4),
-+ GATE_SGMII0(CLK_SGM0_CDR_CK0_EN, "sgm0_cdr_ck0_en", "usb_cdr", 5),
-+};
-+
-+static const struct mtk_gate_regs sgmii1_cg_regs = {
-+ .set_ofs = 0xE4,
-+ .clr_ofs = 0xE4,
-+ .sta_ofs = 0xE4,
-+};
-+
-+#define GATE_SGMII1(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &sgmii1_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate sgmii1_clks[] __initconst = {
-+ GATE_SGMII1(CLK_SGM1_TX_EN, "sgm1_tx_en", "usb_tx250m", 2),
-+ GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", "usb_eq_rx250m", 3),
-+ GATE_SGMII1(CLK_SGM1_CK1_EN, "sgm1_ck1_en", "usb_ln0", 4),
-+ GATE_SGMII1(CLK_SGM1_CDR_CK1_EN, "sgm1_cdr_ck1_en", "usb_cdr", 5),
-+};
-+
-+static const struct mtk_gate_regs eth_cg_regs = {
-+ .set_ofs = 0x30,
-+ .clr_ofs = 0x30,
-+ .sta_ofs = 0x30,
-+};
-+
-+#define GATE_ETH(_id, _name, _parent, _shift) { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = ð_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate eth_clks[] __initconst = {
-+ GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x", 6),
-+ GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m", 7),
-+ GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m", 8),
-+ GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", "netsys_wed_mcu", 15),
-+};
-+
-+static const struct mtk_clk_desc eth_desc = {
-+ .clks = eth_clks,
-+ .num_clks = ARRAY_SIZE(eth_clks),
-+};
-+
-+static const struct mtk_clk_desc sgmii0_desc = {
-+ .clks = sgmii0_clks,
-+ .num_clks = ARRAY_SIZE(sgmii0_clks),
-+};
-+
-+static const struct mtk_clk_desc sgmii1_desc = {
-+ .clks = sgmii1_clks,
-+ .num_clks = ARRAY_SIZE(sgmii1_clks),
-+};
-+
-+static const struct of_device_id of_match_clk_mt7981_eth[] = {
-+ { .compatible = "mediatek,mt7981-ethsys", .data = ð_desc },
-+ { .compatible = "mediatek,mt7981-sgmiisys_0", .data = &sgmii0_desc },
-+ { .compatible = "mediatek,mt7981-sgmiisys_1", .data = &sgmii1_desc },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver clk_mt7981_eth_drv = {
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
-+ .driver = {
-+ .name = "clk-mt7981-eth",
-+ .of_match_table = of_match_clk_mt7981_eth,
-+ },
-+};
-+module_platform_driver(clk_mt7981_eth_drv);
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt7981-infracfg.c
-@@ -0,0 +1,207 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2021 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
-+ * Author: Jianhui Zhao <zhaojh329@gmail.com>
-+ * Author: Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include "clk-mtk.h"
-+#include "clk-gate.h"
-+#include "clk-mux.h"
-+
-+#include <dt-bindings/clock/mediatek,mt7981-clk.h>
-+#include <linux/clk.h>
-+
-+static DEFINE_SPINLOCK(mt7981_clk_lock);
-+
-+static const struct mtk_fixed_factor infra_divs[] = {
-+ FACTOR(CLK_INFRA_66M_MCK, "infra_66m_mck", "sysaxi_sel", 1, 2),
-+};
-+
-+static const char *const infra_uart_parent[] __initconst = { "csw_f26m_sel",
-+ "uart_sel" };
-+
-+static const char *const infra_spi0_parents[] __initconst = { "i2c_sel",
-+ "spi_sel" };
-+
-+static const char *const infra_spi1_parents[] __initconst = { "i2c_sel",
-+ "spim_mst_sel" };
-+
-+static const char *const infra_pwm1_parents[] __initconst = { "pwm_sel" };
-+
-+static const char *const infra_pwm_bsel_parents[] __initconst = {
-+ "cb_rtc_32p7k", "csw_f26m_sel", "infra_66m_mck", "pwm_sel"
-+};
-+
-+static const char *const infra_pcie_parents[] __initconst = {
-+ "cb_rtc_32p7k", "csw_f26m_sel", "cb_cksq_40m", "pextp_tl_ck_sel"
-+};
-+
-+static const struct mtk_mux infra_muxes[] = {
-+ /* MODULE_CLK_SEL_0 */
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART0_SEL, "infra_uart0_sel",
-+ infra_uart_parent, 0x0018, 0x0010, 0x0014, 0, 1,
-+ -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART1_SEL, "infra_uart1_sel",
-+ infra_uart_parent, 0x0018, 0x0010, 0x0014, 1, 1,
-+ -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART2_SEL, "infra_uart2_sel",
-+ infra_uart_parent, 0x0018, 0x0010, 0x0014, 2, 1,
-+ -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI0_SEL, "infra_spi0_sel",
-+ infra_spi0_parents, 0x0018, 0x0010, 0x0014, 4, 1,
-+ -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI1_SEL, "infra_spi1_sel",
-+ infra_spi1_parents, 0x0018, 0x0010, 0x0014, 5, 1,
-+ -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI2_SEL, "infra_spi2_sel",
-+ infra_spi0_parents, 0x0018, 0x0010, 0x0014, 6, 1,
-+ -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM1_SEL, "infra_pwm1_sel",
-+ infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 9, 1,
-+ -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM2_SEL, "infra_pwm2_sel",
-+ infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 11, 1,
-+ -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM3_SEL, "infra_pwm3_sel",
-+ infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 15, 1,
-+ -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BSEL, "infra_pwm_bsel",
-+ infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 13,
-+ 2, -1, -1, -1),
-+ /* MODULE_CLK_SEL_1 */
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_SEL, "infra_pcie_sel",
-+ infra_pcie_parents, 0x0028, 0x0020, 0x0024, 0, 2,
-+ -1, -1, -1),
-+};
-+
-+static const struct mtk_gate_regs infra0_cg_regs = {
-+ .set_ofs = 0x40,
-+ .clr_ofs = 0x44,
-+ .sta_ofs = 0x48,
-+};
-+
-+static const struct mtk_gate_regs infra1_cg_regs = {
-+ .set_ofs = 0x50,
-+ .clr_ofs = 0x54,
-+ .sta_ofs = 0x58,
-+};
-+
-+static const struct mtk_gate_regs infra2_cg_regs = {
-+ .set_ofs = 0x60,
-+ .clr_ofs = 0x64,
-+ .sta_ofs = 0x68,
-+};
-+
-+#define GATE_INFRA0(_id, _name, _parent, _shift) \
-+ { \
-+ .id = _id, .name = _name, .parent_name = _parent, \
-+ .regs = &infra0_cg_regs, .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr, \
-+ }
-+
-+#define GATE_INFRA1(_id, _name, _parent, _shift) \
-+ { \
-+ .id = _id, .name = _name, .parent_name = _parent, \
-+ .regs = &infra1_cg_regs, .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr, \
-+ }
-+
-+#define GATE_INFRA2(_id, _name, _parent, _shift) \
-+ { \
-+ .id = _id, .name = _name, .parent_name = _parent, \
-+ .regs = &infra2_cg_regs, .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_setclr, \
-+ }
-+
-+static const struct mtk_gate infra_clks[] = {
-+ /* INFRA0 */
-+ GATE_INFRA0(CLK_INFRA_GPT_STA, "infra_gpt_sta", "infra_66m_mck", 0),
-+ GATE_INFRA0(CLK_INFRA_PWM_HCK, "infra_pwm_hck", "infra_66m_mck", 1),
-+ GATE_INFRA0(CLK_INFRA_PWM_STA, "infra_pwm_sta", "infra_pwm_bsel", 2),
-+ GATE_INFRA0(CLK_INFRA_PWM1_CK, "infra_pwm1", "infra_pwm1_sel", 3),
-+ GATE_INFRA0(CLK_INFRA_PWM2_CK, "infra_pwm2", "infra_pwm2_sel", 4),
-+ GATE_INFRA0(CLK_INFRA_CQ_DMA_CK, "infra_cq_dma", "sysaxi", 6),
-+
-+ GATE_INFRA0(CLK_INFRA_AUD_BUS_CK, "infra_aud_bus", "sysaxi", 8),
-+ GATE_INFRA0(CLK_INFRA_AUD_26M_CK, "infra_aud_26m", "csw_f26m_sel", 9),
-+ GATE_INFRA0(CLK_INFRA_AUD_L_CK, "infra_aud_l", "aud_l", 10),
-+ GATE_INFRA0(CLK_INFRA_AUD_AUD_CK, "infra_aud_aud", "a1sys", 11),
-+ GATE_INFRA0(CLK_INFRA_AUD_EG2_CK, "infra_aud_eg2", "a_tuner", 13),
-+ GATE_INFRA0(CLK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", "csw_f26m_sel",
-+ 14),
-+ GATE_INFRA0(CLK_INFRA_DBG_CK, "infra_dbg", "infra_66m_mck", 15),
-+ GATE_INFRA0(CLK_INFRA_AP_DMA_CK, "infra_ap_dma", "infra_66m_mck", 16),
-+ GATE_INFRA0(CLK_INFRA_SEJ_CK, "infra_sej", "infra_66m_mck", 24),
-+ GATE_INFRA0(CLK_INFRA_SEJ_13M_CK, "infra_sej_13m", "csw_f26m_sel", 25),
-+ GATE_INFRA0(CLK_INFRA_PWM3_CK, "infra_pwm3", "infra_pwm3_sel", 27),
-+ /* INFRA1 */
-+ GATE_INFRA1(CLK_INFRA_THERM_CK, "infra_therm", "csw_f26m_sel", 0),
-+ GATE_INFRA1(CLK_INFRA_I2C0_CK, "infra_i2c0", "i2c_bck", 1),
-+ GATE_INFRA1(CLK_INFRA_UART0_CK, "infra_uart0", "infra_uart0_sel", 2),
-+ GATE_INFRA1(CLK_INFRA_UART1_CK, "infra_uart1", "infra_uart1_sel", 3),
-+ GATE_INFRA1(CLK_INFRA_UART2_CK, "infra_uart2", "infra_uart2_sel", 4),
-+ GATE_INFRA1(CLK_INFRA_SPI2_CK, "infra_spi2", "infra_spi2_sel", 6),
-+ GATE_INFRA1(CLK_INFRA_SPI2_HCK_CK, "infra_spi2_hck", "infra_66m_mck", 7),
-+ GATE_INFRA1(CLK_INFRA_NFI1_CK, "infra_nfi1", "nfi1x", 8),
-+ GATE_INFRA1(CLK_INFRA_SPINFI1_CK, "infra_spinfi1", "spinfi_bck", 9),
-+ GATE_INFRA1(CLK_INFRA_NFI_HCK_CK, "infra_nfi_hck", "infra_66m_mck", 10),
-+ GATE_INFRA1(CLK_INFRA_SPI0_CK, "infra_spi0", "infra_spi0_sel", 11),
-+ GATE_INFRA1(CLK_INFRA_SPI1_CK, "infra_spi1", "infra_spi1_sel", 12),
-+ GATE_INFRA1(CLK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", "infra_66m_mck",
-+ 13),
-+ GATE_INFRA1(CLK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", "infra_66m_mck",
-+ 14),
-+ GATE_INFRA1(CLK_INFRA_FRTC_CK, "infra_frtc", "cb_rtc_32k", 15),
-+ GATE_INFRA1(CLK_INFRA_MSDC_CK, "infra_msdc", "emmc_400m", 16),
-+ GATE_INFRA1(CLK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", "emmc_208m", 17),
-+ GATE_INFRA1(CLK_INFRA_MSDC_133M_CK, "infra_msdc_133m", "sysaxi", 18),
-+ GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "sysaxi", 19),
-+ GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "infra_adc_frc", 20),
-+ GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m", 21),
-+ GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x", 23),
-+ GATE_INFRA1(CLK_INFRA_I2C_MCK_CK, "infra_i2c_mck", "sysaxi", 25),
-+ GATE_INFRA1(CLK_INFRA_I2C_PCK_CK, "infra_i2c_pck", "infra_66m_mck", 26),
-+ /* INFRA2 */
-+ GATE_INFRA2(CLK_INFRA_IUSB_133_CK, "infra_iusb_133", "sysaxi", 0),
-+ GATE_INFRA2(CLK_INFRA_IUSB_66M_CK, "infra_iusb_66m", "sysaxi", 1),
-+ GATE_INFRA2(CLK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", "u2u3_sys", 2),
-+ GATE_INFRA2(CLK_INFRA_IUSB_CK, "infra_iusb", "u2u3_ref", 3),
-+ GATE_INFRA2(CLK_INFRA_IPCIE_CK, "infra_ipcie", "pextp_tl", 12),
-+ GATE_INFRA2(CLK_INFRA_IPCIE_PIPE_CK, "infra_ipcie_pipe", "cb_cksq_40m",
-+ 13),
-+ GATE_INFRA2(CLK_INFRA_IPCIER_CK, "infra_ipcier", "csw_f26m", 14),
-+ GATE_INFRA2(CLK_INFRA_IPCIEB_CK, "infra_ipcieb", "sysaxi", 15),
-+};
-+
-+static const struct mtk_clk_desc infracfg_desc = {
-+ .factor_clks = infra_divs,
-+ .num_factor_clks = ARRAY_SIZE(infra_divs),
-+ .mux_clks = infra_muxes,
-+ .num_mux_clks = ARRAY_SIZE(infra_muxes),
-+ .clks = infra_clks,
-+ .num_clks = ARRAY_SIZE(infra_clks),
-+ .clk_lock = &mt7981_clk_lock,
-+};
-+
-+static const struct of_device_id of_match_clk_mt7981_infracfg[] = {
-+ { .compatible = "mediatek,mt7981-infracfg", .data = &infracfg_desc },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver clk_mt7981_infracfg_drv = {
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
-+ .driver = {
-+ .name = "clk-mt7981-infracfg",
-+ .of_match_table = of_match_clk_mt7981_infracfg,
-+ },
-+};
-+builtin_platform_driver(clk_mt7981_infracfg_drv);
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt7981-topckgen.c
-@@ -0,0 +1,422 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2021 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
-+ * Author: Jianhui Zhao <zhaojh329@gmail.com>
-+ */
-+
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include "clk-mtk.h"
-+#include "clk-gate.h"
-+#include "clk-mux.h"
-+
-+#include <dt-bindings/clock/mediatek,mt7981-clk.h>
-+#include <linux/clk.h>
-+
-+static DEFINE_SPINLOCK(mt7981_clk_lock);
-+
-+static const struct mtk_fixed_factor top_divs[] = {
-+ FACTOR(CLK_TOP_CB_CKSQ_40M, "cb_cksq_40m", "clkxtal", 1, 1),
-+ FACTOR(CLK_TOP_CB_M_416M, "cb_m_416m", "mpll", 1, 1),
-+ FACTOR(CLK_TOP_CB_M_D2, "cb_m_d2", "mpll", 1, 2),
-+ FACTOR(CLK_TOP_CB_M_D3, "cb_m_d3", "mpll", 1, 3),
-+ FACTOR(CLK_TOP_M_D3_D2, "m_d3_d2", "mpll", 1, 2),
-+ FACTOR(CLK_TOP_CB_M_D4, "cb_m_d4", "mpll", 1, 4),
-+ FACTOR(CLK_TOP_CB_M_D8, "cb_m_d8", "mpll", 1, 8),
-+ FACTOR(CLK_TOP_M_D8_D2, "m_d8_d2", "mpll", 1, 16),
-+ FACTOR(CLK_TOP_CB_MM_720M, "cb_mm_720m", "mmpll", 1, 1),
-+ FACTOR(CLK_TOP_CB_MM_D2, "cb_mm_d2", "mmpll", 1, 2),
-+ FACTOR(CLK_TOP_CB_MM_D3, "cb_mm_d3", "mmpll", 1, 3),
-+ FACTOR(CLK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5", "mmpll", 1, 15),
-+ FACTOR(CLK_TOP_CB_MM_D4, "cb_mm_d4", "mmpll", 1, 4),
-+ FACTOR(CLK_TOP_CB_MM_D6, "cb_mm_d6", "mmpll", 1, 6),
-+ FACTOR(CLK_TOP_MM_D6_D2, "mm_d6_d2", "mmpll", 1, 12),
-+ FACTOR(CLK_TOP_CB_MM_D8, "cb_mm_d8", "mmpll", 1, 8),
-+ FACTOR(CLK_TOP_CB_APLL2_196M, "cb_apll2_196m", "apll2", 1, 1),
-+ FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2", 1, 2),
-+ FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
-+ FACTOR(CLK_TOP_NET1_2500M, "net1_2500m", "net1pll", 1, 1),
-+ FACTOR(CLK_TOP_CB_NET1_D4, "cb_net1_d4", "net1pll", 1, 4),
-+ FACTOR(CLK_TOP_CB_NET1_D5, "cb_net1_d5", "net1pll", 1, 5),
-+ FACTOR(CLK_TOP_NET1_D5_D2, "net1_d5_d2", "net1pll", 1, 10),
-+ FACTOR(CLK_TOP_NET1_D5_D4, "net1_d5_d4", "net1pll", 1, 20),
-+ FACTOR(CLK_TOP_CB_NET1_D8, "cb_net1_d8", "net1pll", 1, 8),
-+ FACTOR(CLK_TOP_NET1_D8_D2, "net1_d8_d2", "net1pll", 1, 16),
-+ FACTOR(CLK_TOP_NET1_D8_D4, "net1_d8_d4", "net1pll", 1, 32),
-+ FACTOR(CLK_TOP_CB_NET2_800M, "cb_net2_800m", "net2pll", 1, 1),
-+ FACTOR(CLK_TOP_CB_NET2_D2, "cb_net2_d2", "net2pll", 1, 2),
-+ FACTOR(CLK_TOP_CB_NET2_D4, "cb_net2_d4", "net2pll", 1, 4),
-+ FACTOR(CLK_TOP_NET2_D4_D2, "net2_d4_d2", "net2pll", 1, 8),
-+ FACTOR(CLK_TOP_NET2_D4_D4, "net2_d4_d4", "net2pll", 1, 16),
-+ FACTOR(CLK_TOP_CB_NET2_D6, "cb_net2_d6", "net2pll", 1, 6),
-+ FACTOR(CLK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m", "wedmcupll", 1, 1),
-+ FACTOR(CLK_TOP_CB_SGM_325M, "cb_sgm_325m", "sgmpll", 1, 1),
-+ FACTOR(CLK_TOP_CKSQ_40M_D2, "cksq_40m_d2", "cb_cksq_40m", 1, 2),
-+ FACTOR(CLK_TOP_CB_RTC_32K, "cb_rtc_32k", "cb_cksq_40m", 1, 1250),
-+ FACTOR(CLK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", "cb_cksq_40m", 1, 1220),
-+ FACTOR(CLK_TOP_USB_TX250M, "usb_tx250m", "cb_cksq_40m", 1, 1),
-+ FACTOR(CLK_TOP_FAUD, "faud", "aud_sel", 1, 1),
-+ FACTOR(CLK_TOP_NFI1X, "nfi1x", "nfi1x_sel", 1, 1),
-+ FACTOR(CLK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", "cb_cksq_40m", 1, 1),
-+ FACTOR(CLK_TOP_USB_CDR_CK, "usb_cdr", "cb_cksq_40m", 1, 1),
-+ FACTOR(CLK_TOP_USB_LN0_CK, "usb_ln0", "cb_cksq_40m", 1, 1),
-+ FACTOR(CLK_TOP_SPINFI_BCK, "spinfi_bck", "spinfi_sel", 1, 1),
-+ FACTOR(CLK_TOP_SPI, "spi", "spi_sel", 1, 1),
-+ FACTOR(CLK_TOP_SPIM_MST, "spim_mst", "spim_mst_sel", 1, 1),
-+ FACTOR(CLK_TOP_UART_BCK, "uart_bck", "uart_sel", 1, 1),
-+ FACTOR(CLK_TOP_PWM_BCK, "pwm_bck", "pwm_sel", 1, 1),
-+ FACTOR(CLK_TOP_I2C_BCK, "i2c_bck", "i2c_sel", 1, 1),
-+ FACTOR(CLK_TOP_PEXTP_TL, "pextp_tl", "pextp_tl_ck_sel", 1, 1),
-+ FACTOR(CLK_TOP_EMMC_208M, "emmc_208m", "emmc_208m_sel", 1, 1),
-+ FACTOR(CLK_TOP_EMMC_400M, "emmc_400m", "emmc_400m_sel", 1, 1),
-+ FACTOR(CLK_TOP_DRAMC_REF, "dramc_ref", "dramc_sel", 1, 1),
-+ FACTOR(CLK_TOP_DRAMC_MD32, "dramc_md32", "dramc_md32_sel", 1, 1),
-+ FACTOR(CLK_TOP_SYSAXI, "sysaxi", "sysaxi_sel", 1, 1),
-+ FACTOR(CLK_TOP_SYSAPB, "sysapb", "sysapb_sel", 1, 1),
-+ FACTOR(CLK_TOP_ARM_DB_MAIN, "arm_db_main", "arm_db_main_sel", 1, 1),
-+ FACTOR(CLK_TOP_AP2CNN_HOST, "ap2cnn_host", "ap2cnn_host_sel", 1, 1),
-+ FACTOR(CLK_TOP_NETSYS, "netsys", "netsys_sel", 1, 1),
-+ FACTOR(CLK_TOP_NETSYS_500M, "netsys_500m", "netsys_500m_sel", 1, 1),
-+ FACTOR(CLK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu", "netsys_mcu_sel", 1, 1),
-+ FACTOR(CLK_TOP_NETSYS_2X, "netsys_2x", "netsys_2x_sel", 1, 1),
-+ FACTOR(CLK_TOP_SGM_325M, "sgm_325m", "sgm_325m_sel", 1, 1),
-+ FACTOR(CLK_TOP_SGM_REG, "sgm_reg", "sgm_reg_sel", 1, 1),
-+ FACTOR(CLK_TOP_F26M, "csw_f26m", "csw_f26m_sel", 1, 1),
-+ FACTOR(CLK_TOP_EIP97B, "eip97b", "eip97b_sel", 1, 1),
-+ FACTOR(CLK_TOP_USB3_PHY, "usb3_phy", "usb3_phy_sel", 1, 1),
-+ FACTOR(CLK_TOP_AUD, "aud", "faud", 1, 1),
-+ FACTOR(CLK_TOP_A1SYS, "a1sys", "a1sys_sel", 1, 1),
-+ FACTOR(CLK_TOP_AUD_L, "aud_l", "aud_l_sel", 1, 1),
-+ FACTOR(CLK_TOP_A_TUNER, "a_tuner", "a_tuner_sel", 1, 1),
-+ FACTOR(CLK_TOP_U2U3_REF, "u2u3_ref", "u2u3_sel", 1, 1),
-+ FACTOR(CLK_TOP_U2U3_SYS, "u2u3_sys", "u2u3_sys_sel", 1, 1),
-+ FACTOR(CLK_TOP_U2U3_XHCI, "u2u3_xhci", "u2u3_xhci_sel", 1, 1),
-+ FACTOR(CLK_TOP_USB_FRMCNT, "usb_frmcnt", "usb_frmcnt_sel", 1, 1),
-+};
-+
-+static const char * const nfi1x_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_mm_d4",
-+ "net1_d8_d2",
-+ "cb_net2_d6",
-+ "cb_m_d4",
-+ "cb_mm_d8",
-+ "net1_d8_d4",
-+ "cb_m_d8"
-+};
-+
-+static const char * const spinfi_parents[] __initconst = {
-+ "cksq_40m_d2",
-+ "cb_cksq_40m",
-+ "net1_d5_d4",
-+ "cb_m_d4",
-+ "cb_mm_d8",
-+ "net1_d8_d4",
-+ "mm_d6_d2",
-+ "cb_m_d8"
-+};
-+
-+static const char * const spi_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_m_d2",
-+ "cb_mm_d4",
-+ "net1_d8_d2",
-+ "cb_net2_d6",
-+ "net1_d5_d4",
-+ "cb_m_d4",
-+ "net1_d8_d4"
-+};
-+
-+static const char * const uart_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_m_d8",
-+ "m_d8_d2"
-+};
-+
-+static const char * const pwm_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "net1_d8_d2",
-+ "net1_d5_d4",
-+ "cb_m_d4",
-+ "m_d8_d2",
-+ "cb_rtc_32k"
-+};
-+
-+static const char * const i2c_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "net1_d5_d4",
-+ "cb_m_d4",
-+ "net1_d8_d4"
-+};
-+
-+static const char * const pextp_tl_ck_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "net1_d5_d4",
-+ "cb_m_d4",
-+ "cb_rtc_32k"
-+};
-+
-+static const char * const emmc_208m_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_m_d2",
-+ "cb_net2_d4",
-+ "cb_apll2_196m",
-+ "cb_mm_d4",
-+ "net1_d8_d2",
-+ "cb_mm_d6"
-+};
-+
-+static const char * const emmc_400m_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_net2_d2",
-+ "cb_mm_d2",
-+ "cb_net2_d2"
-+};
-+
-+static const char * const csw_f26m_parents[] __initconst = {
-+ "cksq_40m_d2",
-+ "m_d8_d2"
-+};
-+
-+static const char * const dramc_md32_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_m_d2",
-+ "cb_wedmcu_208m"
-+};
-+
-+static const char * const sysaxi_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "net1_d8_d2"
-+};
-+
-+static const char * const sysapb_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "m_d3_d2"
-+};
-+
-+static const char * const arm_db_main_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_net2_d6"
-+};
-+
-+static const char * const ap2cnn_host_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "net1_d8_d4"
-+};
-+
-+static const char * const netsys_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_mm_d2"
-+};
-+
-+static const char * const netsys_500m_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_net1_d5"
-+};
-+
-+static const char * const netsys_mcu_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_mm_720m",
-+ "cb_net1_d4",
-+ "cb_net1_d5",
-+ "cb_m_416m"
-+};
-+
-+static const char * const netsys_2x_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_net2_800m",
-+ "cb_mm_720m"
-+};
-+
-+static const char * const sgm_325m_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_sgm_325m"
-+};
-+
-+static const char * const sgm_reg_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_net2_d4"
-+};
-+
-+static const char * const eip97b_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_net1_d5",
-+ "cb_m_416m",
-+ "cb_mm_d2",
-+ "net1_d5_d2"
-+};
-+
-+static const char * const aud_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_apll2_196m"
-+};
-+
-+static const char * const a1sys_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "apll2_d4"
-+};
-+
-+static const char * const aud_l_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_apll2_196m",
-+ "m_d8_d2"
-+};
-+
-+static const char * const a_tuner_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "apll2_d4",
-+ "m_d8_d2"
-+};
-+
-+static const char * const u2u3_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "m_d8_d2"
-+};
-+
-+static const char * const u2u3_sys_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "net1_d5_d4"
-+};
-+
-+static const char * const usb_frmcnt_parents[] __initconst = {
-+ "cb_cksq_40m",
-+ "cb_mm_d3_d5"
-+};
-+
-+static const struct mtk_mux top_muxes[] = {
-+ /* CLK_CFG_0 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents,
-+ 0x000, 0x004, 0x008, 0, 3, 7, 0x1C0, 0),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents,
-+ 0x000, 0x004, 0x008, 8, 3, 15, 0x1C0, 1),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents,
-+ 0x000, 0x004, 0x008, 16, 3, 23, 0x1C0, 2),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
-+ 0x000, 0x004, 0x008, 24, 3, 31, 0x1C0, 3),
-+ /* CLK_CFG_1 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
-+ 0x010, 0x014, 0x018, 0, 2, 7, 0x1C0, 4),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
-+ 0x010, 0x014, 0x018, 8, 3, 15, 0x1C0, 5),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents,
-+ 0x010, 0x014, 0x018, 16, 2, 23, 0x1C0, 6),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel",
-+ pextp_tl_ck_parents, 0x010, 0x014, 0x018, 24, 2, 31,
-+ 0x1C0, 7),
-+ /* CLK_CFG_2 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_208M_SEL, "emmc_208m_sel",
-+ emmc_208m_parents, 0x020, 0x024, 0x028, 0, 3, 7,
-+ 0x1C0, 8),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_400M_SEL, "emmc_400m_sel",
-+ emmc_400m_parents, 0x020, 0x024, 0x028, 8, 2, 15,
-+ 0x1C0, 9),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_F26M_SEL, "csw_f26m_sel",
-+ csw_f26m_parents, 0x020, 0x024, 0x028, 16, 1, 23,
-+ 0x1C0, 10,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_SEL, "dramc_sel",
-+ csw_f26m_parents, 0x020, 0x024, 0x028, 24, 1,
-+ 31, 0x1C0, 11,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
-+ /* CLK_CFG_3 */
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
-+ dramc_md32_parents, 0x030, 0x034, 0x038, 0, 2,
-+ 7, 0x1C0, 12,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAXI_SEL, "sysaxi_sel",
-+ sysaxi_parents, 0x030, 0x034, 0x038, 8, 1, 15,
-+ 0x1C0, 13,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAPB_SEL, "sysapb_sel",
-+ sysapb_parents, 0x030, 0x034, 0x038, 16, 1,
-+ 23, 0x1C0, 14,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
-+ arm_db_main_parents, 0x030, 0x034, 0x038, 24, 1, 31,
-+ 0x1C0, 15),
-+ /* CLK_CFG_4 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel",
-+ ap2cnn_host_parents, 0x040, 0x044, 0x048, 0, 1, 7,
-+ 0x1C0, 16),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
-+ 0x040, 0x044, 0x048, 8, 1, 15, 0x1C0, 17),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
-+ netsys_500m_parents, 0x040, 0x044, 0x048, 16, 1, 23,
-+ 0x1C0, 18),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel",
-+ netsys_mcu_parents, 0x040, 0x044, 0x048, 24, 3, 31,
-+ 0x1C0, 19),
-+ /* CLK_CFG_5 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
-+ netsys_2x_parents, 0x050, 0x054, 0x058, 0, 2, 7,
-+ 0x1C0, 20),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
-+ sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
-+ 0x1C0, 21),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
-+ 0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents,
-+ 0x050, 0x054, 0x058, 24, 3, 31, 0x1C0, 23),
-+ /* CLK_CFG_6 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB3_PHY_SEL, "usb3_phy_sel",
-+ csw_f26m_parents, 0x060, 0x064, 0x068, 0, 1,
-+ 7, 0x1C0, 24),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x060,
-+ 0x064, 0x068, 8, 1, 15, 0x1C0, 25),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
-+ 0x060, 0x064, 0x068, 16, 1, 23, 0x1C0, 26),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
-+ 0x060, 0x064, 0x068, 24, 2, 31, 0x1C0, 27),
-+ /* CLK_CFG_7 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel",
-+ a_tuner_parents, 0x070, 0x074, 0x078, 0, 2, 7,
-+ 0x1C0, 28),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x070,
-+ 0x074, 0x078, 8, 1, 15, 0x1C0, 29),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel",
-+ u2u3_sys_parents, 0x070, 0x074, 0x078, 16, 1, 23,
-+ 0x1C0, 30),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel",
-+ u2u3_sys_parents, 0x070, 0x074, 0x078, 24, 1, 31,
-+ 0x1C4, 0),
-+ /* CLK_CFG_8 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel",
-+ usb_frmcnt_parents, 0x080, 0x084, 0x088, 0, 1, 7,
-+ 0x1C4, 1),
-+};
-+
-+static struct mtk_composite top_aud_divs[] = {
-+ DIV_GATE(CLK_TOP_AUD_I2S_M, "aud_i2s_m", "aud",
-+ 0x0420, 0, 0x0420, 8, 8),
-+};
-+
-+static const struct mtk_clk_desc topck_desc = {
-+ .factor_clks = top_divs,
-+ .num_factor_clks = ARRAY_SIZE(top_divs),
-+ .mux_clks = top_muxes,
-+ .num_mux_clks = ARRAY_SIZE(top_muxes),
-+ .composite_clks = top_aud_divs,
-+ .num_composite_clks = ARRAY_SIZE(top_aud_divs),
-+ .clk_lock = &mt7981_clk_lock,
-+};
-+
-+static const struct of_device_id of_match_clk_mt7981_topckgen[] = {
-+ { .compatible = "mediatek,mt7981-topckgen", .data = &topck_desc },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver clk_mt7981_topckgen_drv = {
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
-+ .driver = {
-+ .name = "clk-mt7981-topckgen",
-+ .of_match_table = of_match_clk_mt7981_topckgen,
-+ },
-+};
-+builtin_platform_driver(clk_mt7981_topckgen_drv);
+++ /dev/null
-From fc157139e6b7f8dfb6430ac7191ba754027705e8 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 18 Feb 2024 01:59:59 +0000
-Subject: [PATCH] clk: mediatek: mt7981-topckgen: flag SGM_REG_SEL as critical
-
-Without the SGM_REG_SEL clock enabled the system freezes if trying to
-access registers used by MT7981 clock drivers itself.
-Mark SGM_REG_SEL as critical to make sure it is always enabled to
-prevent freezes on boot depending on probe order.
-
-Fixes: 813c3b53b55ba ("clk: mediatek: add MT7981 clock support")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/clk/mediatek/clk-mt7981-topckgen.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mt7981-topckgen.c
-+++ b/drivers/clk/mediatek/clk-mt7981-topckgen.c
-@@ -359,8 +359,9 @@ static const struct mtk_mux top_muxes[]
- MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
- sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
- 0x1C0, 21),
-- MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
-- 0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
-+ 0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22,
-+ CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
- MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents,
- 0x050, 0x054, 0x058, 24, 3, 31, 0x1C0, 23),
- /* CLK_CFG_6 */
+++ /dev/null
---- a/drivers/pinctrl/mediatek/Kconfig
-+++ b/drivers/pinctrl/mediatek/Kconfig
-@@ -141,6 +141,13 @@ config PINCTRL_MT7986
- default ARM64 && ARCH_MEDIATEK
- select PINCTRL_MTK_MOORE
-
-+config PINCTRL_MT7988
-+ bool "Mediatek MT7988 pin control"
-+ depends on OF
-+ depends on ARM64 || COMPILE_TEST
-+ default ARCH_MEDIATEK
-+ select PINCTRL_MTK_MOORE
-+
- config PINCTRL_MT8167
- bool "Mediatek MT8167 pin control"
- depends on OF
---- a/drivers/pinctrl/mediatek/Makefile
-+++ b/drivers/pinctrl/mediatek/Makefile
-@@ -20,6 +20,7 @@ obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-
- obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
- obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o
- obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o
-+obj-$(CONFIG_PINCTRL_MT7988) += pinctrl-mt7988.o
- obj-$(CONFIG_PINCTRL_MT8167) += pinctrl-mt8167.o
- obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
- obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o
+++ /dev/null
-From cc4d9e0c77494fcf6bccbc57e23db0007cf681b7 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 26 Jan 2023 03:33:46 +0000
-Subject: [PATCH] dt-bindings: clock: Add compatibles for MT7981
-
-Add compatible string for MT7981 to existing bindings at
- - mediatek,apmixedsys.yaml
- - mediatek,topckgen.yaml
- - mediatek,ethsys.txt
- - mediatek,infracfg.yaml
- - mediatek,sgmiisys.txt
-
-Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Link: https://lore.kernel.org/r/cc85ee470c781ff4013f6c21c92c0a21574b12b2.1674703830.git.daniel@makrotopia.org
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- .../devicetree/bindings/arm/mediatek/mediatek,ethsys.txt | 1 +
- .../devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml | 1 +
- .../devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt | 2 ++
- .../devicetree/bindings/clock/mediatek,apmixedsys.yaml | 1 +
- Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml | 1 +
- 5 files changed, 6 insertions(+)
-
---- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
-+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
-@@ -10,6 +10,7 @@ Required Properties:
- - "mediatek,mt7622-ethsys", "syscon"
- - "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon"
- - "mediatek,mt7629-ethsys", "syscon"
-+ - "mediatek,mt7981-ethsys", "syscon"
- - "mediatek,mt7986-ethsys", "syscon"
- - #clock-cells: Must be 1
- - #reset-cells: Must be 1
---- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml
-+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml
-@@ -28,6 +28,7 @@ properties:
- - mediatek,mt6797-infracfg
- - mediatek,mt7622-infracfg
- - mediatek,mt7629-infracfg
-+ - mediatek,mt7981-infracfg
- - mediatek,mt7986-infracfg
- - mediatek,mt8135-infracfg
- - mediatek,mt8167-infracfg
---- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
-+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
-@@ -8,6 +8,8 @@ Required Properties:
- - compatible: Should be:
- - "mediatek,mt7622-sgmiisys", "syscon"
- - "mediatek,mt7629-sgmiisys", "syscon"
-+ - "mediatek,mt7981-sgmiisys_0", "syscon"
-+ - "mediatek,mt7981-sgmiisys_1", "syscon"
- - "mediatek,mt7986-sgmiisys_0", "syscon"
- - "mediatek,mt7986-sgmiisys_1", "syscon"
- - #clock-cells: Must be 1
---- a/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml
-+++ b/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml
-@@ -20,6 +20,7 @@ properties:
- - enum:
- - mediatek,mt6797-apmixedsys
- - mediatek,mt7622-apmixedsys
-+ - mediatek,mt7981-apmixedsys
- - mediatek,mt7986-apmixedsys
- - mediatek,mt8135-apmixedsys
- - mediatek,mt8173-apmixedsys
---- a/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml
-+++ b/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml
-@@ -35,6 +35,7 @@ properties:
- - mediatek,mt6779-topckgen
- - mediatek,mt6795-topckgen
- - mediatek,mt7629-topckgen
-+ - mediatek,mt7981-topckgen
- - mediatek,mt7986-topckgen
- - mediatek,mt8167-topckgen
- - mediatek,mt8183-topckgen
+++ /dev/null
-From d4f08a703565abf47baa5a77d05365cf4598d55c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:56:52 +0000
-Subject: [PATCH 1/2] dt-bindings: arm: mediatek: sgmiisys: Convert to DT
- schema
-
-Convert mediatek,sgmiiisys bindings to DT schema format.
-Add maintainer Matthias Brugger, no maintainers were listed in the
-original documentation.
-As this node is also referenced by the Ethernet controller and used
-as SGMII PCS add this fact to the description.
-Move the file to Documentation/devicetree/bindings/net/pcs/ which seems
-more appropriate given that the great majority of registers are related
-to SGMII PCS functionality and only one register represents clock bits.
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../arm/mediatek/mediatek,sgmiisys.txt | 27 ----------
- .../bindings/net/pcs/mediatek,sgmiisys.yaml | 49 +++++++++++++++++++
- 2 files changed, 49 insertions(+), 27 deletions(-)
- delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
- create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
-
---- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
-+++ /dev/null
-@@ -1,27 +0,0 @@
--MediaTek SGMIISYS controller
--============================
--
--The MediaTek SGMIISYS controller provides various clocks to the system.
--
--Required Properties:
--
--- compatible: Should be:
-- - "mediatek,mt7622-sgmiisys", "syscon"
-- - "mediatek,mt7629-sgmiisys", "syscon"
-- - "mediatek,mt7981-sgmiisys_0", "syscon"
-- - "mediatek,mt7981-sgmiisys_1", "syscon"
-- - "mediatek,mt7986-sgmiisys_0", "syscon"
-- - "mediatek,mt7986-sgmiisys_1", "syscon"
--- #clock-cells: Must be 1
--
--The SGMIISYS controller uses the common clk binding from
--Documentation/devicetree/bindings/clock/clock-bindings.txt
--The available clocks are defined in dt-bindings/clock/mt*-clk.h.
--
--Example:
--
--sgmiisys: sgmiisys@1b128000 {
-- compatible = "mediatek,mt7622-sgmiisys", "syscon";
-- reg = <0 0x1b128000 0 0x1000>;
-- #clock-cells = <1>;
--};
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
-@@ -0,0 +1,49 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/pcs/mediatek,sgmiisys.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MediaTek SGMIISYS Controller
-+
-+maintainers:
-+ - Matthias Brugger <matthias.bgg@gmail.com>
-+
-+description:
-+ The MediaTek SGMIISYS controller provides a SGMII PCS and some clocks
-+ to the ethernet subsystem to which it is attached.
-+
-+properties:
-+ compatible:
-+ items:
-+ - enum:
-+ - mediatek,mt7622-sgmiisys
-+ - mediatek,mt7629-sgmiisys
-+ - mediatek,mt7986-sgmiisys_0
-+ - mediatek,mt7986-sgmiisys_1
-+ - const: syscon
-+
-+ reg:
-+ maxItems: 1
-+
-+ '#clock-cells':
-+ const: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - '#clock-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ soc {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ sgmiisys: syscon@1b128000 {
-+ compatible = "mediatek,mt7622-sgmiisys", "syscon";
-+ reg = <0 0x1b128000 0 0x1000>;
-+ #clock-cells = <1>;
-+ };
-+ };
+++ /dev/null
-From 4f7eb19c4f44078100659f6ba073b0cc7191bc91 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 19 Mar 2023 12:57:04 +0000
-Subject: [PATCH 2/2] dt-bindings: net: pcs: mediatek,sgmiisys: add MT7981 SoC
-
-Add mediatek,pnswap boolean property needed on many boards using the
-MediaTek MT7981 SoC.
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- .../devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
-+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
-@@ -19,6 +19,8 @@ properties:
- - enum:
- - mediatek,mt7622-sgmiisys
- - mediatek,mt7629-sgmiisys
-+ - mediatek,mt7981-sgmiisys_0
-+ - mediatek,mt7981-sgmiisys_1
- - mediatek,mt7986-sgmiisys_0
- - mediatek,mt7986-sgmiisys_1
- - const: syscon
-@@ -29,6 +31,10 @@ properties:
- '#clock-cells':
- const: 1
-
-+ mediatek,pnswap:
-+ description: Invert polarity of the SGMII data lanes
-+ type: boolean
-+
- required:
- - compatible
- - reg
+++ /dev/null
-From 94b0f301f6ee92f79a2fe2c655dfdbdfe2aec536 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 19 Nov 2023 22:24:16 +0100
-Subject: [PATCH] dt-bindings: arm: mediatek: move ethsys controller & convert
- to DT schema
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-DT schema helps validating DTS files. Binding was moved to clock/ as
-this hardware is a clock provider. Example required a small fix for
-"reg" value (1 address cell + 1 size cell).
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20231119212416.2682-1-zajec5@gmail.com
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- .../bindings/arm/mediatek/mediatek,ethsys.txt | 29 ----------
- .../bindings/clock/mediatek,ethsys.yaml | 54 +++++++++++++++++++
- 2 files changed, 54 insertions(+), 29 deletions(-)
- delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
- create mode 100644 Documentation/devicetree/bindings/clock/mediatek,ethsys.yaml
-
---- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
-+++ /dev/null
-@@ -1,29 +0,0 @@
--Mediatek ethsys controller
--============================
--
--The Mediatek ethsys controller provides various clocks to the system.
--
--Required Properties:
--
--- compatible: Should be:
-- - "mediatek,mt2701-ethsys", "syscon"
-- - "mediatek,mt7622-ethsys", "syscon"
-- - "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon"
-- - "mediatek,mt7629-ethsys", "syscon"
-- - "mediatek,mt7981-ethsys", "syscon"
-- - "mediatek,mt7986-ethsys", "syscon"
--- #clock-cells: Must be 1
--- #reset-cells: Must be 1
--
--The ethsys controller uses the common clk binding from
--Documentation/devicetree/bindings/clock/clock-bindings.txt
--The available clocks are defined in dt-bindings/clock/mt*-clk.h.
--
--Example:
--
--ethsys: clock-controller@1b000000 {
-- compatible = "mediatek,mt2701-ethsys", "syscon";
-- reg = <0 0x1b000000 0 0x1000>;
-- #clock-cells = <1>;
-- #reset-cells = <1>;
--};
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/mediatek,ethsys.yaml
-@@ -0,0 +1,54 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/mediatek,ethsys.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Mediatek ethsys controller
-+
-+description:
-+ The available clocks are defined in dt-bindings/clock/mt*-clk.h.
-+
-+maintainers:
-+ - James Liao <jamesjj.liao@mediatek.com>
-+
-+properties:
-+ compatible:
-+ oneOf:
-+ - items:
-+ - enum:
-+ - mediatek,mt2701-ethsys
-+ - mediatek,mt7622-ethsys
-+ - mediatek,mt7629-ethsys
-+ - mediatek,mt7981-ethsys
-+ - mediatek,mt7986-ethsys
-+ - const: syscon
-+ - items:
-+ - const: mediatek,mt7623-ethsys
-+ - const: mediatek,mt2701-ethsys
-+ - const: syscon
-+
-+ reg:
-+ maxItems: 1
-+
-+ "#clock-cells":
-+ const: 1
-+
-+ "#reset-cells":
-+ const: 1
-+
-+required:
-+ - reg
-+ - "#clock-cells"
-+ - "#reset-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ clock-controller@1b000000 {
-+ compatible = "mediatek,mt2701-ethsys", "syscon";
-+ reg = <0x1b000000 0x1000>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
+++ /dev/null
-From 5cfa3beb7761cb84be77225902e018d9d3f9b973 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 17 Dec 2023 21:49:45 +0000
-Subject: [PATCH 1/4] dt-bindings: reset: mediatek: add MT7988 ethwarp reset
- IDs
-
-Add reset ID for ethwarp subsystem allowing to reset the built-in
-Ethernet switch of the MediaTek MT7988 SoC.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/0c14bbacf471683af67ffa7572bfa1d5c45a0b5d.1702849494.git.daniel@makrotopia.org
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- include/dt-bindings/reset/mediatek,mt7988-resets.h | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
- create mode 100644 include/dt-bindings/reset/mediatek,mt7988-resets.h
-
---- /dev/null
-+++ b/include/dt-bindings/reset/mediatek,mt7988-resets.h
-@@ -0,0 +1,13 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
-+ * Author: Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7988
-+#define _DT_BINDINGS_RESET_CONTROLLER_MT7988
-+
-+/* ETHWARP resets */
-+#define MT7988_ETHWARP_RST_SWITCH 0
-+
-+#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT7988 */
+++ /dev/null
-From 8187e001de156e99ef95366ffd10d627ed090826 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Sun, 17 Dec 2023 21:49:33 +0000
-Subject: [PATCH] dt-bindings: clock: mediatek: add MT7988 clock IDs
-
-Add MT7988 clock dt-bindings for topckgen, apmixedsys, infracfg,
-ethernet and xfipll subsystem clocks.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/27f99db432e9ccc804cc5b6501d7d17d72cae879.1702849494.git.daniel@makrotopia.org
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- .../dt-bindings/clock/mediatek,mt7988-clk.h | 280 ++++++++++++++++++
- 1 file changed, 280 insertions(+)
- create mode 100644 include/dt-bindings/clock/mediatek,mt7988-clk.h
-
---- /dev/null
-+++ b/include/dt-bindings/clock/mediatek,mt7988-clk.h
-@@ -0,0 +1,280 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ * Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
-+ */
-+
-+#ifndef _DT_BINDINGS_CLK_MT7988_H
-+#define _DT_BINDINGS_CLK_MT7988_H
-+
-+/* APMIXEDSYS */
-+
-+#define CLK_APMIXED_NETSYSPLL 0
-+#define CLK_APMIXED_MPLL 1
-+#define CLK_APMIXED_MMPLL 2
-+#define CLK_APMIXED_APLL2 3
-+#define CLK_APMIXED_NET1PLL 4
-+#define CLK_APMIXED_NET2PLL 5
-+#define CLK_APMIXED_WEDMCUPLL 6
-+#define CLK_APMIXED_SGMPLL 7
-+#define CLK_APMIXED_ARM_B 8
-+#define CLK_APMIXED_CCIPLL2_B 9
-+#define CLK_APMIXED_USXGMIIPLL 10
-+#define CLK_APMIXED_MSDCPLL 11
-+
-+/* TOPCKGEN */
-+
-+#define CLK_TOP_XTAL 0
-+#define CLK_TOP_XTAL_D2 1
-+#define CLK_TOP_RTC_32K 2
-+#define CLK_TOP_RTC_32P7K 3
-+#define CLK_TOP_MPLL_D2 4
-+#define CLK_TOP_MPLL_D3_D2 5
-+#define CLK_TOP_MPLL_D4 6
-+#define CLK_TOP_MPLL_D8 7
-+#define CLK_TOP_MPLL_D8_D2 8
-+#define CLK_TOP_MMPLL_D2 9
-+#define CLK_TOP_MMPLL_D3_D5 10
-+#define CLK_TOP_MMPLL_D4 11
-+#define CLK_TOP_MMPLL_D6_D2 12
-+#define CLK_TOP_MMPLL_D8 13
-+#define CLK_TOP_APLL2_D4 14
-+#define CLK_TOP_NET1PLL_D4 15
-+#define CLK_TOP_NET1PLL_D5 16
-+#define CLK_TOP_NET1PLL_D5_D2 17
-+#define CLK_TOP_NET1PLL_D5_D4 18
-+#define CLK_TOP_NET1PLL_D8 19
-+#define CLK_TOP_NET1PLL_D8_D2 20
-+#define CLK_TOP_NET1PLL_D8_D4 21
-+#define CLK_TOP_NET1PLL_D8_D8 22
-+#define CLK_TOP_NET1PLL_D8_D16 23
-+#define CLK_TOP_NET2PLL_D2 24
-+#define CLK_TOP_NET2PLL_D4 25
-+#define CLK_TOP_NET2PLL_D4_D4 26
-+#define CLK_TOP_NET2PLL_D4_D8 27
-+#define CLK_TOP_NET2PLL_D6 28
-+#define CLK_TOP_NET2PLL_D8 29
-+#define CLK_TOP_NETSYS_SEL 30
-+#define CLK_TOP_NETSYS_500M_SEL 31
-+#define CLK_TOP_NETSYS_2X_SEL 32
-+#define CLK_TOP_NETSYS_GSW_SEL 33
-+#define CLK_TOP_ETH_GMII_SEL 34
-+#define CLK_TOP_NETSYS_MCU_SEL 35
-+#define CLK_TOP_NETSYS_PAO_2X_SEL 36
-+#define CLK_TOP_EIP197_SEL 37
-+#define CLK_TOP_AXI_INFRA_SEL 38
-+#define CLK_TOP_UART_SEL 39
-+#define CLK_TOP_EMMC_250M_SEL 40
-+#define CLK_TOP_EMMC_400M_SEL 41
-+#define CLK_TOP_SPI_SEL 42
-+#define CLK_TOP_SPIM_MST_SEL 43
-+#define CLK_TOP_NFI1X_SEL 44
-+#define CLK_TOP_SPINFI_SEL 45
-+#define CLK_TOP_PWM_SEL 46
-+#define CLK_TOP_I2C_SEL 47
-+#define CLK_TOP_PCIE_MBIST_250M_SEL 48
-+#define CLK_TOP_PEXTP_TL_SEL 49
-+#define CLK_TOP_PEXTP_TL_P1_SEL 50
-+#define CLK_TOP_PEXTP_TL_P2_SEL 51
-+#define CLK_TOP_PEXTP_TL_P3_SEL 52
-+#define CLK_TOP_USB_SYS_SEL 53
-+#define CLK_TOP_USB_SYS_P1_SEL 54
-+#define CLK_TOP_USB_XHCI_SEL 55
-+#define CLK_TOP_USB_XHCI_P1_SEL 56
-+#define CLK_TOP_USB_FRMCNT_SEL 57
-+#define CLK_TOP_USB_FRMCNT_P1_SEL 58
-+#define CLK_TOP_AUD_SEL 59
-+#define CLK_TOP_A1SYS_SEL 60
-+#define CLK_TOP_AUD_L_SEL 61
-+#define CLK_TOP_A_TUNER_SEL 62
-+#define CLK_TOP_SSPXTP_SEL 63
-+#define CLK_TOP_USB_PHY_SEL 64
-+#define CLK_TOP_USXGMII_SBUS_0_SEL 65
-+#define CLK_TOP_USXGMII_SBUS_1_SEL 66
-+#define CLK_TOP_SGM_0_SEL 67
-+#define CLK_TOP_SGM_SBUS_0_SEL 68
-+#define CLK_TOP_SGM_1_SEL 69
-+#define CLK_TOP_SGM_SBUS_1_SEL 70
-+#define CLK_TOP_XFI_PHY_0_XTAL_SEL 71
-+#define CLK_TOP_XFI_PHY_1_XTAL_SEL 72
-+#define CLK_TOP_SYSAXI_SEL 73
-+#define CLK_TOP_SYSAPB_SEL 74
-+#define CLK_TOP_ETH_REFCK_50M_SEL 75
-+#define CLK_TOP_ETH_SYS_200M_SEL 76
-+#define CLK_TOP_ETH_SYS_SEL 77
-+#define CLK_TOP_ETH_XGMII_SEL 78
-+#define CLK_TOP_BUS_TOPS_SEL 79
-+#define CLK_TOP_NPU_TOPS_SEL 80
-+#define CLK_TOP_DRAMC_SEL 81
-+#define CLK_TOP_DRAMC_MD32_SEL 82
-+#define CLK_TOP_INFRA_F26M_SEL 83
-+#define CLK_TOP_PEXTP_P0_SEL 84
-+#define CLK_TOP_PEXTP_P1_SEL 85
-+#define CLK_TOP_PEXTP_P2_SEL 86
-+#define CLK_TOP_PEXTP_P3_SEL 87
-+#define CLK_TOP_DA_XTP_GLB_P0_SEL 88
-+#define CLK_TOP_DA_XTP_GLB_P1_SEL 89
-+#define CLK_TOP_DA_XTP_GLB_P2_SEL 90
-+#define CLK_TOP_DA_XTP_GLB_P3_SEL 91
-+#define CLK_TOP_CKM_SEL 92
-+#define CLK_TOP_DA_SEL 93
-+#define CLK_TOP_PEXTP_SEL 94
-+#define CLK_TOP_TOPS_P2_26M_SEL 95
-+#define CLK_TOP_MCUSYS_BACKUP_625M_SEL 96
-+#define CLK_TOP_NETSYS_SYNC_250M_SEL 97
-+#define CLK_TOP_MACSEC_SEL 98
-+#define CLK_TOP_NETSYS_TOPS_400M_SEL 99
-+#define CLK_TOP_NETSYS_PPEFB_250M_SEL 100
-+#define CLK_TOP_NETSYS_WARP_SEL 101
-+#define CLK_TOP_ETH_MII_SEL 102
-+#define CLK_TOP_NPU_SEL 103
-+#define CLK_TOP_AUD_I2S_M 104
-+
-+/* MCUSYS */
-+
-+#define CLK_MCU_BUS_DIV_SEL 0
-+#define CLK_MCU_ARM_DIV_SEL 1
-+
-+/* INFRACFG_AO */
-+
-+#define CLK_INFRA_MUX_UART0_SEL 0
-+#define CLK_INFRA_MUX_UART1_SEL 1
-+#define CLK_INFRA_MUX_UART2_SEL 2
-+#define CLK_INFRA_MUX_SPI0_SEL 3
-+#define CLK_INFRA_MUX_SPI1_SEL 4
-+#define CLK_INFRA_MUX_SPI2_SEL 5
-+#define CLK_INFRA_PWM_SEL 6
-+#define CLK_INFRA_PWM_CK1_SEL 7
-+#define CLK_INFRA_PWM_CK2_SEL 8
-+#define CLK_INFRA_PWM_CK3_SEL 9
-+#define CLK_INFRA_PWM_CK4_SEL 10
-+#define CLK_INFRA_PWM_CK5_SEL 11
-+#define CLK_INFRA_PWM_CK6_SEL 12
-+#define CLK_INFRA_PWM_CK7_SEL 13
-+#define CLK_INFRA_PWM_CK8_SEL 14
-+#define CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL 15
-+#define CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL 16
-+#define CLK_INFRA_PCIE_GFMUX_TL_O_P2_SEL 17
-+#define CLK_INFRA_PCIE_GFMUX_TL_O_P3_SEL 18
-+
-+/* INFRACFG */
-+
-+#define CLK_INFRA_PCIE_PERI_26M_CK_P0 19
-+#define CLK_INFRA_PCIE_PERI_26M_CK_P1 20
-+#define CLK_INFRA_PCIE_PERI_26M_CK_P2 21
-+#define CLK_INFRA_PCIE_PERI_26M_CK_P3 22
-+#define CLK_INFRA_66M_GPT_BCK 23
-+#define CLK_INFRA_66M_PWM_HCK 24
-+#define CLK_INFRA_66M_PWM_BCK 25
-+#define CLK_INFRA_66M_PWM_CK1 26
-+#define CLK_INFRA_66M_PWM_CK2 27
-+#define CLK_INFRA_66M_PWM_CK3 28
-+#define CLK_INFRA_66M_PWM_CK4 29
-+#define CLK_INFRA_66M_PWM_CK5 30
-+#define CLK_INFRA_66M_PWM_CK6 31
-+#define CLK_INFRA_66M_PWM_CK7 32
-+#define CLK_INFRA_66M_PWM_CK8 33
-+#define CLK_INFRA_133M_CQDMA_BCK 34
-+#define CLK_INFRA_66M_AUD_SLV_BCK 35
-+#define CLK_INFRA_AUD_26M 36
-+#define CLK_INFRA_AUD_L 37
-+#define CLK_INFRA_AUD_AUD 38
-+#define CLK_INFRA_AUD_EG2 39
-+#define CLK_INFRA_DRAMC_F26M 40
-+#define CLK_INFRA_133M_DBG_ACKM 41
-+#define CLK_INFRA_66M_AP_DMA_BCK 42
-+#define CLK_INFRA_66M_SEJ_BCK 43
-+#define CLK_INFRA_PRE_CK_SEJ_F13M 44
-+#define CLK_INFRA_26M_THERM_SYSTEM 45
-+#define CLK_INFRA_I2C_BCK 46
-+#define CLK_INFRA_52M_UART0_CK 47
-+#define CLK_INFRA_52M_UART1_CK 48
-+#define CLK_INFRA_52M_UART2_CK 49
-+#define CLK_INFRA_NFI 50
-+#define CLK_INFRA_SPINFI 51
-+#define CLK_INFRA_66M_NFI_HCK 52
-+#define CLK_INFRA_104M_SPI0 53
-+#define CLK_INFRA_104M_SPI1 54
-+#define CLK_INFRA_104M_SPI2_BCK 55
-+#define CLK_INFRA_66M_SPI0_HCK 56
-+#define CLK_INFRA_66M_SPI1_HCK 57
-+#define CLK_INFRA_66M_SPI2_HCK 58
-+#define CLK_INFRA_66M_FLASHIF_AXI 59
-+#define CLK_INFRA_RTC 60
-+#define CLK_INFRA_26M_ADC_BCK 61
-+#define CLK_INFRA_RC_ADC 62
-+#define CLK_INFRA_MSDC400 63
-+#define CLK_INFRA_MSDC2_HCK 64
-+#define CLK_INFRA_133M_MSDC_0_HCK 65
-+#define CLK_INFRA_66M_MSDC_0_HCK 66
-+#define CLK_INFRA_133M_CPUM_BCK 67
-+#define CLK_INFRA_BIST2FPC 68
-+#define CLK_INFRA_I2C_X16W_MCK_CK_P1 69
-+#define CLK_INFRA_I2C_X16W_PCK_CK_P1 70
-+#define CLK_INFRA_133M_USB_HCK 71
-+#define CLK_INFRA_133M_USB_HCK_CK_P1 72
-+#define CLK_INFRA_66M_USB_HCK 73
-+#define CLK_INFRA_66M_USB_HCK_CK_P1 74
-+#define CLK_INFRA_USB_SYS 75
-+#define CLK_INFRA_USB_SYS_CK_P1 76
-+#define CLK_INFRA_USB_REF 77
-+#define CLK_INFRA_USB_CK_P1 78
-+#define CLK_INFRA_USB_FRMCNT 79
-+#define CLK_INFRA_USB_FRMCNT_CK_P1 80
-+#define CLK_INFRA_USB_PIPE 81
-+#define CLK_INFRA_USB_PIPE_CK_P1 82
-+#define CLK_INFRA_USB_UTMI 83
-+#define CLK_INFRA_USB_UTMI_CK_P1 84
-+#define CLK_INFRA_USB_XHCI 85
-+#define CLK_INFRA_USB_XHCI_CK_P1 86
-+#define CLK_INFRA_PCIE_GFMUX_TL_P0 87
-+#define CLK_INFRA_PCIE_GFMUX_TL_P1 88
-+#define CLK_INFRA_PCIE_GFMUX_TL_P2 89
-+#define CLK_INFRA_PCIE_GFMUX_TL_P3 90
-+#define CLK_INFRA_PCIE_PIPE_P0 91
-+#define CLK_INFRA_PCIE_PIPE_P1 92
-+#define CLK_INFRA_PCIE_PIPE_P2 93
-+#define CLK_INFRA_PCIE_PIPE_P3 94
-+#define CLK_INFRA_133M_PCIE_CK_P0 95
-+#define CLK_INFRA_133M_PCIE_CK_P1 96
-+#define CLK_INFRA_133M_PCIE_CK_P2 97
-+#define CLK_INFRA_133M_PCIE_CK_P3 98
-+
-+/* ETHDMA */
-+
-+#define CLK_ETHDMA_XGP1_EN 0
-+#define CLK_ETHDMA_XGP2_EN 1
-+#define CLK_ETHDMA_XGP3_EN 2
-+#define CLK_ETHDMA_FE_EN 3
-+#define CLK_ETHDMA_GP2_EN 4
-+#define CLK_ETHDMA_GP1_EN 5
-+#define CLK_ETHDMA_GP3_EN 6
-+#define CLK_ETHDMA_ESW_EN 7
-+#define CLK_ETHDMA_CRYPT0_EN 8
-+#define CLK_ETHDMA_NR_CLK 9
-+
-+/* SGMIISYS_0 */
-+
-+#define CLK_SGM0_TX_EN 0
-+#define CLK_SGM0_RX_EN 1
-+#define CLK_SGMII0_NR_CLK 2
-+
-+/* SGMIISYS_1 */
-+
-+#define CLK_SGM1_TX_EN 0
-+#define CLK_SGM1_RX_EN 1
-+#define CLK_SGMII1_NR_CLK 2
-+
-+/* ETHWARP */
-+
-+#define CLK_ETHWARP_WOCPU2_EN 0
-+#define CLK_ETHWARP_WOCPU1_EN 1
-+#define CLK_ETHWARP_WOCPU0_EN 2
-+#define CLK_ETHWARP_NR_CLK 3
-+
-+/* XFIPLL */
-+#define CLK_XFIPLL_PLL 0
-+#define CLK_XFIPLL_PLL_EN 1
-+
-+#endif /* _DT_BINDINGS_CLK_MT7988_H */
+++ /dev/null
-From afd36e9d91b0a840983b829a9e95407d8151f7e7 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 17 Dec 2023 21:49:55 +0000
-Subject: [PATCH 2/4] dt-bindings: clock: mediatek: add clock controllers of
- MT7988
-
-Add various clock controllers found in the MT7988 SoC to existing
-bindings (if applicable) and add files for the new ethwarp, mcusys
-and xfi-pll clock controllers not previously present in any SoC.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/07e76a544ce4392bcb88e34d5480e99bb7994618.1702849494.git.daniel@makrotopia.org
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- .../arm/mediatek/mediatek,infracfg.yaml | 1 +
- .../bindings/clock/mediatek,apmixedsys.yaml | 1 +
- .../bindings/clock/mediatek,ethsys.yaml | 1 +
- .../clock/mediatek,mt7988-ethwarp.yaml | 52 +++++++++++++++
- .../clock/mediatek,mt7988-xfi-pll.yaml | 48 ++++++++++++++
- .../bindings/clock/mediatek,topckgen.yaml | 2 +
- .../bindings/net/pcs/mediatek,sgmiisys.yaml | 65 ++++++++++++++++---
- 7 files changed, 161 insertions(+), 9 deletions(-)
- create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7988-ethwarp.yaml
- create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7988-xfi-pll.yaml
-
---- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml
-+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml
-@@ -30,6 +30,7 @@ properties:
- - mediatek,mt7629-infracfg
- - mediatek,mt7981-infracfg
- - mediatek,mt7986-infracfg
-+ - mediatek,mt7988-infracfg
- - mediatek,mt8135-infracfg
- - mediatek,mt8167-infracfg
- - mediatek,mt8173-infracfg
---- a/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml
-+++ b/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml
-@@ -22,6 +22,7 @@ properties:
- - mediatek,mt7622-apmixedsys
- - mediatek,mt7981-apmixedsys
- - mediatek,mt7986-apmixedsys
-+ - mediatek,mt7988-apmixedsys
- - mediatek,mt8135-apmixedsys
- - mediatek,mt8173-apmixedsys
- - mediatek,mt8516-apmixedsys
---- a/Documentation/devicetree/bindings/clock/mediatek,ethsys.yaml
-+++ b/Documentation/devicetree/bindings/clock/mediatek,ethsys.yaml
-@@ -22,6 +22,7 @@ properties:
- - mediatek,mt7629-ethsys
- - mediatek,mt7981-ethsys
- - mediatek,mt7986-ethsys
-+ - mediatek,mt7988-ethsys
- - const: syscon
- - items:
- - const: mediatek,mt7623-ethsys
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7988-ethwarp.yaml
-@@ -0,0 +1,52 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/mediatek,mt7988-ethwarp.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MediaTek MT7988 ethwarp Controller
-+
-+maintainers:
-+ - Daniel Golle <daniel@makrotopia.org>
-+
-+description:
-+ The Mediatek MT7988 ethwarp controller provides clocks and resets for the
-+ Ethernet related subsystems found the MT7988 SoC.
-+ The clock values can be found in <dt-bindings/clock/mt*-clk.h>.
-+
-+properties:
-+ compatible:
-+ items:
-+ - const: mediatek,mt7988-ethwarp
-+
-+ reg:
-+ maxItems: 1
-+
-+ '#clock-cells':
-+ const: 1
-+
-+ '#reset-cells':
-+ const: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - '#clock-cells'
-+ - '#reset-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/reset/ti-syscon.h>
-+ soc {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+
-+ clock-controller@15031000 {
-+ compatible = "mediatek,mt7988-ethwarp";
-+ reg = <0 0x15031000 0 0x1000>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+ };
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7988-xfi-pll.yaml
-@@ -0,0 +1,48 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/mediatek,mt7988-xfi-pll.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MediaTek MT7988 XFI PLL Clock Controller
-+
-+maintainers:
-+ - Daniel Golle <daniel@makrotopia.org>
-+
-+description:
-+ The MediaTek XFI PLL controller provides the 156.25MHz clock for the
-+ Ethernet SerDes PHY from the 40MHz top_xtal clock.
-+
-+properties:
-+ compatible:
-+ const: mediatek,mt7988-xfi-pll
-+
-+ reg:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+
-+ '#clock-cells':
-+ const: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - resets
-+ - '#clock-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ soc {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ clock-controller@11f40000 {
-+ compatible = "mediatek,mt7988-xfi-pll";
-+ reg = <0 0x11f40000 0 0x1000>;
-+ resets = <&watchdog 16>;
-+ #clock-cells = <1>;
-+ };
-+ };
---- a/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml
-+++ b/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml
-@@ -37,6 +37,8 @@ properties:
- - mediatek,mt7629-topckgen
- - mediatek,mt7981-topckgen
- - mediatek,mt7986-topckgen
-+ - mediatek,mt7988-mcusys
-+ - mediatek,mt7988-topckgen
- - mediatek,mt8167-topckgen
- - mediatek,mt8183-topckgen
- - const: syscon
---- a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
-+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
-@@ -15,15 +15,22 @@ description:
-
- properties:
- compatible:
-- items:
-- - enum:
-- - mediatek,mt7622-sgmiisys
-- - mediatek,mt7629-sgmiisys
-- - mediatek,mt7981-sgmiisys_0
-- - mediatek,mt7981-sgmiisys_1
-- - mediatek,mt7986-sgmiisys_0
-- - mediatek,mt7986-sgmiisys_1
-- - const: syscon
-+ oneOf:
-+ - items:
-+ - enum:
-+ - mediatek,mt7622-sgmiisys
-+ - mediatek,mt7629-sgmiisys
-+ - mediatek,mt7981-sgmiisys_0
-+ - mediatek,mt7981-sgmiisys_1
-+ - mediatek,mt7986-sgmiisys_0
-+ - mediatek,mt7986-sgmiisys_1
-+ - const: syscon
-+ - items:
-+ - enum:
-+ - mediatek,mt7988-sgmiisys0
-+ - mediatek,mt7988-sgmiisys1
-+ - const: simple-mfd
-+ - const: syscon
-
- reg:
- maxItems: 1
-@@ -35,11 +42,51 @@ properties:
- description: Invert polarity of the SGMII data lanes
- type: boolean
-
-+ pcs:
-+ type: object
-+ description: MediaTek LynxI HSGMII PCS
-+ properties:
-+ compatible:
-+ const: mediatek,mt7988-sgmii
-+
-+ clocks:
-+ maxItems: 3
-+
-+ clock-names:
-+ items:
-+ - const: sgmii_sel
-+ - const: sgmii_tx
-+ - const: sgmii_rx
-+
-+ required:
-+ - compatible
-+ - clocks
-+ - clock-names
-+
-+ additionalProperties: false
-+
- required:
- - compatible
- - reg
- - '#clock-cells'
-
-+allOf:
-+ - if:
-+ properties:
-+ compatible:
-+ contains:
-+ enum:
-+ - mediatek,mt7988-sgmiisys0
-+ - mediatek,mt7988-sgmiisys1
-+
-+ then:
-+ required:
-+ - pcs
-+
-+ else:
-+ properties:
-+ pcs: false
-+
- additionalProperties: false
-
- examples:
+++ /dev/null
-From d9bf944beaaad1890ad3fcb755c61e1c7e4c5630 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Sun, 17 Dec 2023 21:50:07 +0000
-Subject: [PATCH 3/4] clk: mediatek: add pcw_chg_bit control for PLLs of MT7988
-
-Introduce pcw_chg_bit member to struct mtk_pll_data and use it instead
-of the previously hardcoded PCW_CHG_MASK macro if set.
-This will needed for clocks on the MT7988 SoC.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/3b9c65ddb08c8bedf790aacf29871af026b6f0b7.1702849494.git.daniel@makrotopia.org
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/mediatek/clk-pll.c | 5 +++--
- drivers/clk/mediatek/clk-pll.h | 1 +
- 2 files changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/clk/mediatek/clk-pll.c
-+++ b/drivers/clk/mediatek/clk-pll.c
-@@ -23,7 +23,7 @@
- #define CON0_BASE_EN BIT(0)
- #define CON0_PWR_ON BIT(0)
- #define CON0_ISO_EN BIT(1)
--#define PCW_CHG_MASK BIT(31)
-+#define PCW_CHG_BIT 31
-
- #define AUDPLL_TUNER_EN BIT(31)
-
-@@ -141,7 +141,8 @@ static void mtk_pll_set_rate_regs(struct
- pll->data->pcw_shift);
- val |= pcw << pll->data->pcw_shift;
- writel(val, pll->pcw_addr);
-- chg = readl(pll->pcw_chg_addr) | PCW_CHG_MASK;
-+ chg = readl(pll->pcw_chg_addr) |
-+ BIT(pll->data->pcw_chg_bit ? : PCW_CHG_BIT);
- writel(chg, pll->pcw_chg_addr);
- if (pll->tuner_addr)
- writel(val + 1, pll->tuner_addr);
---- a/drivers/clk/mediatek/clk-pll.h
-+++ b/drivers/clk/mediatek/clk-pll.h
-@@ -46,6 +46,7 @@ struct mtk_pll_data {
- const char *parent_name;
- u32 en_reg;
- u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
-+ u8 pcw_chg_bit;
- };
-
- int mtk_clk_register_plls(struct device_node *node,
+++ /dev/null
-From 4b4719437d85f0173d344f2c76fa1a5b7f7d184b Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Sun, 17 Dec 2023 21:50:15 +0000
-Subject: [PATCH 4/4] clk: mediatek: add drivers for MT7988 SoC
-
-Add APMIXED, ETH, INFRACFG and TOPCKGEN clock drivers which are
-typical MediaTek designs.
-
-Also add driver for XFIPLL clock generating the 156.25MHz clock for
-the XFI SerDes. It needs an undocumented software workaround and has
-an unknown internal design.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/c7574d808e2da1a530182f0fd790c1337c336e1b.1702849494.git.daniel@makrotopia.org
-[sboyd@kernel.org: Add module license to infracfg file]
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/mediatek/Kconfig | 9 +
- drivers/clk/mediatek/Makefile | 5 +
- drivers/clk/mediatek/clk-mt7988-apmixed.c | 114 ++++++++
- drivers/clk/mediatek/clk-mt7988-eth.c | 150 ++++++++++
- drivers/clk/mediatek/clk-mt7988-infracfg.c | 275 +++++++++++++++++
- drivers/clk/mediatek/clk-mt7988-topckgen.c | 325 +++++++++++++++++++++
- drivers/clk/mediatek/clk-mt7988-xfipll.c | 82 ++++++
- 7 files changed, 960 insertions(+)
- create mode 100644 drivers/clk/mediatek/clk-mt7988-apmixed.c
- create mode 100644 drivers/clk/mediatek/clk-mt7988-eth.c
- create mode 100644 drivers/clk/mediatek/clk-mt7988-infracfg.c
- create mode 100644 drivers/clk/mediatek/clk-mt7988-topckgen.c
- create mode 100644 drivers/clk/mediatek/clk-mt7988-xfipll.c
-
---- a/drivers/clk/mediatek/Kconfig
-+++ b/drivers/clk/mediatek/Kconfig
-@@ -415,6 +415,15 @@ config COMMON_CLK_MT7986_ETHSYS
- This driver adds support for clocks for Ethernet and SGMII
- required on MediaTek MT7986 SoC.
-
-+config COMMON_CLK_MT7988
-+ tristate "Clock driver for MediaTek MT7988"
-+ depends on ARCH_MEDIATEK || COMPILE_TEST
-+ select COMMON_CLK_MEDIATEK
-+ default ARCH_MEDIATEK
-+ help
-+ This driver supports MediaTek MT7988 basic clocks and clocks
-+ required for various periperals found on this SoC.
-+
- config COMMON_CLK_MT8135
- bool "Clock driver for MediaTek MT8135"
- depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
---- a/drivers/clk/mediatek/Makefile
-+++ b/drivers/clk/mediatek/Makefile
-@@ -60,6 +60,11 @@ obj-$(CONFIG_COMMON_CLK_MT7986) += clk-m
- obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
- obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
- obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o
-+obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-apmixed.o
-+obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-topckgen.o
-+obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-infracfg.o
-+obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-eth.o
-+obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-xfipll.o
- obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
- obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o
- obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt7988-apmixed.c
-@@ -0,0 +1,114 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ * Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include "clk-mtk.h"
-+#include "clk-gate.h"
-+#include "clk-mux.h"
-+#include "clk-pll.h"
-+#include <dt-bindings/clock/mediatek,mt7988-clk.h>
-+
-+#define MT7988_PLL_FMAX (2500UL * MHZ)
-+#define MT7988_PCW_CHG_BIT 2
-+
-+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask, _pcwbits, _pd_reg, \
-+ _pd_shift, _tuner_reg, _tuner_en_reg, _tuner_en_bit, _pcw_reg, _pcw_shift, \
-+ _pcw_chg_reg) \
-+ { \
-+ .id = _id, \
-+ .name = _name, \
-+ .reg = _reg, \
-+ .pwr_reg = _pwr_reg, \
-+ .en_mask = _en_mask, \
-+ .flags = _flags, \
-+ .rst_bar_mask = BIT(_rst_bar_mask), \
-+ .fmax = MT7988_PLL_FMAX, \
-+ .pcwbits = _pcwbits, \
-+ .pd_reg = _pd_reg, \
-+ .pd_shift = _pd_shift, \
-+ .tuner_reg = _tuner_reg, \
-+ .tuner_en_reg = _tuner_en_reg, \
-+ .tuner_en_bit = _tuner_en_bit, \
-+ .pcw_reg = _pcw_reg, \
-+ .pcw_shift = _pcw_shift, \
-+ .pcw_chg_reg = _pcw_chg_reg, \
-+ .pcw_chg_bit = MT7988_PCW_CHG_BIT, \
-+ .parent_name = "clkxtal", \
-+ }
-+
-+static const struct mtk_pll_data plls[] = {
-+ PLL(CLK_APMIXED_NETSYSPLL, "netsyspll", 0x0104, 0x0110, 0x00000001, 0, 0, 32, 0x0104, 4, 0,
-+ 0, 0, 0x0108, 0, 0x0104),
-+ PLL(CLK_APMIXED_MPLL, "mpll", 0x0114, 0x0120, 0xff000001, HAVE_RST_BAR, 23, 32, 0x0114, 4,
-+ 0, 0, 0, 0x0118, 0, 0x0114),
-+ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0124, 0x0130, 0xff000001, HAVE_RST_BAR, 23, 32, 0x0124, 4,
-+ 0, 0, 0, 0x0128, 0, 0x0124),
-+ PLL(CLK_APMIXED_APLL2, "apll2", 0x0134, 0x0140, 0x00000001, 0, 0, 32, 0x0134, 4, 0x0704,
-+ 0x0700, 1, 0x0138, 0, 0x0134),
-+ PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0144, 0x0150, 0xff000001, HAVE_RST_BAR, 23, 32,
-+ 0x0144, 4, 0, 0, 0, 0x0148, 0, 0x0144),
-+ PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0154, 0x0160, 0xff000001, (HAVE_RST_BAR | PLL_AO), 23,
-+ 32, 0x0154, 4, 0, 0, 0, 0x0158, 0, 0x0154),
-+ PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0164, 0x0170, 0x00000001, 0, 0, 32, 0x0164, 4, 0,
-+ 0, 0, 0x0168, 0, 0x0164),
-+ PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0174, 0x0180, 0x00000001, 0, 0, 32, 0x0174, 4, 0, 0, 0,
-+ 0x0178, 0, 0x0174),
-+ PLL(CLK_APMIXED_ARM_B, "arm_b", 0x0204, 0x0210, 0xff000001, (HAVE_RST_BAR | PLL_AO), 23, 32,
-+ 0x0204, 4, 0, 0, 0, 0x0208, 0, 0x0204),
-+ PLL(CLK_APMIXED_CCIPLL2_B, "ccipll2_b", 0x0214, 0x0220, 0xff000001, HAVE_RST_BAR, 23, 32,
-+ 0x0214, 4, 0, 0, 0, 0x0218, 0, 0x0214),
-+ PLL(CLK_APMIXED_USXGMIIPLL, "usxgmiipll", 0x0304, 0x0310, 0xff000001, HAVE_RST_BAR, 23, 32,
-+ 0x0304, 4, 0, 0, 0, 0x0308, 0, 0x0304),
-+ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0314, 0x0320, 0x00000001, 0, 0, 32, 0x0314, 4, 0, 0,
-+ 0, 0x0318, 0, 0x0314),
-+};
-+
-+static const struct of_device_id of_match_clk_mt7988_apmixed[] = {
-+ { .compatible = "mediatek,mt7988-apmixedsys" },
-+ { /* sentinel */ }
-+};
-+
-+static int clk_mt7988_apmixed_probe(struct platform_device *pdev)
-+{
-+ struct clk_hw_onecell_data *clk_data;
-+ struct device_node *node = pdev->dev.of_node;
-+ int r;
-+
-+ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
-+ if (!clk_data)
-+ return -ENOMEM;
-+
-+ r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
-+ if (r)
-+ goto free_apmixed_data;
-+
-+ r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-+ if (r)
-+ goto unregister_plls;
-+
-+ return r;
-+
-+unregister_plls:
-+ mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
-+free_apmixed_data:
-+ mtk_free_clk_data(clk_data);
-+ return r;
-+}
-+
-+static struct platform_driver clk_mt7988_apmixed_drv = {
-+ .probe = clk_mt7988_apmixed_probe,
-+ .driver = {
-+ .name = "clk-mt7988-apmixed",
-+ .of_match_table = of_match_clk_mt7988_apmixed,
-+ },
-+};
-+builtin_platform_driver(clk_mt7988_apmixed_drv);
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt7988-eth.c
-@@ -0,0 +1,150 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ * Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include "clk-mtk.h"
-+#include "clk-gate.h"
-+#include "reset.h"
-+#include <dt-bindings/clock/mediatek,mt7988-clk.h>
-+#include <dt-bindings/reset/mediatek,mt7988-resets.h>
-+
-+static const struct mtk_gate_regs ethdma_cg_regs = {
-+ .set_ofs = 0x30,
-+ .clr_ofs = 0x30,
-+ .sta_ofs = 0x30,
-+};
-+
-+#define GATE_ETHDMA(_id, _name, _parent, _shift) \
-+ { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = ðdma_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate ethdma_clks[] = {
-+ GATE_ETHDMA(CLK_ETHDMA_XGP1_EN, "ethdma_xgp1_en", "top_xtal", 0),
-+ GATE_ETHDMA(CLK_ETHDMA_XGP2_EN, "ethdma_xgp2_en", "top_xtal", 1),
-+ GATE_ETHDMA(CLK_ETHDMA_XGP3_EN, "ethdma_xgp3_en", "top_xtal", 2),
-+ GATE_ETHDMA(CLK_ETHDMA_FE_EN, "ethdma_fe_en", "netsys_2x_sel", 6),
-+ GATE_ETHDMA(CLK_ETHDMA_GP2_EN, "ethdma_gp2_en", "top_xtal", 7),
-+ GATE_ETHDMA(CLK_ETHDMA_GP1_EN, "ethdma_gp1_en", "top_xtal", 8),
-+ GATE_ETHDMA(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en", "top_xtal", 10),
-+ GATE_ETHDMA(CLK_ETHDMA_ESW_EN, "ethdma_esw_en", "netsys_gsw_sel", 16),
-+ GATE_ETHDMA(CLK_ETHDMA_CRYPT0_EN, "ethdma_crypt0_en", "eip197_sel", 29),
-+};
-+
-+static const struct mtk_clk_desc ethdma_desc = {
-+ .clks = ethdma_clks,
-+ .num_clks = ARRAY_SIZE(ethdma_clks),
-+};
-+
-+static const struct mtk_gate_regs sgmii_cg_regs = {
-+ .set_ofs = 0xe4,
-+ .clr_ofs = 0xe4,
-+ .sta_ofs = 0xe4,
-+};
-+
-+#define GATE_SGMII(_id, _name, _parent, _shift) \
-+ { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &sgmii_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate sgmii0_clks[] = {
-+ GATE_SGMII(CLK_SGM0_TX_EN, "sgm0_tx_en", "top_xtal", 2),
-+ GATE_SGMII(CLK_SGM0_RX_EN, "sgm0_rx_en", "top_xtal", 3),
-+};
-+
-+static const struct mtk_clk_desc sgmii0_desc = {
-+ .clks = sgmii0_clks,
-+ .num_clks = ARRAY_SIZE(sgmii0_clks),
-+};
-+
-+static const struct mtk_gate sgmii1_clks[] = {
-+ GATE_SGMII(CLK_SGM1_TX_EN, "sgm1_tx_en", "top_xtal", 2),
-+ GATE_SGMII(CLK_SGM1_RX_EN, "sgm1_rx_en", "top_xtal", 3),
-+};
-+
-+static const struct mtk_clk_desc sgmii1_desc = {
-+ .clks = sgmii1_clks,
-+ .num_clks = ARRAY_SIZE(sgmii1_clks),
-+};
-+
-+static const struct mtk_gate_regs ethwarp_cg_regs = {
-+ .set_ofs = 0x14,
-+ .clr_ofs = 0x14,
-+ .sta_ofs = 0x14,
-+};
-+
-+#define GATE_ETHWARP(_id, _name, _parent, _shift) \
-+ { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = ðwarp_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+ }
-+
-+static const struct mtk_gate ethwarp_clks[] = {
-+ GATE_ETHWARP(CLK_ETHWARP_WOCPU2_EN, "ethwarp_wocpu2_en", "netsys_mcu_sel", 13),
-+ GATE_ETHWARP(CLK_ETHWARP_WOCPU1_EN, "ethwarp_wocpu1_en", "netsys_mcu_sel", 14),
-+ GATE_ETHWARP(CLK_ETHWARP_WOCPU0_EN, "ethwarp_wocpu0_en", "netsys_mcu_sel", 15),
-+};
-+
-+static u16 ethwarp_rst_ofs[] = { 0x8 };
-+
-+static u16 ethwarp_idx_map[] = {
-+ [MT7988_ETHWARP_RST_SWITCH] = 9,
-+};
-+
-+static const struct mtk_clk_rst_desc ethwarp_rst_desc = {
-+ .version = MTK_RST_SIMPLE,
-+ .rst_bank_ofs = ethwarp_rst_ofs,
-+ .rst_bank_nr = ARRAY_SIZE(ethwarp_rst_ofs),
-+ .rst_idx_map = ethwarp_idx_map,
-+ .rst_idx_map_nr = ARRAY_SIZE(ethwarp_idx_map),
-+};
-+
-+static const struct mtk_clk_desc ethwarp_desc = {
-+ .clks = ethwarp_clks,
-+ .num_clks = ARRAY_SIZE(ethwarp_clks),
-+ .rst_desc = ðwarp_rst_desc,
-+};
-+
-+static const struct of_device_id of_match_clk_mt7988_eth[] = {
-+ { .compatible = "mediatek,mt7988-ethsys", .data = ðdma_desc },
-+ { .compatible = "mediatek,mt7988-sgmiisys0", .data = &sgmii0_desc },
-+ { .compatible = "mediatek,mt7988-sgmiisys1", .data = &sgmii1_desc },
-+ { .compatible = "mediatek,mt7988-ethwarp", .data = ðwarp_desc },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_eth);
-+
-+static struct platform_driver clk_mt7988_eth_drv = {
-+ .driver = {
-+ .name = "clk-mt7988-eth",
-+ .of_match_table = of_match_clk_mt7988_eth,
-+ },
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
-+};
-+module_platform_driver(clk_mt7988_eth_drv);
-+
-+MODULE_DESCRIPTION("MediaTek MT7988 Ethernet clocks driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c
-@@ -0,0 +1,275 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ * Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include "clk-mtk.h"
-+#include "clk-gate.h"
-+#include "clk-mux.h"
-+#include <dt-bindings/clock/mediatek,mt7988-clk.h>
-+
-+static DEFINE_SPINLOCK(mt7988_clk_lock);
-+
-+static const char *const infra_mux_uart0_parents[] __initconst = { "csw_infra_f26m_sel",
-+ "uart_sel" };
-+
-+static const char *const infra_mux_uart1_parents[] __initconst = { "csw_infra_f26m_sel",
-+ "uart_sel" };
-+
-+static const char *const infra_mux_uart2_parents[] __initconst = { "csw_infra_f26m_sel",
-+ "uart_sel" };
-+
-+static const char *const infra_mux_spi0_parents[] __initconst = { "i2c_sel", "spi_sel" };
-+
-+static const char *const infra_mux_spi1_parents[] __initconst = { "i2c_sel", "spim_mst_sel" };
-+
-+static const char *const infra_pwm_bck_parents[] __initconst = { "top_rtc_32p7k",
-+ "csw_infra_f26m_sel", "sysaxi_sel",
-+ "pwm_sel" };
-+
-+static const char *const infra_pcie_gfmux_tl_ck_o_p0_parents[] __initconst = {
-+ "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel", "pextp_tl_sel"
-+};
-+
-+static const char *const infra_pcie_gfmux_tl_ck_o_p1_parents[] __initconst = {
-+ "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel", "pextp_tl_p1_sel"
-+};
-+
-+static const char *const infra_pcie_gfmux_tl_ck_o_p2_parents[] __initconst = {
-+ "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel", "pextp_tl_p2_sel"
-+};
-+
-+static const char *const infra_pcie_gfmux_tl_ck_o_p3_parents[] __initconst = {
-+ "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel", "pextp_tl_p3_sel"
-+};
-+
-+static const struct mtk_mux infra_muxes[] = {
-+ /* MODULE_CLK_SEL_0 */
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART0_SEL, "infra_mux_uart0_sel",
-+ infra_mux_uart0_parents, 0x0018, 0x0010, 0x0014, 0, 1, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART1_SEL, "infra_mux_uart1_sel",
-+ infra_mux_uart1_parents, 0x0018, 0x0010, 0x0014, 1, 1, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART2_SEL, "infra_mux_uart2_sel",
-+ infra_mux_uart2_parents, 0x0018, 0x0010, 0x0014, 2, 1, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI0_SEL, "infra_mux_spi0_sel", infra_mux_spi0_parents,
-+ 0x0018, 0x0010, 0x0014, 4, 1, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI1_SEL, "infra_mux_spi1_sel", infra_mux_spi1_parents,
-+ 0x0018, 0x0010, 0x0014, 5, 1, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI2_SEL, "infra_mux_spi2_sel", infra_mux_spi0_parents,
-+ 0x0018, 0x0010, 0x0014, 6, 1, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_SEL, "infra_pwm_sel", infra_pwm_bck_parents, 0x0018,
-+ 0x0010, 0x0014, 14, 2, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK1_SEL, "infra_pwm_ck1_sel", infra_pwm_bck_parents,
-+ 0x0018, 0x0010, 0x0014, 16, 2, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK2_SEL, "infra_pwm_ck2_sel", infra_pwm_bck_parents,
-+ 0x0018, 0x0010, 0x0014, 18, 2, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK3_SEL, "infra_pwm_ck3_sel", infra_pwm_bck_parents,
-+ 0x0018, 0x0010, 0x0014, 20, 2, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK4_SEL, "infra_pwm_ck4_sel", infra_pwm_bck_parents,
-+ 0x0018, 0x0010, 0x0014, 22, 2, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK5_SEL, "infra_pwm_ck5_sel", infra_pwm_bck_parents,
-+ 0x0018, 0x0010, 0x0014, 24, 2, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK6_SEL, "infra_pwm_ck6_sel", infra_pwm_bck_parents,
-+ 0x0018, 0x0010, 0x0014, 26, 2, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK7_SEL, "infra_pwm_ck7_sel", infra_pwm_bck_parents,
-+ 0x0018, 0x0010, 0x0014, 28, 2, -1, -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK8_SEL, "infra_pwm_ck8_sel", infra_pwm_bck_parents,
-+ 0x0018, 0x0010, 0x0014, 30, 2, -1, -1, -1),
-+ /* MODULE_CLK_SEL_1 */
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL, "infra_pcie_gfmux_tl_o_p0_sel",
-+ infra_pcie_gfmux_tl_ck_o_p0_parents, 0x0028, 0x0020, 0x0024, 0, 2, -1,
-+ -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL, "infra_pcie_gfmux_tl_o_p1_sel",
-+ infra_pcie_gfmux_tl_ck_o_p1_parents, 0x0028, 0x0020, 0x0024, 2, 2, -1,
-+ -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P2_SEL, "infra_pcie_gfmux_tl_o_p2_sel",
-+ infra_pcie_gfmux_tl_ck_o_p2_parents, 0x0028, 0x0020, 0x0024, 4, 2, -1,
-+ -1, -1),
-+ MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P3_SEL, "infra_pcie_gfmux_tl_o_p3_sel",
-+ infra_pcie_gfmux_tl_ck_o_p3_parents, 0x0028, 0x0020, 0x0024, 6, 2, -1,
-+ -1, -1),
-+};
-+
-+static const struct mtk_gate_regs infra0_cg_regs = {
-+ .set_ofs = 0x10,
-+ .clr_ofs = 0x14,
-+ .sta_ofs = 0x18,
-+};
-+
-+static const struct mtk_gate_regs infra1_cg_regs = {
-+ .set_ofs = 0x40,
-+ .clr_ofs = 0x44,
-+ .sta_ofs = 0x48,
-+};
-+
-+static const struct mtk_gate_regs infra2_cg_regs = {
-+ .set_ofs = 0x50,
-+ .clr_ofs = 0x54,
-+ .sta_ofs = 0x58,
-+};
-+
-+static const struct mtk_gate_regs infra3_cg_regs = {
-+ .set_ofs = 0x60,
-+ .clr_ofs = 0x64,
-+ .sta_ofs = 0x68,
-+};
-+
-+#define GATE_INFRA0_FLAGS(_id, _name, _parent, _shift, _flags) \
-+ GATE_MTK_FLAGS(_id, _name, _parent, &infra0_cg_regs, _shift, &mtk_clk_gate_ops_setclr, \
-+ _flags)
-+
-+#define GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, _flags) \
-+ GATE_MTK_FLAGS(_id, _name, _parent, &infra1_cg_regs, _shift, &mtk_clk_gate_ops_setclr, \
-+ _flags)
-+
-+#define GATE_INFRA2_FLAGS(_id, _name, _parent, _shift, _flags) \
-+ GATE_MTK_FLAGS(_id, _name, _parent, &infra2_cg_regs, _shift, &mtk_clk_gate_ops_setclr, \
-+ _flags)
-+
-+#define GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, _flags) \
-+ GATE_MTK_FLAGS(_id, _name, _parent, &infra3_cg_regs, _shift, &mtk_clk_gate_ops_setclr, \
-+ _flags)
-+
-+#define GATE_INFRA0(_id, _name, _parent, _shift) GATE_INFRA0_FLAGS(_id, _name, _parent, _shift, 0)
-+
-+#define GATE_INFRA1(_id, _name, _parent, _shift) GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, 0)
-+
-+#define GATE_INFRA2(_id, _name, _parent, _shift) GATE_INFRA2_FLAGS(_id, _name, _parent, _shift, 0)
-+
-+#define GATE_INFRA3(_id, _name, _parent, _shift) GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, 0)
-+
-+static const struct mtk_gate infra_clks[] = {
-+ /* INFRA0 */
-+ GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P0, "infra_pcie_peri_ck_26m_ck_p0",
-+ "csw_infra_f26m_sel", 7),
-+ GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P1, "infra_pcie_peri_ck_26m_ck_p1",
-+ "csw_infra_f26m_sel", 8),
-+ GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P2, "infra_pcie_peri_ck_26m_ck_p2",
-+ "csw_infra_f26m_sel", 9),
-+ GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P3, "infra_pcie_peri_ck_26m_ck_p3",
-+ "csw_infra_f26m_sel", 10),
-+ /* INFRA1 */
-+ GATE_INFRA1(CLK_INFRA_66M_GPT_BCK, "infra_hf_66m_gpt_bck", "sysaxi_sel", 0),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_HCK, "infra_hf_66m_pwm_hck", "sysaxi_sel", 1),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_BCK, "infra_hf_66m_pwm_bck", "infra_pwm_sel", 2),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_CK1, "infra_hf_66m_pwm_ck1", "infra_pwm_ck1_sel", 3),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_CK2, "infra_hf_66m_pwm_ck2", "infra_pwm_ck2_sel", 4),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_CK3, "infra_hf_66m_pwm_ck3", "infra_pwm_ck3_sel", 5),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_CK4, "infra_hf_66m_pwm_ck4", "infra_pwm_ck4_sel", 6),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_CK5, "infra_hf_66m_pwm_ck5", "infra_pwm_ck5_sel", 7),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_CK6, "infra_hf_66m_pwm_ck6", "infra_pwm_ck6_sel", 8),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_CK7, "infra_hf_66m_pwm_ck7", "infra_pwm_ck7_sel", 9),
-+ GATE_INFRA1(CLK_INFRA_66M_PWM_CK8, "infra_hf_66m_pwm_ck8", "infra_pwm_ck8_sel", 10),
-+ GATE_INFRA1(CLK_INFRA_133M_CQDMA_BCK, "infra_hf_133m_cqdma_bck", "sysaxi_sel", 12),
-+ GATE_INFRA1(CLK_INFRA_66M_AUD_SLV_BCK, "infra_66m_aud_slv_bck", "sysaxi_sel", 13),
-+ GATE_INFRA1(CLK_INFRA_AUD_26M, "infra_f_faud_26m", "csw_infra_f26m_sel", 14),
-+ GATE_INFRA1(CLK_INFRA_AUD_L, "infra_f_faud_l", "aud_l_sel", 15),
-+ GATE_INFRA1(CLK_INFRA_AUD_AUD, "infra_f_aud_aud", "a1sys_sel", 16),
-+ GATE_INFRA1(CLK_INFRA_AUD_EG2, "infra_f_faud_eg2", "a_tuner_sel", 18),
-+ GATE_INFRA1_FLAGS(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", "csw_infra_f26m_sel", 19,
-+ CLK_IS_CRITICAL),
-+ /* JTAG */
-+ GATE_INFRA1_FLAGS(CLK_INFRA_133M_DBG_ACKM, "infra_hf_133m_dbg_ackm", "sysaxi_sel", 20,
-+ CLK_IS_CRITICAL),
-+ GATE_INFRA1(CLK_INFRA_66M_AP_DMA_BCK, "infra_66m_ap_dma_bck", "sysaxi_sel", 21),
-+ GATE_INFRA1(CLK_INFRA_66M_SEJ_BCK, "infra_hf_66m_sej_bck", "sysaxi_sel", 29),
-+ GATE_INFRA1(CLK_INFRA_PRE_CK_SEJ_F13M, "infra_pre_ck_sej_f13m", "csw_infra_f26m_sel", 30),
-+ /* INFRA2 */
-+ GATE_INFRA2(CLK_INFRA_26M_THERM_SYSTEM, "infra_hf_26m_therm_system", "csw_infra_f26m_sel",
-+ 0),
-+ GATE_INFRA2(CLK_INFRA_I2C_BCK, "infra_i2c_bck", "i2c_sel", 1),
-+ GATE_INFRA2(CLK_INFRA_52M_UART0_CK, "infra_f_52m_uart0", "infra_mux_uart0_sel", 3),
-+ GATE_INFRA2(CLK_INFRA_52M_UART1_CK, "infra_f_52m_uart1", "infra_mux_uart1_sel", 4),
-+ GATE_INFRA2(CLK_INFRA_52M_UART2_CK, "infra_f_52m_uart2", "infra_mux_uart2_sel", 5),
-+ GATE_INFRA2(CLK_INFRA_NFI, "infra_f_fnfi", "nfi1x_sel", 9),
-+ GATE_INFRA2(CLK_INFRA_SPINFI, "infra_f_fspinfi", "spinfi_sel", 10),
-+ GATE_INFRA2_FLAGS(CLK_INFRA_66M_NFI_HCK, "infra_hf_66m_nfi_hck", "sysaxi_sel", 11,
-+ CLK_IS_CRITICAL),
-+ GATE_INFRA2_FLAGS(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0", "infra_mux_spi0_sel", 12,
-+ CLK_IS_CRITICAL),
-+ GATE_INFRA2(CLK_INFRA_104M_SPI1, "infra_hf_104m_spi1", "infra_mux_spi1_sel", 13),
-+ GATE_INFRA2(CLK_INFRA_104M_SPI2_BCK, "infra_hf_104m_spi2_bck", "infra_mux_spi2_sel", 14),
-+ GATE_INFRA2_FLAGS(CLK_INFRA_66M_SPI0_HCK, "infra_hf_66m_spi0_hck", "sysaxi_sel", 15,
-+ CLK_IS_CRITICAL),
-+ GATE_INFRA2(CLK_INFRA_66M_SPI1_HCK, "infra_hf_66m_spi1_hck", "sysaxi_sel", 16),
-+ GATE_INFRA2(CLK_INFRA_66M_SPI2_HCK, "infra_hf_66m_spi2_hck", "sysaxi_sel", 17),
-+ GATE_INFRA2(CLK_INFRA_66M_FLASHIF_AXI, "infra_hf_66m_flashif_axi", "sysaxi_sel", 18),
-+ GATE_INFRA2_FLAGS(CLK_INFRA_RTC, "infra_f_frtc", "top_rtc_32k", 19, CLK_IS_CRITICAL),
-+ GATE_INFRA2(CLK_INFRA_26M_ADC_BCK, "infra_f_26m_adc_bck", "csw_infra_f26m_sel", 20),
-+ GATE_INFRA2(CLK_INFRA_RC_ADC, "infra_f_frc_adc", "infra_f_26m_adc_bck", 21),
-+ GATE_INFRA2(CLK_INFRA_MSDC400, "infra_f_fmsdc400", "emmc_400m_sel", 22),
-+ GATE_INFRA2(CLK_INFRA_MSDC2_HCK, "infra_f_fmsdc2_hck", "emmc_250m_sel", 23),
-+ GATE_INFRA2(CLK_INFRA_133M_MSDC_0_HCK, "infra_hf_133m_msdc_0_hck", "sysaxi_sel", 24),
-+ GATE_INFRA2(CLK_INFRA_66M_MSDC_0_HCK, "infra_66m_msdc_0_hck", "sysaxi_sel", 25),
-+ GATE_INFRA2(CLK_INFRA_133M_CPUM_BCK, "infra_hf_133m_cpum_bck", "sysaxi_sel", 26),
-+ GATE_INFRA2(CLK_INFRA_BIST2FPC, "infra_hf_fbist2fpc", "nfi1x_sel", 27),
-+ GATE_INFRA2(CLK_INFRA_I2C_X16W_MCK_CK_P1, "infra_hf_i2c_x16w_mck_ck_p1", "sysaxi_sel", 29),
-+ GATE_INFRA2(CLK_INFRA_I2C_X16W_PCK_CK_P1, "infra_hf_i2c_x16w_pck_ck_p1", "sysaxi_sel", 31),
-+ /* INFRA3 */
-+ GATE_INFRA3(CLK_INFRA_133M_USB_HCK, "infra_133m_usb_hck", "sysaxi_sel", 0),
-+ GATE_INFRA3(CLK_INFRA_133M_USB_HCK_CK_P1, "infra_133m_usb_hck_ck_p1", "sysaxi_sel", 1),
-+ GATE_INFRA3(CLK_INFRA_66M_USB_HCK, "infra_66m_usb_hck", "sysaxi_sel", 2),
-+ GATE_INFRA3(CLK_INFRA_66M_USB_HCK_CK_P1, "infra_66m_usb_hck_ck_p1", "sysaxi_sel", 3),
-+ GATE_INFRA3(CLK_INFRA_USB_SYS, "infra_usb_sys", "usb_sys_sel", 4),
-+ GATE_INFRA3(CLK_INFRA_USB_SYS_CK_P1, "infra_usb_sys_ck_p1", "usb_sys_p1_sel", 5),
-+ GATE_INFRA3(CLK_INFRA_USB_REF, "infra_usb_ref", "top_xtal", 6),
-+ GATE_INFRA3(CLK_INFRA_USB_CK_P1, "infra_usb_ck_p1", "top_xtal", 7),
-+ GATE_INFRA3_FLAGS(CLK_INFRA_USB_FRMCNT, "infra_usb_frmcnt", "usb_frmcnt_sel", 8,
-+ CLK_IS_CRITICAL),
-+ GATE_INFRA3_FLAGS(CLK_INFRA_USB_FRMCNT_CK_P1, "infra_usb_frmcnt_ck_p1", "usb_frmcnt_p1_sel",
-+ 9, CLK_IS_CRITICAL),
-+ GATE_INFRA3(CLK_INFRA_USB_PIPE, "infra_usb_pipe", "sspxtp_sel", 10),
-+ GATE_INFRA3(CLK_INFRA_USB_PIPE_CK_P1, "infra_usb_pipe_ck_p1", "usb_phy_sel", 11),
-+ GATE_INFRA3(CLK_INFRA_USB_UTMI, "infra_usb_utmi", "top_xtal", 12),
-+ GATE_INFRA3(CLK_INFRA_USB_UTMI_CK_P1, "infra_usb_utmi_ck_p1", "top_xtal", 13),
-+ GATE_INFRA3(CLK_INFRA_USB_XHCI, "infra_usb_xhci", "usb_xhci_sel", 14),
-+ GATE_INFRA3(CLK_INFRA_USB_XHCI_CK_P1, "infra_usb_xhci_ck_p1", "usb_xhci_p1_sel", 15),
-+ GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P0, "infra_pcie_gfmux_tl_ck_p0",
-+ "infra_pcie_gfmux_tl_o_p0_sel", 20),
-+ GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P1, "infra_pcie_gfmux_tl_ck_p1",
-+ "infra_pcie_gfmux_tl_o_p1_sel", 21),
-+ GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P2, "infra_pcie_gfmux_tl_ck_p2",
-+ "infra_pcie_gfmux_tl_o_p2_sel", 22),
-+ GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P3, "infra_pcie_gfmux_tl_ck_p3",
-+ "infra_pcie_gfmux_tl_o_p3_sel", 23),
-+ GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P0, "infra_pcie_pipe_ck_p0", "top_xtal", 24),
-+ GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P1, "infra_pcie_pipe_ck_p1", "top_xtal", 25),
-+ GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P2, "infra_pcie_pipe_ck_p2", "top_xtal", 26),
-+ GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P3, "infra_pcie_pipe_ck_p3", "top_xtal", 27),
-+ GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P0, "infra_133m_pcie_ck_p0", "sysaxi_sel", 28),
-+ GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P1, "infra_133m_pcie_ck_p1", "sysaxi_sel", 29),
-+ GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P2, "infra_133m_pcie_ck_p2", "sysaxi_sel", 30),
-+ GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P3, "infra_133m_pcie_ck_p3", "sysaxi_sel", 31),
-+};
-+
-+static const struct mtk_clk_desc infra_desc = {
-+ .clks = infra_clks,
-+ .num_clks = ARRAY_SIZE(infra_clks),
-+ .mux_clks = infra_muxes,
-+ .num_mux_clks = ARRAY_SIZE(infra_muxes),
-+ .clk_lock = &mt7988_clk_lock,
-+};
-+
-+static const struct of_device_id of_match_clk_mt7988_infracfg[] = {
-+ { .compatible = "mediatek,mt7988-infracfg", .data = &infra_desc },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_infracfg);
-+
-+static struct platform_driver clk_mt7988_infracfg_drv = {
-+ .driver = {
-+ .name = "clk-mt7988-infracfg",
-+ .of_match_table = of_match_clk_mt7988_infracfg,
-+ },
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
-+};
-+module_platform_driver(clk_mt7988_infracfg_drv);
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt7988-topckgen.c
-@@ -0,0 +1,325 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Author: Sam Shih <sam.shih@mediatek.com>
-+ * Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include "clk-mtk.h"
-+#include "clk-gate.h"
-+#include "clk-mux.h"
-+#include <dt-bindings/clock/mediatek,mt7988-clk.h>
-+
-+static DEFINE_SPINLOCK(mt7988_clk_lock);
-+
-+static const struct mtk_fixed_clk top_fixed_clks[] = {
-+ FIXED_CLK(CLK_TOP_XTAL, "top_xtal", "clkxtal", 40000000),
-+};
-+
-+static const struct mtk_fixed_factor top_divs[] = {
-+ FACTOR(CLK_TOP_XTAL_D2, "top_xtal_d2", "top_xtal", 1, 2),
-+ FACTOR(CLK_TOP_RTC_32K, "top_rtc_32k", "top_xtal", 1, 1250),
-+ FACTOR(CLK_TOP_RTC_32P7K, "top_rtc_32p7k", "top_xtal", 1, 1220),
-+ FACTOR(CLK_TOP_MPLL_D2, "mpll_d2", "mpll", 1, 2),
-+ FACTOR(CLK_TOP_MPLL_D3_D2, "mpll_d3_d2", "mpll", 1, 2),
-+ FACTOR(CLK_TOP_MPLL_D4, "mpll_d4", "mpll", 1, 4),
-+ FACTOR(CLK_TOP_MPLL_D8, "mpll_d8", "mpll", 1, 8),
-+ FACTOR(CLK_TOP_MPLL_D8_D2, "mpll_d8_d2", "mpll", 1, 16),
-+ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
-+ FACTOR(CLK_TOP_MMPLL_D3_D5, "mmpll_d3_d5", "mmpll", 1, 15),
-+ FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll", 1, 4),
-+ FACTOR(CLK_TOP_MMPLL_D6_D2, "mmpll_d6_d2", "mmpll", 1, 12),
-+ FACTOR(CLK_TOP_MMPLL_D8, "mmpll_d8", "mmpll", 1, 8),
-+ FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
-+ FACTOR(CLK_TOP_NET1PLL_D4, "net1pll_d4", "net1pll", 1, 4),
-+ FACTOR(CLK_TOP_NET1PLL_D5, "net1pll_d5", "net1pll", 1, 5),
-+ FACTOR(CLK_TOP_NET1PLL_D5_D2, "net1pll_d5_d2", "net1pll", 1, 10),
-+ FACTOR(CLK_TOP_NET1PLL_D5_D4, "net1pll_d5_d4", "net1pll", 1, 20),
-+ FACTOR(CLK_TOP_NET1PLL_D8, "net1pll_d8", "net1pll", 1, 8),
-+ FACTOR(CLK_TOP_NET1PLL_D8_D2, "net1pll_d8_d2", "net1pll", 1, 16),
-+ FACTOR(CLK_TOP_NET1PLL_D8_D4, "net1pll_d8_d4", "net1pll", 1, 32),
-+ FACTOR(CLK_TOP_NET1PLL_D8_D8, "net1pll_d8_d8", "net1pll", 1, 64),
-+ FACTOR(CLK_TOP_NET1PLL_D8_D16, "net1pll_d8_d16", "net1pll", 1, 128),
-+ FACTOR(CLK_TOP_NET2PLL_D2, "net2pll_d2", "net2pll", 1, 2),
-+ FACTOR(CLK_TOP_NET2PLL_D4, "net2pll_d4", "net2pll", 1, 4),
-+ FACTOR(CLK_TOP_NET2PLL_D4_D4, "net2pll_d4_d4", "net2pll", 1, 16),
-+ FACTOR(CLK_TOP_NET2PLL_D4_D8, "net2pll_d4_d8", "net2pll", 1, 32),
-+ FACTOR(CLK_TOP_NET2PLL_D6, "net2pll_d6", "net2pll", 1, 6),
-+ FACTOR(CLK_TOP_NET2PLL_D8, "net2pll_d8", "net2pll", 1, 8),
-+};
-+
-+static const char *const netsys_parents[] = { "top_xtal", "net2pll_d2", "mmpll_d2" };
-+static const char *const netsys_500m_parents[] = { "top_xtal", "net1pll_d5", "net1pll_d5_d2" };
-+static const char *const netsys_2x_parents[] = { "top_xtal", "net2pll", "mmpll" };
-+static const char *const netsys_gsw_parents[] = { "top_xtal", "net1pll_d4", "net1pll_d5" };
-+static const char *const eth_gmii_parents[] = { "top_xtal", "net1pll_d5_d4" };
-+static const char *const netsys_mcu_parents[] = { "top_xtal", "net2pll", "mmpll",
-+ "net1pll_d4", "net1pll_d5", "mpll" };
-+static const char *const eip197_parents[] = { "top_xtal", "netsyspll", "net2pll",
-+ "mmpll", "net1pll_d4", "net1pll_d5" };
-+static const char *const axi_infra_parents[] = { "top_xtal", "net1pll_d8_d2" };
-+static const char *const uart_parents[] = { "top_xtal", "mpll_d8", "mpll_d8_d2" };
-+static const char *const emmc_250m_parents[] = { "top_xtal", "net1pll_d5_d2", "mmpll_d4" };
-+static const char *const emmc_400m_parents[] = { "top_xtal", "msdcpll", "mmpll_d2",
-+ "mpll_d2", "mmpll_d4", "net1pll_d8_d2" };
-+static const char *const spi_parents[] = { "top_xtal", "mpll_d2", "mmpll_d4",
-+ "net1pll_d8_d2", "net2pll_d6", "net1pll_d5_d4",
-+ "mpll_d4", "net1pll_d8_d4" };
-+static const char *const nfi1x_parents[] = { "top_xtal", "mmpll_d4", "net1pll_d8_d2", "net2pll_d6",
-+ "mpll_d4", "mmpll_d8", "net1pll_d8_d4", "mpll_d8" };
-+static const char *const spinfi_parents[] = { "top_xtal_d2", "top_xtal", "net1pll_d5_d4",
-+ "mpll_d4", "mmpll_d8", "net1pll_d8_d4",
-+ "mmpll_d6_d2", "mpll_d8" };
-+static const char *const pwm_parents[] = { "top_xtal", "net1pll_d8_d2", "net1pll_d5_d4",
-+ "mpll_d4", "mpll_d8_d2", "top_rtc_32k" };
-+static const char *const i2c_parents[] = { "top_xtal", "net1pll_d5_d4", "mpll_d4",
-+ "net1pll_d8_d4" };
-+static const char *const pcie_mbist_250m_parents[] = { "top_xtal", "net1pll_d5_d2" };
-+static const char *const pextp_tl_ck_parents[] = { "top_xtal", "net2pll_d6", "mmpll_d8",
-+ "mpll_d8_d2", "top_rtc_32k" };
-+static const char *const usb_frmcnt_parents[] = { "top_xtal", "mmpll_d3_d5" };
-+static const char *const aud_parents[] = { "top_xtal", "apll2" };
-+static const char *const a1sys_parents[] = { "top_xtal", "apll2_d4" };
-+static const char *const aud_l_parents[] = { "top_xtal", "apll2", "mpll_d8_d2" };
-+static const char *const sspxtp_parents[] = { "top_xtal_d2", "mpll_d8_d2" };
-+static const char *const usxgmii_sbus_0_parents[] = { "top_xtal", "net1pll_d8_d4" };
-+static const char *const sgm_0_parents[] = { "top_xtal", "sgmpll" };
-+static const char *const sysapb_parents[] = { "top_xtal", "mpll_d3_d2" };
-+static const char *const eth_refck_50m_parents[] = { "top_xtal", "net2pll_d4_d4" };
-+static const char *const eth_sys_200m_parents[] = { "top_xtal", "net2pll_d4" };
-+static const char *const eth_xgmii_parents[] = { "top_xtal_d2", "net1pll_d8_d8", "net1pll_d8_d16" };
-+static const char *const bus_tops_parents[] = { "top_xtal", "net1pll_d5", "net2pll_d2" };
-+static const char *const npu_tops_parents[] = { "top_xtal", "net2pll" };
-+static const char *const dramc_md32_parents[] = { "top_xtal", "mpll_d2", "wedmcupll" };
-+static const char *const da_xtp_glb_p0_parents[] = { "top_xtal", "net2pll_d8" };
-+static const char *const mcusys_backup_625m_parents[] = { "top_xtal", "net1pll_d4" };
-+static const char *const macsec_parents[] = { "top_xtal", "sgmpll", "net1pll_d8" };
-+static const char *const netsys_tops_400m_parents[] = { "top_xtal", "net2pll_d2" };
-+static const char *const eth_mii_parents[] = { "top_xtal_d2", "net2pll_d4_d8" };
-+
-+static const struct mtk_mux top_muxes[] = {
-+ /* CLK_CFG_0 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x000, 0x004, 0x008,
-+ 0, 2, 7, 0x1c0, 0),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents, 0x000,
-+ 0x004, 0x008, 8, 2, 15, 0x1C0, 1),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x000,
-+ 0x004, 0x008, 16, 2, 23, 0x1C0, 2),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_GSW_SEL, "netsys_gsw_sel", netsys_gsw_parents, 0x000,
-+ 0x004, 0x008, 24, 2, 31, 0x1C0, 3),
-+ /* CLK_CFG_1 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_GMII_SEL, "eth_gmii_sel", eth_gmii_parents, 0x010, 0x014,
-+ 0x018, 0, 1, 7, 0x1C0, 4),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents, 0x010,
-+ 0x014, 0x018, 8, 3, 15, 0x1C0, 5),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_PAO_2X_SEL, "netsys_pao_2x_sel", netsys_mcu_parents,
-+ 0x010, 0x014, 0x018, 16, 3, 23, 0x1C0, 6),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP197_SEL, "eip197_sel", eip197_parents, 0x010, 0x014, 0x018,
-+ 24, 3, 31, 0x1c0, 7),
-+ /* CLK_CFG_2 */
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_INFRA_SEL, "axi_infra_sel", axi_infra_parents, 0x020,
-+ 0x024, 0x028, 0, 1, 7, 0x1C0, 8, CLK_IS_CRITICAL),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x020, 0x024, 0x028, 8, 2,
-+ 15, 0x1c0, 9),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_250M_SEL, "emmc_250m_sel", emmc_250m_parents, 0x020,
-+ 0x024, 0x028, 16, 2, 23, 0x1C0, 10),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_400M_SEL, "emmc_400m_sel", emmc_400m_parents, 0x020,
-+ 0x024, 0x028, 24, 3, 31, 0x1C0, 11),
-+ /* CLK_CFG_3 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x030, 0x034, 0x038, 0, 3, 7,
-+ 0x1c0, 12),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x030, 0x034, 0x038,
-+ 8, 3, 15, 0x1c0, 13),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x030, 0x034, 0x038, 16,
-+ 3, 23, 0x1c0, 14),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x030, 0x034, 0x038,
-+ 24, 3, 31, 0x1c0, 15),
-+ /* CLK_CFG_4 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x040, 0x044, 0x048, 0, 3, 7,
-+ 0x1c0, 16),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x040, 0x044, 0x048, 8, 2, 15,
-+ 0x1c0, 17),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PCIE_MBIST_250M_SEL, "pcie_mbist_250m_sel",
-+ pcie_mbist_250m_parents, 0x040, 0x044, 0x048, 16, 1, 23, 0x1C0, 18),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_sel", pextp_tl_ck_parents, 0x040,
-+ 0x044, 0x048, 24, 3, 31, 0x1C0, 19),
-+ /* CLK_CFG_5 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P1_SEL, "pextp_tl_p1_sel", pextp_tl_ck_parents, 0x050,
-+ 0x054, 0x058, 0, 3, 7, 0x1C0, 20),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P2_SEL, "pextp_tl_p2_sel", pextp_tl_ck_parents, 0x050,
-+ 0x054, 0x058, 8, 3, 15, 0x1C0, 21),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P3_SEL, "pextp_tl_p3_sel", pextp_tl_ck_parents, 0x050,
-+ 0x054, 0x058, 16, 3, 23, 0x1C0, 22),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_SYS_SEL, "usb_sys_sel", eth_gmii_parents, 0x050, 0x054,
-+ 0x058, 24, 1, 31, 0x1C0, 23),
-+ /* CLK_CFG_6 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_SYS_P1_SEL, "usb_sys_p1_sel", eth_gmii_parents, 0x060,
-+ 0x064, 0x068, 0, 1, 7, 0x1C0, 24),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_XHCI_SEL, "usb_xhci_sel", eth_gmii_parents, 0x060, 0x064,
-+ 0x068, 8, 1, 15, 0x1C0, 25),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_XHCI_P1_SEL, "usb_xhci_p1_sel", eth_gmii_parents, 0x060,
-+ 0x064, 0x068, 16, 1, 23, 0x1C0, 26),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel", usb_frmcnt_parents, 0x060,
-+ 0x064, 0x068, 24, 1, 31, 0x1C0, 27),
-+ /* CLK_CFG_7 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_FRMCNT_P1_SEL, "usb_frmcnt_p1_sel", usb_frmcnt_parents,
-+ 0x070, 0x074, 0x078, 0, 1, 7, 0x1C0, 28),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x070, 0x074, 0x078, 8, 1, 15,
-+ 0x1c0, 29),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x070, 0x074, 0x078, 16,
-+ 1, 23, 0x1c0, 30),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x070, 0x074, 0x078, 24,
-+ 2, 31, 0x1c4, 0),
-+ /* CLK_CFG_8 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel", a1sys_parents, 0x080, 0x084, 0x088,
-+ 0, 1, 7, 0x1c4, 1),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SSPXTP_SEL, "sspxtp_sel", sspxtp_parents, 0x080, 0x084, 0x088,
-+ 8, 1, 15, 0x1c4, 2),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_PHY_SEL, "usb_phy_sel", sspxtp_parents, 0x080, 0x084,
-+ 0x088, 16, 1, 23, 0x1c4, 3),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USXGMII_SBUS_0_SEL, "usxgmii_sbus_0_sel",
-+ usxgmii_sbus_0_parents, 0x080, 0x084, 0x088, 24, 1, 31, 0x1C4, 4),
-+ /* CLK_CFG_9 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_USXGMII_SBUS_1_SEL, "usxgmii_sbus_1_sel",
-+ usxgmii_sbus_0_parents, 0x090, 0x094, 0x098, 0, 1, 7, 0x1C4, 5),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_0_SEL, "sgm_0_sel", sgm_0_parents, 0x090, 0x094, 0x098, 8,
-+ 1, 15, 0x1c4, 6),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_SBUS_0_SEL, "sgm_sbus_0_sel", usxgmii_sbus_0_parents,
-+ 0x090, 0x094, 0x098, 16, 1, 23, 0x1C4, 7, CLK_IS_CRITICAL),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_1_SEL, "sgm_1_sel", sgm_0_parents, 0x090, 0x094, 0x098, 24,
-+ 1, 31, 0x1c4, 8),
-+ /* CLK_CFG_10 */
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_SBUS_1_SEL, "sgm_sbus_1_sel", usxgmii_sbus_0_parents,
-+ 0x0a0, 0x0a4, 0x0a8, 0, 1, 7, 0x1C4, 9, CLK_IS_CRITICAL),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_XFI_PHY_0_XTAL_SEL, "xfi_phy_0_xtal_sel", sspxtp_parents,
-+ 0x0a0, 0x0a4, 0x0a8, 8, 1, 15, 0x1C4, 10),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_XFI_PHY_1_XTAL_SEL, "xfi_phy_1_xtal_sel", sspxtp_parents,
-+ 0x0a0, 0x0a4, 0x0a8, 16, 1, 23, 0x1C4, 11),
-+ /* CLK_CFG_11 */
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAXI_SEL, "sysaxi_sel", axi_infra_parents, 0x0a0,
-+ 0x0a4, 0x0a8, 24, 1, 31, 0x1C4, 12, CLK_IS_CRITICAL),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x0b0, 0x0b4,
-+ 0x0b8, 0, 1, 7, 0x1c4, 13, CLK_IS_CRITICAL),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_REFCK_50M_SEL, "eth_refck_50m_sel", eth_refck_50m_parents,
-+ 0x0b0, 0x0b4, 0x0b8, 8, 1, 15, 0x1C4, 14),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_SYS_200M_SEL, "eth_sys_200m_sel", eth_sys_200m_parents,
-+ 0x0b0, 0x0b4, 0x0b8, 16, 1, 23, 0x1C4, 15),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_SYS_SEL, "eth_sys_sel", pcie_mbist_250m_parents, 0x0b0,
-+ 0x0b4, 0x0b8, 24, 1, 31, 0x1C4, 16),
-+ /* CLK_CFG_12 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_XGMII_SEL, "eth_xgmii_sel", eth_xgmii_parents, 0x0c0,
-+ 0x0c4, 0x0c8, 0, 2, 7, 0x1C4, 17),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_BUS_TOPS_SEL, "bus_tops_sel", bus_tops_parents, 0x0c0, 0x0c4,
-+ 0x0c8, 8, 2, 15, 0x1C4, 18),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NPU_TOPS_SEL, "npu_tops_sel", npu_tops_parents, 0x0c0, 0x0c4,
-+ 0x0c8, 16, 1, 23, 0x1C4, 19),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_SEL, "dramc_sel", sspxtp_parents, 0x0c0, 0x0c4,
-+ 0x0c8, 24, 1, 31, 0x1C4, 20, CLK_IS_CRITICAL),
-+ /* CLK_CFG_13 */
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents,
-+ 0x0d0, 0x0d4, 0x0d8, 0, 2, 7, 0x1C4, 21, CLK_IS_CRITICAL),
-+ MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_INFRA_F26M_SEL, "csw_infra_f26m_sel", sspxtp_parents,
-+ 0x0d0, 0x0d4, 0x0d8, 8, 1, 15, 0x1C4, 22, CLK_IS_CRITICAL),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P0_SEL, "pextp_p0_sel", sspxtp_parents, 0x0d0, 0x0d4,
-+ 0x0d8, 16, 1, 23, 0x1C4, 23),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P1_SEL, "pextp_p1_sel", sspxtp_parents, 0x0d0, 0x0d4,
-+ 0x0d8, 24, 1, 31, 0x1C4, 24),
-+ /* CLK_CFG_14 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P2_SEL, "pextp_p2_sel", sspxtp_parents, 0x0e0, 0x0e4,
-+ 0x0e8, 0, 1, 7, 0x1C4, 25),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P3_SEL, "pextp_p3_sel", sspxtp_parents, 0x0e0, 0x0e4,
-+ 0x0e8, 8, 1, 15, 0x1C4, 26),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P0_SEL, "da_xtp_glb_p0_sel", da_xtp_glb_p0_parents,
-+ 0x0e0, 0x0e4, 0x0e8, 16, 1, 23, 0x1C4, 27),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P1_SEL, "da_xtp_glb_p1_sel", da_xtp_glb_p0_parents,
-+ 0x0e0, 0x0e4, 0x0e8, 24, 1, 31, 0x1C4, 28),
-+ /* CLK_CFG_15 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P2_SEL, "da_xtp_glb_p2_sel", da_xtp_glb_p0_parents,
-+ 0x0f0, 0x0f4, 0x0f8, 0, 1, 7, 0x1C4, 29),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P3_SEL, "da_xtp_glb_p3_sel", da_xtp_glb_p0_parents,
-+ 0x0f0, 0x0f4, 0x0f8, 8, 1, 15, 0x1C4, 30),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_CKM_SEL, "ckm_sel", sspxtp_parents, 0x0F0, 0x0f4, 0x0f8, 16, 1,
-+ 23, 0x1c8, 0),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_SEL, "da_sel", sspxtp_parents, 0x0f0, 0x0f4, 0x0f8, 24, 1,
-+ 31, 0x1C8, 1),
-+ /* CLK_CFG_16 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_SEL, "pextp_sel", sspxtp_parents, 0x0100, 0x104, 0x108,
-+ 0, 1, 7, 0x1c8, 2),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_TOPS_P2_26M_SEL, "tops_p2_26m_sel", sspxtp_parents, 0x0100,
-+ 0x104, 0x108, 8, 1, 15, 0x1C8, 3),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MCUSYS_BACKUP_625M_SEL, "mcusys_backup_625m_sel",
-+ mcusys_backup_625m_parents, 0x0100, 0x104, 0x108, 16, 1, 23, 0x1C8, 4),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SYNC_250M_SEL, "netsys_sync_250m_sel",
-+ pcie_mbist_250m_parents, 0x0100, 0x104, 0x108, 24, 1, 31, 0x1c8, 5),
-+ /* CLK_CFG_17 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_MACSEC_SEL, "macsec_sel", macsec_parents, 0x0110, 0x114, 0x118,
-+ 0, 2, 7, 0x1c8, 6),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_TOPS_400M_SEL, "netsys_tops_400m_sel",
-+ netsys_tops_400m_parents, 0x0110, 0x114, 0x118, 8, 1, 15, 0x1c8, 7),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_PPEFB_250M_SEL, "netsys_ppefb_250m_sel",
-+ pcie_mbist_250m_parents, 0x0110, 0x114, 0x118, 16, 1, 23, 0x1c8, 8),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_WARP_SEL, "netsys_warp_sel", netsys_parents, 0x0110,
-+ 0x114, 0x118, 24, 2, 31, 0x1C8, 9),
-+ /* CLK_CFG_18 */
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_MII_SEL, "eth_mii_sel", eth_mii_parents, 0x0120, 0x124,
-+ 0x128, 0, 1, 7, 0x1c8, 10),
-+ MUX_GATE_CLR_SET_UPD(CLK_TOP_NPU_SEL, "ck_npu_sel", netsys_2x_parents, 0x0120, 0x124, 0x128,
-+ 8, 2, 15, 0x1c8, 11),
-+};
-+
-+static const struct mtk_composite top_aud_divs[] = {
-+ DIV_GATE(CLK_TOP_AUD_I2S_M, "aud_i2s_m", "aud_sel", 0x0420, 0, 0x0420, 8, 8),
-+};
-+
-+static const struct mtk_clk_desc topck_desc = {
-+ .fixed_clks = top_fixed_clks,
-+ .num_fixed_clks = ARRAY_SIZE(top_fixed_clks),
-+ .factor_clks = top_divs,
-+ .num_factor_clks = ARRAY_SIZE(top_divs),
-+ .mux_clks = top_muxes,
-+ .num_mux_clks = ARRAY_SIZE(top_muxes),
-+ .composite_clks = top_aud_divs,
-+ .num_composite_clks = ARRAY_SIZE(top_aud_divs),
-+ .clk_lock = &mt7988_clk_lock,
-+};
-+
-+static const char *const mcu_bus_div_parents[] = { "top_xtal", "ccipll2_b", "net1pll_d4" };
-+
-+static const char *const mcu_arm_div_parents[] = { "top_xtal", "arm_b", "net1pll_d4" };
-+
-+static struct mtk_composite mcu_muxes[] = {
-+ /* bus_pll_divider_cfg */
-+ MUX_GATE_FLAGS(CLK_MCU_BUS_DIV_SEL, "mcu_bus_div_sel", mcu_bus_div_parents, 0x7C0, 9, 2, -1,
-+ CLK_IS_CRITICAL),
-+ /* mp2_pll_divider_cfg */
-+ MUX_GATE_FLAGS(CLK_MCU_ARM_DIV_SEL, "mcu_arm_div_sel", mcu_arm_div_parents, 0x7A8, 9, 2, -1,
-+ CLK_IS_CRITICAL),
-+};
-+
-+static const struct mtk_clk_desc mcusys_desc = {
-+ .composite_clks = mcu_muxes,
-+ .num_composite_clks = ARRAY_SIZE(mcu_muxes),
-+};
-+
-+static const struct of_device_id of_match_clk_mt7988_topckgen[] = {
-+ { .compatible = "mediatek,mt7988-topckgen", .data = &topck_desc },
-+ { .compatible = "mediatek,mt7988-mcusys", .data = &mcusys_desc },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_topckgen);
-+
-+static struct platform_driver clk_mt7988_topckgen_drv = {
-+ .probe = mtk_clk_simple_probe,
-+ .remove = mtk_clk_simple_remove,
-+ .driver = {
-+ .name = "clk-mt7988-topckgen",
-+ .of_match_table = of_match_clk_mt7988_topckgen,
-+ },
-+};
-+module_platform_driver(clk_mt7988_topckgen_drv);
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-mt7988-xfipll.c
-@@ -0,0 +1,82 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include "clk-mtk.h"
-+#include "clk-gate.h"
-+#include <dt-bindings/clock/mediatek,mt7988-clk.h>
-+
-+/* Register to control USXGMII XFI PLL analog */
-+#define XFI_PLL_ANA_GLB8 0x108
-+#define RG_XFI_PLL_ANA_SWWA 0x02283248
-+
-+static const struct mtk_gate_regs xfipll_cg_regs = {
-+ .set_ofs = 0x8,
-+ .clr_ofs = 0x8,
-+ .sta_ofs = 0x8,
-+};
-+
-+#define GATE_XFIPLL(_id, _name, _parent, _shift) \
-+ { \
-+ .id = _id, \
-+ .name = _name, \
-+ .parent_name = _parent, \
-+ .regs = &xfipll_cg_regs, \
-+ .shift = _shift, \
-+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+ }
-+
-+static const struct mtk_fixed_factor xfipll_divs[] = {
-+ FACTOR(CLK_XFIPLL_PLL, "xfipll_pll", "top_xtal", 125, 32),
-+};
-+
-+static const struct mtk_gate xfipll_clks[] = {
-+ GATE_XFIPLL(CLK_XFIPLL_PLL_EN, "xfipll_pll_en", "xfipll_pll", 31),
-+};
-+
-+static const struct mtk_clk_desc xfipll_desc = {
-+ .clks = xfipll_clks,
-+ .num_clks = ARRAY_SIZE(xfipll_clks),
-+ .factor_clks = xfipll_divs,
-+ .num_factor_clks = ARRAY_SIZE(xfipll_divs),
-+};
-+
-+static int clk_mt7988_xfipll_probe(struct platform_device *pdev)
-+{
-+ struct device_node *node = pdev->dev.of_node;
-+ void __iomem *base = of_iomap(node, 0);
-+
-+ if (!base)
-+ return -ENOMEM;
-+
-+ /* Apply software workaround for USXGMII PLL TCL issue */
-+ writel(RG_XFI_PLL_ANA_SWWA, base + XFI_PLL_ANA_GLB8);
-+ iounmap(base);
-+
-+ return mtk_clk_simple_probe(pdev);
-+};
-+
-+static const struct of_device_id of_match_clk_mt7988_xfipll[] = {
-+ { .compatible = "mediatek,mt7988-xfi-pll", .data = &xfipll_desc },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_xfipll);
-+
-+static struct platform_driver clk_mt7988_xfipll_drv = {
-+ .driver = {
-+ .name = "clk-mt7988-xfipll",
-+ .of_match_table = of_match_clk_mt7988_xfipll,
-+ },
-+ .probe = clk_mt7988_xfipll_probe,
-+ .remove = mtk_clk_simple_remove,
-+};
-+module_platform_driver(clk_mt7988_xfipll_drv);
-+
-+MODULE_DESCRIPTION("MediaTek MT7988 XFI PLL clock driver");
-+MODULE_LICENSE("GPL");
+++ /dev/null
-From 26ced94177b150710d94cf365002a09cc48950e9 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Wed, 17 Jan 2024 19:41:11 +0100
-Subject: [PATCH] clk: mediatek: add infracfg reset controller for mt7988
-
-Infracfg can also operate as reset controller, add support for it.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
----
- drivers/clk/mediatek/clk-mt7988-infracfg.c | 23 ++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
-
---- a/drivers/clk/mediatek/clk-mt7988-infracfg.c
-+++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c
-@@ -14,6 +14,10 @@
- #include "clk-gate.h"
- #include "clk-mux.h"
- #include <dt-bindings/clock/mediatek,mt7988-clk.h>
-+#include <dt-bindings/reset/mediatek,mt7988-resets.h>
-+
-+#define MT7988_INFRA_RST0_SET_OFFSET 0x70
-+#define MT7988_INFRA_RST1_SET_OFFSET 0x80
-
- static DEFINE_SPINLOCK(mt7988_clk_lock);
-
-@@ -249,12 +253,31 @@ static const struct mtk_gate infra_clks[
- GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P3, "infra_133m_pcie_ck_p3", "sysaxi_sel", 31),
- };
-
-+static u16 infra_rst_ofs[] = {
-+ MT7988_INFRA_RST0_SET_OFFSET,
-+ MT7988_INFRA_RST1_SET_OFFSET,
-+};
-+
-+static u16 infra_idx_map[] = {
-+ [MT7988_INFRA_RST0_PEXTP_MAC_SWRST] = 0 * RST_NR_PER_BANK + 6,
-+ [MT7988_INFRA_RST1_THERM_CTRL_SWRST] = 1 * RST_NR_PER_BANK + 9,
-+};
-+
-+static struct mtk_clk_rst_desc infra_rst_desc = {
-+ .version = MTK_RST_SET_CLR,
-+ .rst_bank_ofs = infra_rst_ofs,
-+ .rst_bank_nr = ARRAY_SIZE(infra_rst_ofs),
-+ .rst_idx_map = infra_idx_map,
-+ .rst_idx_map_nr = ARRAY_SIZE(infra_idx_map),
-+};
-+
- static const struct mtk_clk_desc infra_desc = {
- .clks = infra_clks,
- .num_clks = ARRAY_SIZE(infra_clks),
- .mux_clks = infra_muxes,
- .num_mux_clks = ARRAY_SIZE(infra_muxes),
- .clk_lock = &mt7988_clk_lock,
-+ .rst_desc = &infra_rst_desc,
- };
-
- static const struct of_device_id of_match_clk_mt7988_infracfg[] = {
+++ /dev/null
-From 3c810da3206f2e52c92f9f15a87f05db4bbba734 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Wed, 17 Jan 2024 19:41:10 +0100
-Subject: [PATCH] dt-bindings: reset: mediatek: add MT7988 reset IDs
-
-Add reset constants for using as index in driver and dts.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
----
- include/dt-bindings/reset/mediatek,mt7988-resets.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/include/dt-bindings/reset/mediatek,mt7988-resets.h
-+++ b/include/dt-bindings/reset/mediatek,mt7988-resets.h
-@@ -10,4 +10,10 @@
- /* ETHWARP resets */
- #define MT7988_ETHWARP_RST_SWITCH 0
-
-+/* INFRA resets */
-+#define MT7988_INFRA_RST0_PEXTP_MAC_SWRST 0
-+#define MT7988_INFRA_RST1_THERM_CTRL_SWRST 1
-+
-+
- #endif /* _DT_BINDINGS_RESET_CONTROLLER_MT7988 */
-+
+++ /dev/null
-From 137c9e08e5e542d58aa606b0bb4f0990117309a0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 20 Nov 2023 18:22:31 +0000
-Subject: [PATCH] watchdog: mediatek: mt7988: add wdt support
-
-Add support for watchdog and reset generator unit of the MediaTek
-MT7988 SoC.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Guenter Roeck <linux@roeck-us.net>
-Link: https://lore.kernel.org/r/c0cf5f701801cce60470853fa15f1d9dced78c4f.1700504385.git.daniel@makrotopia.org
-Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
----
- drivers/watchdog/mtk_wdt.c | 42 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 42 insertions(+)
-
---- a/drivers/watchdog/mtk_wdt.c
-+++ b/drivers/watchdog/mtk_wdt.c
-@@ -56,9 +56,13 @@
- #define WDT_SWSYSRST 0x18U
- #define WDT_SWSYS_RST_KEY 0x88000000
-
-+#define WDT_SWSYSRST_EN 0xfc
-+
- #define DRV_NAME "mtk-wdt"
- #define DRV_VERSION "1.0"
-
-+#define MT7988_TOPRGU_SW_RST_NUM 24
-+
- static bool nowayout = WATCHDOG_NOWAYOUT;
- static unsigned int timeout;
-
-@@ -68,10 +72,12 @@ struct mtk_wdt_dev {
- spinlock_t lock; /* protects WDT_SWSYSRST reg */
- struct reset_controller_dev rcdev;
- bool disable_wdt_extrst;
-+ bool has_swsysrst_en;
- };
-
- struct mtk_wdt_data {
- int toprgu_sw_rst_num;
-+ bool has_swsysrst_en;
- };
-
- static const struct mtk_wdt_data mt2712_data = {
-@@ -82,6 +88,11 @@ static const struct mtk_wdt_data mt7986_
- .toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM,
- };
-
-+static const struct mtk_wdt_data mt7988_data = {
-+ .toprgu_sw_rst_num = MT7988_TOPRGU_SW_RST_NUM,
-+ .has_swsysrst_en = true,
-+};
-+
- static const struct mtk_wdt_data mt8183_data = {
- .toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM,
- };
-@@ -98,6 +109,28 @@ static const struct mtk_wdt_data mt8195_
- .toprgu_sw_rst_num = MT8195_TOPRGU_SW_RST_NUM,
- };
-
-+/**
-+ * toprgu_reset_sw_en_unlocked() - enable/disable software control for reset bit
-+ * @data: Pointer to instance of driver data.
-+ * @id: Bit number identifying the reset to be enabled or disabled.
-+ * @enable: If true, enable software control for that bit, disable otherwise.
-+ *
-+ * Context: The caller must hold lock of struct mtk_wdt_dev.
-+ */
-+static void toprgu_reset_sw_en_unlocked(struct mtk_wdt_dev *data,
-+ unsigned long id, bool enable)
-+{
-+ u32 tmp;
-+
-+ tmp = readl(data->wdt_base + WDT_SWSYSRST_EN);
-+ if (enable)
-+ tmp |= BIT(id);
-+ else
-+ tmp &= ~BIT(id);
-+
-+ writel(tmp, data->wdt_base + WDT_SWSYSRST_EN);
-+}
-+
- static int toprgu_reset_update(struct reset_controller_dev *rcdev,
- unsigned long id, bool assert)
- {
-@@ -108,6 +141,9 @@ static int toprgu_reset_update(struct re
-
- spin_lock_irqsave(&data->lock, flags);
-
-+ if (assert && data->has_swsysrst_en)
-+ toprgu_reset_sw_en_unlocked(data, id, true);
-+
- tmp = readl(data->wdt_base + WDT_SWSYSRST);
- if (assert)
- tmp |= BIT(id);
-@@ -116,6 +152,9 @@ static int toprgu_reset_update(struct re
- tmp |= WDT_SWSYS_RST_KEY;
- writel(tmp, data->wdt_base + WDT_SWSYSRST);
-
-+ if (!assert && data->has_swsysrst_en)
-+ toprgu_reset_sw_en_unlocked(data, id, false);
-+
- spin_unlock_irqrestore(&data->lock, flags);
-
- return 0;
-@@ -393,6 +432,8 @@ static int mtk_wdt_probe(struct platform
- wdt_data->toprgu_sw_rst_num);
- if (err)
- return err;
-+
-+ mtk_wdt->has_swsysrst_en = wdt_data->has_swsysrst_en;
- }
-
- mtk_wdt->disable_wdt_extrst =
-@@ -427,6 +468,7 @@ static const struct of_device_id mtk_wdt
- { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
- { .compatible = "mediatek,mt6589-wdt" },
- { .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
-+ { .compatible = "mediatek,mt7988-wdt", .data = &mt7988_data },
- { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
- { .compatible = "mediatek,mt8186-wdt", .data = &mt8186_data },
- { .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
+++ /dev/null
-From c202f510bbaa34ab5d65a69a61e0e72761374b17 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 11 Mar 2024 17:14:19 +0000
-Subject: [PATCH] clk: mediatek: mt7988-infracfg: fix clocks for 2nd PCIe port
-
-Due to what seems to be an undocumented oddity in MediaTek's MT7988
-SoC design the CLK_INFRA_PCIE_PERI_26M_CK_P2 clock requires
-CLK_INFRA_PCIE_PERI_26M_CK_P3 to be enabled.
-
-This currently leads to PCIe port 2 not working in Linux.
-
-Reflect the apparent relationship in the clk driver to make sure PCIe
-port 2 of the MT7988 SoC works.
-
-Suggested-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/clk/mediatek/clk-mt7988-infracfg.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/mediatek/clk-mt7988-infracfg.c
-+++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c
-@@ -156,7 +156,7 @@ static const struct mtk_gate infra_clks[
- GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P1, "infra_pcie_peri_ck_26m_ck_p1",
- "csw_infra_f26m_sel", 8),
- GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P2, "infra_pcie_peri_ck_26m_ck_p2",
-- "csw_infra_f26m_sel", 9),
-+ "infra_pcie_peri_ck_26m_ck_p3", 9),
- GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P3, "infra_pcie_peri_ck_26m_ck_p3",
- "csw_infra_f26m_sel", 10),
- /* INFRA1 */
+++ /dev/null
-From patchwork Wed Jan 17 12:42:33 2024
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Jean Thomas <jean.thomas@wifirst.fr>
-X-Patchwork-Id: 13521682
-Return-Path:
- <linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org>
-From: Jean Thomas <jean.thomas@wifirst.fr>
-To: sean.wang@kernel.org,
- linus.walleij@linaro.org,
- matthias.bgg@gmail.com,
- angelogioacchino.delregno@collabora.com,
- linux-mediatek@lists.infradead.org,
- linux-gpio@vger.kernel.org,
- linux-kernel@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org
-Cc: Jean Thomas <jean.thomas@wifirst.fr>
-Subject: [PATCH 1/2] pinctrl: mediatek: mt7981: add additional uart group
-Date: Wed, 17 Jan 2024 13:42:33 +0100
-Message-Id: <20240117124234.3137050-1-jean.thomas@wifirst.fr>
-MIME-Version: 1.0
-List-Id: <linux-mediatek.lists.infradead.org>
-
-Add uart1_3 (pins 26, 27) group to the pinctrl driver for the
-MediaTek MT7981 SoC.
-
-Signed-off-by: Jean Thomas <jean.thomas@wifirst.fr>
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/pinctrl/mediatek/pinctrl-mt7981.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
-@@ -737,6 +737,9 @@ static int mt7981_uart1_1_funcs[] = { 2,
- static int mt7981_uart1_2_pins[] = { 9, 10, };
- static int mt7981_uart1_2_funcs[] = { 2, 2, };
-
-+static int mt7981_uart1_3_pins[] = { 26, 27, };
-+static int mt7981_uart1_3_funcs[] = { 2, 2, };
-+
- /* UART2 */
- static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, };
- static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, };
-@@ -871,6 +874,8 @@ static const struct group_desc mt7981_gr
- PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1),
- /* @GPIO(9,10): UART1(2) */
- PINCTRL_PIN_GROUP("uart1_2", mt7981_uart1_2),
-+ /* @GPIO(26,27): UART1(2) */
-+ PINCTRL_PIN_GROUP("uart1_3", mt7981_uart1_3),
- /* @GPIO(22,25): UART1(3) */
- PINCTRL_PIN_GROUP("uart2_1", mt7981_uart2_1),
- /* @GPIO(22,24) PTA_EXT(4) */
-@@ -933,7 +938,7 @@ static const struct group_desc mt7981_gr
- static const char *mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", "wm_aice1_1",
- "wa_aice3", "wm_aice1_2", };
- static const char *mt7981_uart_groups[] = { "net_wo0_uart_txd_0", "net_wo0_uart_txd_1",
-- "net_wo0_uart_txd_2", "uart0", "uart1_0", "uart1_1", "uart1_2", "uart2_0",
-+ "net_wo0_uart_txd_2", "uart0", "uart1_0", "uart1_1", "uart1_2", "uart1_3", "uart2_0",
- "uart2_0_tx_rx", "uart2_1", "wm_uart_0", "wm_aurt_1", "wm_aurt_2", };
- static const char *mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", };
- static const char *mt7981_wdt_groups[] = { "watchdog", "watchdog1", };
+++ /dev/null
-From patchwork Wed Jan 17 14:55:47 2024
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Jean Thomas <jean.thomas@wifirst.fr>
-X-Patchwork-Id: 13521855
-Return-Path:
- <linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org>
-From: Jean Thomas <jean.thomas@wifirst.fr>
-To: sean.wang@kernel.org,
- linus.walleij@linaro.org,
- matthias.bgg@gmail.com,
- angelogioacchino.delregno@collabora.com,
- linux-mediatek@lists.infradead.org,
- linux-gpio@vger.kernel.org,
- linux-kernel@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org
-Cc: Jean Thomas <jean.thomas@wifirst.fr>,
- Daniel Golle <daniel@makrotopia.org>
-Subject: [PATCH v2 2/2] pinctrl: mediatek: mt7981: add additional emmc groups
-Date: Wed, 17 Jan 2024 15:55:47 +0100
-Message-Id: <20240117145547.3354242-1-jean.thomas@wifirst.fr>
-List-Id: <linux-mediatek.lists.infradead.org>
-
-Add new emmc groups in the pinctrl driver for the
-MediaTek MT7981 SoC:
-* emmc reset, with pin 15.
-* emmc 4-bit bus-width, with pins 16 to 19, and 24 to 25.
-* emmc 8-bit bus-width, with pins 16 to 25.
-
-The existing emmc_45 group is kept for legacy reasons, even
-if this is the union of emmc_reset and emmc_8 groups.
-
-Signed-off-by: Jean Thomas <jean.thomas@wifirst.fr>
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/pinctrl/mediatek/pinctrl-mt7981.c | 17 ++++++++++++++++-
- 1 file changed, 16 insertions(+), 1 deletion(-)
-
---
-2.39.2
-
---- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
-@@ -700,6 +700,15 @@ static int mt7981_drv_vbus_pins[] = { 14
- static int mt7981_drv_vbus_funcs[] = { 1, };
-
- /* EMMC */
-+static int mt7981_emmc_reset_pins[] = { 15, };
-+static int mt7981_emmc_reset_funcs[] = { 2, };
-+
-+static int mt7981_emmc_4_pins[] = { 16, 17, 18, 19, 24, 25, };
-+static int mt7981_emmc_4_funcs[] = { 2, 2, 2, 2, 2, 2, };
-+
-+static int mt7981_emmc_8_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, };
-+static int mt7981_emmc_8_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
-+
- static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, };
- static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
-
-@@ -854,6 +863,12 @@ static const struct group_desc mt7981_gr
- PINCTRL_PIN_GROUP("udi", mt7981_udi),
- /* @GPIO(14) DRV_VBUS(1) */
- PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus),
-+ /* @GPIO(15): EMMC_RSTB(2) */
-+ PINCTRL_PIN_GROUP("emmc_reset", mt7981_emmc_reset),
-+ /* @GPIO(16,17,18,19,24,25): EMMC_DATx, EMMC_CLK, EMMC_CMD */
-+ PINCTRL_PIN_GROUP("emmc_4", mt7981_emmc_4),
-+ /* @GPIO(16,17,18,19,20,21,22,23,24,25): EMMC_DATx, EMMC_CLK, EMMC_CMD */
-+ PINCTRL_PIN_GROUP("emmc_8", mt7981_emmc_8),
- /* @GPIO(15,25): EMMC(2) */
- PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45),
- /* @GPIO(16,21): SNFI(3) */
-@@ -957,7 +972,7 @@ static const char *mt7981_i2c_groups[] =
- static const char *mt7981_pcm_groups[] = { "pcm", };
- static const char *mt7981_udi_groups[] = { "udi", };
- static const char *mt7981_usb_groups[] = { "drv_vbus", };
--static const char *mt7981_flash_groups[] = { "emmc_45", "snfi", };
-+static const char *mt7981_flash_groups[] = { "emmc_reset", "emmc_4", "emmc_8", "emmc_45", "snfi", };
- static const char *mt7981_ethernet_groups[] = { "smi_mdc_mdio", "gbe_ext_mdc_mdio",
- "wf0_mode1", "wf0_mode3", "mt7531_int", };
- static const char *mt7981_ant_groups[] = { "ant_sel", };
+++ /dev/null
-From 24e961b93d292d0dd6380213d22a071a99ea787d Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Tue, 25 Oct 2022 15:29:53 +0200
-Subject: [PATCH 1/6] mmc: mediatek: add support for MT7986 SoC
-
-Adding mt7986 own characteristics and of_device_id to have support
-of MT7986 SoC.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221025132953.81286-7-linux@fw-web.de
-Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
----
- drivers/mmc/host/mtk-sd.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/drivers/mmc/host/mtk-sd.c
-+++ b/drivers/mmc/host/mtk-sd.c
-@@ -552,6 +552,19 @@ static const struct mtk_mmc_compatible m
- .support_64g = false,
- };
-
-+static const struct mtk_mmc_compatible mt7986_compat = {
-+ .clk_div_bits = 12,
-+ .recheck_sdio_irq = true,
-+ .hs400_tune = false,
-+ .pad_tune_reg = MSDC_PAD_TUNE0,
-+ .async_fifo = true,
-+ .data_tune = true,
-+ .busy_check = true,
-+ .stop_clk_fix = true,
-+ .enhance_rx = true,
-+ .support_64g = true,
-+};
-+
- static const struct mtk_mmc_compatible mt8135_compat = {
- .clk_div_bits = 8,
- .recheck_sdio_irq = true,
-@@ -609,6 +622,7 @@ static const struct of_device_id msdc_of
- { .compatible = "mediatek,mt6795-mmc", .data = &mt6795_compat},
- { .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat},
- { .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat},
-+ { .compatible = "mediatek,mt7986-mmc", .data = &mt7986_compat},
- { .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat},
- { .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat},
- { .compatible = "mediatek,mt8183-mmc", .data = &mt8183_compat},
+++ /dev/null
-From 7b438d0377fbd520b475a68bdd9de1692393f22d Mon Sep 17 00:00:00 2001
-From: Mengqi Zhang <mengqi.zhang@mediatek.com>
-Date: Sun, 6 Nov 2022 11:39:24 +0800
-Subject: [PATCH 2/6] mmc: mtk-sd: add Inline Crypto Engine clock control
-
-Add crypto clock control and ungate it before CQHCI init.
-
-Signed-off-by: Mengqi Zhang <mengqi.zhang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221106033924.9854-2-mengqi.zhang@mediatek.com
-Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
----
- drivers/mmc/host/mtk-sd.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
---- a/drivers/mmc/host/mtk-sd.c
-+++ b/drivers/mmc/host/mtk-sd.c
-@@ -452,6 +452,7 @@ struct msdc_host {
- struct clk *bus_clk; /* bus clock which used to access register */
- struct clk *src_clk_cg; /* msdc source clock control gate */
- struct clk *sys_clk_cg; /* msdc subsys clock control gate */
-+ struct clk *crypto_clk; /* msdc crypto clock control gate */
- struct clk_bulk_data bulk_clks[MSDC_NR_CLOCKS];
- u32 mclk; /* mmc subsystem clock frequency */
- u32 src_clk_freq; /* source clock frequency */
-@@ -840,6 +841,7 @@ static void msdc_set_busy_timeout(struct
- static void msdc_gate_clock(struct msdc_host *host)
- {
- clk_bulk_disable_unprepare(MSDC_NR_CLOCKS, host->bulk_clks);
-+ clk_disable_unprepare(host->crypto_clk);
- clk_disable_unprepare(host->src_clk_cg);
- clk_disable_unprepare(host->src_clk);
- clk_disable_unprepare(host->bus_clk);
-@@ -855,6 +857,7 @@ static int msdc_ungate_clock(struct msdc
- clk_prepare_enable(host->bus_clk);
- clk_prepare_enable(host->src_clk);
- clk_prepare_enable(host->src_clk_cg);
-+ clk_prepare_enable(host->crypto_clk);
- ret = clk_bulk_prepare_enable(MSDC_NR_CLOCKS, host->bulk_clks);
- if (ret) {
- dev_err(host->dev, "Cannot enable pclk/axi/ahb clock gates\n");
-@@ -2670,6 +2673,15 @@ static int msdc_drv_probe(struct platfor
- goto host_free;
- }
-
-+ /* only eMMC has crypto property */
-+ if (!(mmc->caps2 & MMC_CAP2_NO_MMC)) {
-+ host->crypto_clk = devm_clk_get_optional(&pdev->dev, "crypto");
-+ if (IS_ERR(host->crypto_clk))
-+ host->crypto_clk = NULL;
-+ else
-+ mmc->caps2 |= MMC_CAP2_CRYPTO;
-+ }
-+
- host->irq = platform_get_irq(pdev, 0);
- if (host->irq < 0) {
- ret = host->irq;
+++ /dev/null
-From 4b323f02b6e8df1b04292635ef829e7f723bf50e Mon Sep 17 00:00:00 2001
-From: Yu Zhe <yuzhe@nfschina.com>
-Date: Thu, 10 Nov 2022 15:28:19 +0800
-Subject: [PATCH 3/6] mmc: mtk-sd: fix two spelling mistakes in comment
-
-spelling mistake fix : "alreay" -> "already"
- "checksume" -> "checksum"
-
-Signed-off-by: Yu Zhe <yuzhe@nfschina.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221110072819.11530-1-yuzhe@nfschina.com
-Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
----
- drivers/mmc/host/mtk-sd.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/mmc/host/mtk-sd.c
-+++ b/drivers/mmc/host/mtk-sd.c
-@@ -750,7 +750,7 @@ static inline void msdc_dma_setup(struct
- else
- bd[j].bd_info &= ~BDMA_DESC_EOL;
-
-- /* checksume need to clear first */
-+ /* checksum need to clear first */
- bd[j].bd_info &= ~BDMA_DESC_CHECKSUM;
- bd[j].bd_info |= msdc_dma_calcs((u8 *)(&bd[j]), 16) << 8;
- }
-@@ -1229,7 +1229,7 @@ static bool msdc_cmd_done(struct msdc_ho
- !host->hs400_tuning))
- /*
- * should not clear fifo/interrupt as the tune data
-- * may have alreay come when cmd19/cmd21 gets response
-+ * may have already come when cmd19/cmd21 gets response
- * CRC error.
- */
- msdc_reset_hw(host);
+++ /dev/null
-From b98e7e8daf0ebab9dcc36812378a71e1be0b5089 Mon Sep 17 00:00:00 2001
-From: ChanWoo Lee <cw9316.lee@samsung.com>
-Date: Thu, 24 Nov 2022 17:00:31 +0900
-Subject: [PATCH 4/6] mmc: Avoid open coding by using mmc_op_tuning()
-
-Replace code with the already defined function. No functional changes.
-
-Signed-off-by: ChanWoo Lee <cw9316.lee@samsung.com>
-Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
-Link: https://lore.kernel.org/r/20221124080031.14690-1-cw9316.lee@samsung.com
-Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
----
- drivers/mmc/host/mtk-sd.c | 8 ++------
- 1 file changed, 2 insertions(+), 6 deletions(-)
-
---- a/drivers/mmc/host/mtk-sd.c
-+++ b/drivers/mmc/host/mtk-sd.c
-@@ -1224,9 +1224,7 @@ static bool msdc_cmd_done(struct msdc_ho
-
- if (!sbc_error && !(events & MSDC_INT_CMDRDY)) {
- if (events & MSDC_INT_CMDTMO ||
-- (cmd->opcode != MMC_SEND_TUNING_BLOCK &&
-- cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
-- !host->hs400_tuning))
-+ (!mmc_op_tuning(cmd->opcode) && !host->hs400_tuning))
- /*
- * should not clear fifo/interrupt as the tune data
- * may have already come when cmd19/cmd21 gets response
-@@ -1320,9 +1318,7 @@ static void msdc_cmd_next(struct msdc_ho
- {
- if ((cmd->error &&
- !(cmd->error == -EILSEQ &&
-- (cmd->opcode == MMC_SEND_TUNING_BLOCK ||
-- cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200 ||
-- host->hs400_tuning))) ||
-+ (mmc_op_tuning(cmd->opcode) || host->hs400_tuning))) ||
- (mrq->sbc && mrq->sbc->error))
- msdc_request_done(host, mrq);
- else if (cmd == mrq->sbc)
+++ /dev/null
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -19,6 +19,7 @@
- #include <linux/string.h>
- #include <linux/spi/spi.h>
- #include <linux/spi/spi-mem.h>
-+#include <linux/mtd/mtk_bmt.h>
-
- static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
- {
-@@ -1344,6 +1345,7 @@ static int spinand_probe(struct spi_mem
- if (ret)
- return ret;
-
-+ mtk_bmt_attach(mtd);
- ret = mtd_device_register(mtd, NULL, 0);
- if (ret)
- goto err_spinand_cleanup;
-@@ -1351,6 +1353,7 @@ static int spinand_probe(struct spi_mem
- return 0;
-
- err_spinand_cleanup:
-+ mtk_bmt_detach(mtd);
- spinand_cleanup(spinand);
-
- return ret;
-@@ -1369,6 +1372,7 @@ static int spinand_remove(struct spi_mem
- if (ret)
- return ret;
-
-+ mtk_bmt_detach(mtd);
- spinand_cleanup(spinand);
-
- return 0;
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
-@@ -549,6 +549,7 @@
- spi-tx-bus-width = <4>;
- spi-rx-bus-width = <4>;
- nand-ecc-engine = <&snfi>;
-+ mediatek,bmt-v2;
-
- partitions {
- compatible = "fixed-partitions";
+++ /dev/null
-From 5f49a5c9b16330e0df8f639310e4715dcad71947 Mon Sep 17 00:00:00 2001
-From: Davide Fioravanti <pantanastyle@gmail.com>
-Date: Fri, 8 Jan 2021 15:35:24 +0100
-Subject: [PATCH] mtd: spinand: Add support for the Fidelix FM35X1GA
-
-Datasheet: http://www.hobos.com.cn/upload/datasheet/DS35X1GAXXX_100_rev00.pdf
-
-Signed-off-by: Davide Fioravanti <pantanastyle@gmail.com>
----
- drivers/mtd/nand/spi/Makefile | 2 +-
- drivers/mtd/nand/spi/core.c | 1 +
- drivers/mtd/nand/spi/fidelix.c | 76 ++++++++++++++++++++++++++++++++++
- include/linux/mtd/spinand.h | 1 +
- 4 files changed, 79 insertions(+), 1 deletion(-)
- create mode 100644 drivers/mtd/nand/spi/fidelix.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 esmt.o etron.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 fidelix.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
-@@ -940,6 +940,7 @@ static const struct nand_ops spinand_ops
- static const struct spinand_manufacturer *spinand_manufacturers[] = {
- &ato_spinand_manufacturer,
- &esmt_c8_spinand_manufacturer,
-+ &fidelix_spinand_manufacturer,
- &etron_spinand_manufacturer,
- &gigadevice_spinand_manufacturer,
- ¯onix_spinand_manufacturer,
---- /dev/null
-+++ b/drivers/mtd/nand/spi/fidelix.c
-@@ -0,0 +1,76 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (c) 2020 Davide Fioravanti <pantanastyle@gmail.com>
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mtd/spinand.h>
-+
-+#define SPINAND_MFR_FIDELIX 0xE5
-+#define FIDELIX_ECCSR_MASK 0x0F
-+
-+static SPINAND_OP_VARIANTS(read_cache_variants,
-+ SPINAND_PAGE_READ_FROM_CACHE_X4_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 fm35x1ga_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 fm35x1ga_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 fm35x1ga_ooblayout = {
-+ .ecc = fm35x1ga_ooblayout_ecc,
-+ .free = fm35x1ga_ooblayout_free,
-+};
-+
-+static const struct spinand_info fidelix_spinand_table[] = {
-+ SPINAND_INFO("FM35X1GA",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71),
-+ 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),
-+ SPINAND_HAS_QE_BIT,
-+ SPINAND_ECCINFO(&fm35x1ga_ooblayout, NULL)),
-+};
-+
-+static const struct spinand_manufacturer_ops fidelix_spinand_manuf_ops = {
-+};
-+
-+const struct spinand_manufacturer fidelix_spinand_manufacturer = {
-+ .id = SPINAND_MFR_FIDELIX,
-+ .name = "Fidelix",
-+ .chips = fidelix_spinand_table,
-+ .nchips = ARRAY_SIZE(fidelix_spinand_table),
-+ .ops = &fidelix_spinand_manuf_ops,
-+};
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -263,6 +263,7 @@ struct spinand_manufacturer {
- 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 fidelix_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;
+++ /dev/null
-From patchwork Fri Apr 19 16:59: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: 13636668
-Return-Path:
- <linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org>
-Date: Fri, 19 Apr 2024 17:59:07 +0100
-From: Daniel Golle <daniel@makrotopia.org>
-To: "Rafael J. Wysocki" <rafael@kernel.org>,
- Viresh Kumar <viresh.kumar@linaro.org>,
- Matthias Brugger <matthias.bgg@gmail.com>,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
- linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org,
- linux-arm-kernel@lists.infradead.org,
- linux-mediatek@lists.infradead.org
-Subject: [PATCH] cpufreq: mediatek: Add support for MT7988A
-Message-ID:
- <acf4fb446aacfbf6ce7b6e94bf3aad303e0ad4d1.1713545923.git.daniel@makrotopia.org>
-Content-Disposition: inline
-List-Id: <linux-mediatek.lists.infradead.org>
-
-From: Sam Shih <sam.shih@mediatek.com>
-
-This add cpufreq support for mediatek MT7988A SoC.
-
-The platform data of MT7988A is different from previous MediaTek SoCs,
-so we add a new compatible and platform data for it.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
----
- drivers/cpufreq/mediatek-cpufreq.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/cpufreq/mediatek-cpufreq.c
-+++ b/drivers/cpufreq/mediatek-cpufreq.c
-@@ -709,6 +709,15 @@ static const struct mtk_cpufreq_platform
- .ccifreq_supported = false,
- };
-
-+static const struct mtk_cpufreq_platform_data mt7988_platform_data = {
-+ .min_volt_shift = 100000,
-+ .max_volt_shift = 200000,
-+ .proc_max_volt = 900000,
-+ .sram_min_volt = 0,
-+ .sram_max_volt = 1150000,
-+ .ccifreq_supported = true,
-+};
-+
- static const struct mtk_cpufreq_platform_data mt8183_platform_data = {
- .min_volt_shift = 100000,
- .max_volt_shift = 200000,
-@@ -742,6 +751,7 @@ 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,mt8167", .data = &mt8516_platform_data },
- { .compatible = "mediatek,mt817x", .data = &mt2701_platform_data },
- { .compatible = "mediatek,mt8173", .data = &mt2701_platform_data },
+++ /dev/null
---- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
-@@ -601,6 +601,30 @@ out:
- return err;
- }
-
-+static int mtk_pinconf_bias_set_pd(struct mtk_pinctrl *hw,
-+ const struct mtk_pin_desc *desc,
-+ u32 pullup, u32 arg)
-+{
-+ int err, pd;
-+
-+ if (arg == MTK_DISABLE)
-+ pd = 0;
-+ else if ((arg == MTK_ENABLE) && pullup)
-+ pd = 0;
-+ else if ((arg == MTK_ENABLE) && !pullup)
-+ pd = 1;
-+ else {
-+ err = -EINVAL;
-+ goto out;
-+ }
-+
-+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
-+
-+out:
-+ return err;
-+
-+}
-+
- 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;
- }
-
-+ if (try_all_type & MTK_PULL_PD_TYPE) {
-+ err = mtk_pinconf_bias_set_pd(hw, desc, pullup, arg);
-+ if (!err)
-+ return err;
-+ }
-+
- 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:
- return err;
- }
-
-+static int mtk_pinconf_bias_get_pd(struct mtk_pinctrl *hw,
-+ const struct mtk_pin_desc *desc,
-+ u32 *pullup, u32 *enable)
-+{
-+ int err, pd;
-+
-+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
-+ if (err)
-+ goto out;
-+
-+ if (pd == 0) {
-+ *pullup = 0;
-+ *enable = MTK_DISABLE;
-+ } else if (pd == 1) {
-+ *pullup = 0;
-+ *enable = MTK_ENABLE;
-+ } else
-+ err = -EINVAL;
-+
-+out:
-+ return err;
-+}
-+
- 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;
- }
-+
-+ 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);
---- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
-+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
-@@ -24,6 +24,7 @@
- * turned on/off itself. But it can't be selected pull up/down
- */
- #define MTK_PULL_RSEL_TYPE BIT(3)
-+#define MTK_PULL_PD_TYPE BIT(4)
- /* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by
- * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE.
- */
+++ /dev/null
---- a/drivers/crypto/inside-secure/safexcel.c
-+++ b/drivers/crypto/inside-secure/safexcel.c
-@@ -600,6 +600,14 @@ static int safexcel_hw_init(struct safex
- val |= EIP197_MST_CTRL_TX_MAX_CMD(5);
- writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
- }
-+ /*
-+ * Set maximum number of TX commands to 2^4 = 16 for EIP97 HW2.1/HW2.3
-+ */
-+ else {
-+ val = 0;
-+ val |= EIP97_MST_CTRL_TX_MAX_CMD(4);
-+ writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
-+ }
-
- /* Configure wr/rd cache values */
- writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) |
---- a/drivers/crypto/inside-secure/safexcel.h
-+++ b/drivers/crypto/inside-secure/safexcel.h
-@@ -315,6 +315,7 @@
- #define EIP197_MST_CTRL_RD_CACHE(n) (((n) & 0xf) << 0)
- #define EIP197_MST_CTRL_WD_CACHE(n) (((n) & 0xf) << 4)
- #define EIP197_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 20)
-+#define EIP97_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 4)
- #define EIP197_MST_CTRL_BYTE_SWAP BIT(24)
- #define EIP197_MST_CTRL_NO_BYTE_SWAP BIT(25)
- #define EIP197_MST_CTRL_BYTE_SWAP_BITS GENMASK(25, 24)
+++ /dev/null
---- a/drivers/crypto/inside-secure/safexcel.h
-+++ b/drivers/crypto/inside-secure/safexcel.h
-@@ -737,6 +737,9 @@ enum safexcel_eip_version {
- /* Priority we use for advertising our algorithms */
- #define SAFEXCEL_CRA_PRIORITY 300
-
-+/* System cache line size */
-+#define SYSTEM_CACHELINE_SIZE 64
-+
- /* SM3 digest result for zero length message */
- #define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \
- "\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \
---- a/drivers/crypto/inside-secure/safexcel_hash.c
-+++ b/drivers/crypto/inside-secure/safexcel_hash.c
-@@ -55,9 +55,9 @@ struct safexcel_ahash_req {
- u8 block_sz; /* block size, only set once */
- u8 digest_sz; /* output digest size, only set once */
- __le32 state[SHA3_512_BLOCK_SIZE /
-- sizeof(__le32)] __aligned(sizeof(__le32));
-+ sizeof(__le32)] __aligned(SYSTEM_CACHELINE_SIZE);
-
-- u64 len;
-+ u64 len __aligned(SYSTEM_CACHELINE_SIZE);
- u64 processed;
-
- u8 cache[HASH_CACHE_SIZE] __aligned(sizeof(u32));
+++ /dev/null
-From f1da27b7c4191f78ed81d3dabf64c769f896296c Mon Sep 17 00:00:00 2001
-From: "Mingming.Su" <Mingming.Su@mediatek.com>
-Date: Sat, 8 Oct 2022 18:45:53 +0200
-Subject: [PATCH] hwrng: mtk - add mt7986 support
-
-1. Add trng compatible name for MT7986
-2. Fix mtk_rng_wait_ready() function
-
-Signed-off-by: Mingming.Su <Mingming.Su@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
- drivers/char/hw_random/mtk-rng.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/drivers/char/hw_random/mtk-rng.c
-+++ b/drivers/char/hw_random/mtk-rng.c
-@@ -22,7 +22,7 @@
- #define RNG_AUTOSUSPEND_TIMEOUT 100
-
- #define USEC_POLL 2
--#define TIMEOUT_POLL 20
-+#define TIMEOUT_POLL 60
-
- #define RNG_CTRL 0x00
- #define RNG_EN BIT(0)
-@@ -77,7 +77,7 @@ static bool mtk_rng_wait_ready(struct hw
- readl_poll_timeout_atomic(priv->base + RNG_CTRL, ready,
- ready & RNG_READY, USEC_POLL,
- TIMEOUT_POLL);
-- return !!ready;
-+ return !!(ready & RNG_READY);
- }
-
- static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
-@@ -179,6 +179,7 @@ static const struct dev_pm_ops mtk_rng_p
- #endif /* CONFIG_PM */
-
- static const struct of_device_id mtk_rng_match[] = {
-+ { .compatible = "mediatek,mt7986-rng" },
- { .compatible = "mediatek,mt7623-rng" },
- {},
- };
+++ /dev/null
---- a/drivers/tty/serial/8250/8250.h
-+++ b/drivers/tty/serial/8250/8250.h
-@@ -86,6 +86,7 @@ struct serial8250_config {
- * STOP PARITY EPAR SPAR WLEN5 WLEN6
- */
- #define UART_CAP_NOTEMT BIT(18) /* UART without interrupt on TEMT available */
-+#define UART_CAP_NMOD BIT(19) /* UART doesn't do termios */
-
- #define UART_BUG_QUOT BIT(0) /* UART has buggy quot LSB */
- #define UART_BUG_TXEN BIT(1) /* UART has buggy TX IIR status */
---- a/drivers/tty/serial/8250/8250_port.c
-+++ b/drivers/tty/serial/8250/8250_port.c
-@@ -287,7 +287,7 @@ static const struct serial8250_config ua
- .tx_loadsz = 16,
- .fcr = UART_FCR_ENABLE_FIFO |
- UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
-- .flags = UART_CAP_FIFO,
-+ .flags = UART_CAP_FIFO | UART_CAP_NMOD,
- },
- [PORT_NPCM] = {
- .name = "Nuvoton 16550",
-@@ -2767,6 +2767,11 @@ serial8250_do_set_termios(struct uart_po
- unsigned long flags;
- unsigned int baud, quot, frac = 0;
-
-+ if (up->capabilities & UART_CAP_NMOD) {
-+ termios->c_cflag = 0;
-+ return;
-+ }
-+
- if (up->capabilities & UART_CAP_MINI) {
- termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR);
- if ((termios->c_cflag & CSIZE) == CS5 ||
+++ /dev/null
-From bfd3acc428085742d754a6d328d1a93ebf9451df Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:29:51 +0800
-Subject: [PATCH 1/6] drivers: spi-mt65xx: Move chip_config to driver's private
- data
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
----
- drivers/spi/spi-mt65xx.c | 29 +++++++++---------------
- include/linux/platform_data/spi-mt65xx.h | 17 --------------
- 2 files changed, 11 insertions(+), 35 deletions(-)
- delete mode 100644 include/linux/platform_data/spi-mt65xx.h
-
---- a/drivers/spi/spi-mt65xx.c
-+++ b/drivers/spi/spi-mt65xx.c
-@@ -14,7 +14,6 @@
- #include <linux/of.h>
- #include <linux/gpio/consumer.h>
- #include <linux/platform_device.h>
--#include <linux/platform_data/spi-mt65xx.h>
- #include <linux/pm_runtime.h>
- #include <linux/spi/spi.h>
- #include <linux/spi/spi-mem.h>
-@@ -171,6 +170,8 @@ struct mtk_spi {
- struct device *dev;
- dma_addr_t tx_dma;
- dma_addr_t rx_dma;
-+ u32 sample_sel;
-+ u32 get_tick_dly;
- };
-
- static const struct mtk_spi_compatible mtk_common_compat;
-@@ -216,15 +217,6 @@ static const struct mtk_spi_compatible m
- .no_need_unprepare = true,
- };
-
--/*
-- * A piece of default chip info unless the platform
-- * supplies it.
-- */
--static const struct mtk_chip_config mtk_default_chip_info = {
-- .sample_sel = 0,
-- .tick_delay = 0,
--};
--
- static const struct of_device_id mtk_spi_of_match[] = {
- { .compatible = "mediatek,spi-ipm",
- .data = (void *)&mtk_ipm_compat,
-@@ -352,7 +344,6 @@ static int mtk_spi_hw_init(struct spi_ma
- {
- u16 cpha, cpol;
- u32 reg_val;
-- struct mtk_chip_config *chip_config = spi->controller_data;
- struct mtk_spi *mdata = spi_master_get_devdata(master);
-
- cpha = spi->mode & SPI_CPHA ? 1 : 0;
-@@ -402,7 +393,7 @@ static int mtk_spi_hw_init(struct spi_ma
- else
- reg_val &= ~SPI_CMD_CS_POL;
-
-- if (chip_config->sample_sel)
-+ if (mdata->sample_sel)
- reg_val |= SPI_CMD_SAMPLE_SEL;
- else
- reg_val &= ~SPI_CMD_SAMPLE_SEL;
-@@ -429,20 +420,20 @@ static int mtk_spi_hw_init(struct spi_ma
- if (mdata->dev_comp->ipm_design) {
- reg_val = readl(mdata->base + SPI_CMD_REG);
- reg_val &= ~SPI_CMD_IPM_GET_TICKDLY_MASK;
-- reg_val |= ((chip_config->tick_delay & 0x7)
-+ reg_val |= ((mdata->get_tick_dly & 0x7)
- << SPI_CMD_IPM_GET_TICKDLY_OFFSET);
- writel(reg_val, mdata->base + SPI_CMD_REG);
- } else {
- reg_val = readl(mdata->base + SPI_CFG1_REG);
- reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK;
-- reg_val |= ((chip_config->tick_delay & 0x7)
-+ reg_val |= ((mdata->get_tick_dly & 0x7)
- << SPI_CFG1_GET_TICK_DLY_OFFSET);
- writel(reg_val, mdata->base + SPI_CFG1_REG);
- }
- } else {
- reg_val = readl(mdata->base + SPI_CFG1_REG);
- reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK_V1;
-- reg_val |= ((chip_config->tick_delay & 0x3)
-+ reg_val |= ((mdata->get_tick_dly & 0x3)
- << SPI_CFG1_GET_TICK_DLY_OFFSET_V1);
- writel(reg_val, mdata->base + SPI_CFG1_REG);
- }
-@@ -732,9 +723,6 @@ static int mtk_spi_setup(struct spi_devi
- {
- struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
-
-- if (!spi->controller_data)
-- spi->controller_data = (void *)&mtk_default_chip_info;
--
- if (mdata->dev_comp->need_pad_sel && spi->cs_gpiod)
- /* CS de-asserted, gpiolib will handle inversion */
- gpiod_direction_output(spi->cs_gpiod, 0);
-@@ -1140,6 +1128,10 @@ static int mtk_spi_probe(struct platform
- mdata = spi_master_get_devdata(master);
- mdata->dev_comp = device_get_match_data(dev);
-
-+ /* Set device configs to default first. Calibrate it later. */
-+ mdata->sample_sel = 0;
-+ mdata->get_tick_dly = 2;
-+
- if (mdata->dev_comp->enhance_timing)
- master->mode_bits |= SPI_CS_HIGH;
-
---- a/include/linux/platform_data/spi-mt65xx.h
-+++ /dev/null
-@@ -1,17 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0-only */
--/*
-- * MTK SPI bus driver definitions
-- *
-- * Copyright (c) 2015 MediaTek Inc.
-- * Author: Leilk Liu <leilk.liu@mediatek.com>
-- */
--
--#ifndef ____LINUX_PLATFORM_DATA_SPI_MTK_H
--#define ____LINUX_PLATFORM_DATA_SPI_MTK_H
--
--/* Board specific platform_data */
--struct mtk_chip_config {
-- u32 sample_sel;
-- u32 tick_delay;
--};
--#endif
+++ /dev/null
-From 2ade0172154e50c8a2bfd8634c6eff943cffea29 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:35:52 +0800
-Subject: [PATCH 2/6] drivers: spi: Add support for dynamic calibration
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
----
- drivers/spi/spi.c | 137 ++++++++++++++++++++++++++++++++++++++++
- include/linux/spi/spi.h | 42 ++++++++++++
- 2 files changed, 179 insertions(+)
-
---- a/drivers/spi/spi.c
-+++ b/drivers/spi/spi.c
-@@ -1385,6 +1385,70 @@ static int spi_transfer_wait(struct spi_
- return 0;
- }
-
-+int spi_do_calibration(struct spi_controller *ctlr, struct spi_device *spi,
-+ int (*cal_read)(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen), void *drv_priv)
-+{
-+ int datalen = ctlr->cal_rule->datalen;
-+ int addrlen = ctlr->cal_rule->addrlen;
-+ u8 *buf;
-+ int ret;
-+ int i;
-+ struct list_head *cal_head, *listptr;
-+ struct spi_cal_target *target;
-+
-+ /* Calculate calibration result */
-+ int hit_val, total_hit, origin;
-+ bool hit;
-+
-+ /* Make sure we can start calibration */
-+ if(!ctlr->cal_target || !ctlr->cal_rule || !ctlr->append_caldata)
-+ return 0;
-+
-+ buf = kzalloc(datalen * sizeof(u8), GFP_KERNEL);
-+ if(!buf)
-+ return -ENOMEM;
-+
-+ ret = ctlr->append_caldata(ctlr);
-+ if (ret)
-+ goto cal_end;
-+
-+ cal_head = ctlr->cal_target;
-+ list_for_each(listptr, cal_head) {
-+ target = list_entry(listptr, struct spi_cal_target, list);
-+
-+ hit = false;
-+ hit_val = 0;
-+ total_hit = 0;
-+ origin = *target->cal_item;
-+
-+ for(i=target->cal_min; i<=target->cal_max; i+=target->step) {
-+ *target->cal_item = i;
-+ ret = (*cal_read)(drv_priv, ctlr->cal_rule->addr, addrlen, buf, datalen);
-+ if(ret)
-+ break;
-+ dev_dbg(&spi->dev, "controller cal item value: 0x%x\n", i);
-+ if(memcmp(ctlr->cal_rule->match_data, buf, datalen * sizeof(u8)) == 0) {
-+ hit = true;
-+ hit_val += i;
-+ total_hit++;
-+ dev_dbg(&spi->dev, "golden data matches data read!\n");
-+ }
-+ }
-+ if(hit) {
-+ *target->cal_item = DIV_ROUND_CLOSEST(hit_val, total_hit);
-+ dev_info(&spi->dev, "calibration result: 0x%x", *target->cal_item);
-+ } else {
-+ *target->cal_item = origin;
-+ dev_warn(&spi->dev, "calibration failed, fallback to default: 0x%x", origin);
-+ }
-+ }
-+
-+cal_end:
-+ kfree(buf);
-+ return ret? ret: 0;
-+}
-+EXPORT_SYMBOL_GPL(spi_do_calibration);
-+
- static void _spi_transfer_delay_ns(u32 ns)
- {
- if (!ns)
-@@ -2223,6 +2287,75 @@ void spi_flush_queue(struct spi_controll
- /*-------------------------------------------------------------------------*/
-
- #if defined(CONFIG_OF)
-+static inline void alloc_cal_data(struct list_head **cal_target,
-+ struct spi_cal_rule **cal_rule, bool enable)
-+{
-+ if(enable) {
-+ *cal_target = kmalloc(sizeof(struct list_head), GFP_KERNEL);
-+ INIT_LIST_HEAD(*cal_target);
-+ *cal_rule = kmalloc(sizeof(struct spi_cal_rule), GFP_KERNEL);
-+ } else {
-+ kfree(*cal_target);
-+ kfree(*cal_rule);
-+ }
-+}
-+
-+static int of_spi_parse_cal_dt(struct spi_controller *ctlr, struct spi_device *spi,
-+ struct device_node *nc)
-+{
-+ u32 value;
-+ int rc;
-+ const char *cal_mode;
-+
-+ rc = of_property_read_bool(nc, "spi-cal-enable");
-+ if (rc)
-+ alloc_cal_data(&ctlr->cal_target, &ctlr->cal_rule, true);
-+ else
-+ return 0;
-+
-+ rc = of_property_read_string(nc, "spi-cal-mode", &cal_mode);
-+ if(!rc) {
-+ if(strcmp("read-data", cal_mode) == 0){
-+ ctlr->cal_rule->mode = SPI_CAL_READ_DATA;
-+ } else if(strcmp("read-pp", cal_mode) == 0) {
-+ ctlr->cal_rule->mode = SPI_CAL_READ_PP;
-+ return 0;
-+ } else if(strcmp("read-sfdp", cal_mode) == 0){
-+ ctlr->cal_rule->mode = SPI_CAL_READ_SFDP;
-+ return 0;
-+ }
-+ } else
-+ goto err;
-+
-+ ctlr->cal_rule->datalen = 0;
-+ rc = of_property_read_u32(nc, "spi-cal-datalen", &value);
-+ if(!rc && value > 0) {
-+ ctlr->cal_rule->datalen = value;
-+
-+ ctlr->cal_rule->match_data = kzalloc(value * sizeof(u8), GFP_KERNEL);
-+ rc = of_property_read_u8_array(nc, "spi-cal-data",
-+ ctlr->cal_rule->match_data, value);
-+ if(rc)
-+ kfree(ctlr->cal_rule->match_data);
-+ }
-+
-+ rc = of_property_read_u32(nc, "spi-cal-addrlen", &value);
-+ if(!rc && value > 0) {
-+ ctlr->cal_rule->addrlen = value;
-+
-+ ctlr->cal_rule->addr = kzalloc(value * sizeof(u32), GFP_KERNEL);
-+ rc = of_property_read_u32_array(nc, "spi-cal-addr",
-+ ctlr->cal_rule->addr, value);
-+ if(rc)
-+ kfree(ctlr->cal_rule->addr);
-+ }
-+ return 0;
-+
-+err:
-+ alloc_cal_data(&ctlr->cal_target, &ctlr->cal_rule, false);
-+ return 0;
-+}
-+
- static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
- struct device_node *nc)
- {
-@@ -2341,6 +2474,10 @@ of_register_spi_device(struct spi_contro
- if (rc)
- goto err_out;
-
-+ rc = of_spi_parse_cal_dt(ctlr, spi, nc);
-+ if (rc)
-+ goto err_out;
-+
- /* Store a pointer to the node in the device structure */
- of_node_get(nc);
- spi->dev.of_node = nc;
---- a/include/linux/spi/spi.h
-+++ b/include/linux/spi/spi.h
-@@ -318,6 +318,40 @@ struct spi_driver {
- struct device_driver driver;
- };
-
-+enum {
-+ SPI_CAL_READ_DATA = 0,
-+ SPI_CAL_READ_PP = 1, /* only for SPI-NAND */
-+ SPI_CAL_READ_SFDP = 2, /* only for SPI-NOR */
-+};
-+
-+struct nand_addr {
-+ unsigned int lun;
-+ unsigned int plane;
-+ unsigned int eraseblock;
-+ unsigned int page;
-+ unsigned int dataoffs;
-+};
-+
-+/**
-+ * Read calibration rule from device dts node.
-+ * Once calibration result matches the rule, we regard is as success.
-+ */
-+struct spi_cal_rule {
-+ int datalen;
-+ u8 *match_data;
-+ int addrlen;
-+ u32 *addr;
-+ int mode;
-+};
-+
-+struct spi_cal_target {
-+ u32 *cal_item;
-+ int cal_min; /* min of cal_item */
-+ int cal_max; /* max of cal_item */
-+ int step; /* Increase/decrease cal_item */
-+ struct list_head list;
-+};
-+
- static inline struct spi_driver *to_spi_driver(struct device_driver *drv)
- {
- return drv ? container_of(drv, struct spi_driver, driver) : NULL;
-@@ -703,6 +737,11 @@ struct spi_controller {
- void *dummy_rx;
- void *dummy_tx;
-
-+ /* For calibration */
-+ int (*append_caldata)(struct spi_controller *ctlr);
-+ struct list_head *cal_target;
-+ struct spi_cal_rule *cal_rule;
-+
- int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
-
- /*
-@@ -1510,6 +1549,9 @@ spi_register_board_info(struct spi_board
- { return 0; }
- #endif
-
-+extern int spi_do_calibration(struct spi_controller *ctlr,
-+ struct spi_device *spi, int (*cal_read)(void *, u32 *, int, u8 *, int), void *drv_priv);
-+
- /* If you're hotplugging an adapter with devices (parport, usb, etc)
- * use spi_new_device() to describe each device. You can also call
- * spi_unregister_device() to start making that device vanish, but
+++ /dev/null
-From 06640a5da2973318c06e516da16a5b579622e7c5 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:37:55 +0800
-Subject: [PATCH 3/6] drivers: spi-mem: Add spi calibration hook
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
----
- drivers/spi/spi-mem.c | 8 ++++++++
- include/linux/spi/spi-mem.h | 4 ++++
- 2 files changed, 12 insertions(+)
-
---- a/drivers/spi/spi-mem.c
-+++ b/drivers/spi/spi-mem.c
-@@ -419,6 +419,14 @@ int spi_mem_exec_op(struct spi_mem *mem,
- }
- EXPORT_SYMBOL_GPL(spi_mem_exec_op);
-
-+int spi_mem_do_calibration(struct spi_mem *mem,
-+ int (*cal_read)(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen),
-+ void *priv)
-+{
-+ return spi_do_calibration(mem->spi->controller, mem->spi, cal_read, priv);
-+}
-+EXPORT_SYMBOL_GPL(spi_mem_do_calibration);
-+
- /**
- * spi_mem_get_name() - Return the SPI mem device name to be used by the
- * upper layer if necessary
---- a/include/linux/spi/spi-mem.h
-+++ b/include/linux/spi/spi-mem.h
-@@ -366,6 +366,10 @@ bool spi_mem_supports_op(struct spi_mem
- int spi_mem_exec_op(struct spi_mem *mem,
- const struct spi_mem_op *op);
-
-+int spi_mem_do_calibration(struct spi_mem *mem,
-+ int (*cal_read)(void *, u32 *, int, u8 *, int),
-+ void *priv);
-+
- const char *spi_mem_get_name(struct spi_mem *mem);
-
- struct spi_mem_dirmap_desc *
+++ /dev/null
-From d278c7a0bf730318a7ccf8d0a8b434c813e23fd0 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:39:03 +0800
-Subject: [PATCH 4/6] drivers: spi-mt65xx: Add controller's calibration
- paramter
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
----
- drivers/spi/spi-mt65xx.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/drivers/spi/spi-mt65xx.c
-+++ b/drivers/spi/spi-mt65xx.c
-@@ -834,6 +834,21 @@ static irqreturn_t mtk_spi_interrupt(int
- return IRQ_HANDLED;
- }
-
-+static int mtk_spi_append_caldata(struct spi_controller *ctlr)
-+{
-+ struct spi_cal_target *cal_target = kmalloc(sizeof(*cal_target), GFP_KERNEL);
-+ struct mtk_spi *mdata = spi_master_get_devdata(ctlr);
-+
-+ cal_target->cal_item = &mdata->get_tick_dly;
-+ cal_target->cal_min = 0;
-+ cal_target->cal_max = 7;
-+ cal_target->step = 1;
-+
-+ list_add(&cal_target->list, ctlr->cal_target);
-+
-+ return 0;
-+}
-+
- static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
- struct spi_mem_op *op)
- {
-@@ -1124,6 +1139,7 @@ static int mtk_spi_probe(struct platform
- master->setup = mtk_spi_setup;
- master->set_cs_timing = mtk_spi_set_hw_cs_timing;
- master->use_gpio_descriptors = true;
-+ master->append_caldata = mtk_spi_append_caldata;
-
- mdata = spi_master_get_devdata(master);
- mdata->dev_comp = device_get_match_data(dev);
+++ /dev/null
-From 7670ec4a14891a1a182b98a9c403ffbf6b49e4b1 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:39:56 +0800
-Subject: [PATCH 5/6] drivers: mtd: spinand: Add calibration support for
- spinand
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
----
- drivers/mtd/nand/spi/core.c | 54 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 54 insertions(+)
-
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -978,6 +978,56 @@ static int spinand_manufacturer_match(st
- return -ENOTSUPP;
- }
-
-+int spinand_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen) {
-+ struct spinand_device *spinand = (struct spinand_device *)priv;
-+ struct device *dev = &spinand->spimem->spi->dev;
-+ struct spi_mem_op op = SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, buf, readlen);
-+ struct nand_pos pos;
-+ struct nand_page_io_req req;
-+ u8 status;
-+ int ret;
-+
-+ if(addrlen != sizeof(struct nand_addr)/sizeof(unsigned int)) {
-+ dev_err(dev, "Must provide correct addr(length) for spinand calibration\n");
-+ return -EINVAL;
-+ }
-+
-+ ret = spinand_reset_op(spinand);
-+ if (ret)
-+ return ret;
-+
-+ /* We should store our golden data in first target because
-+ * we can't switch target at this moment.
-+ */
-+ pos = (struct nand_pos){
-+ .target = 0,
-+ .lun = *addr,
-+ .plane = *(addr+1),
-+ .eraseblock = *(addr+2),
-+ .page = *(addr+3),
-+ };
-+
-+ req = (struct nand_page_io_req){
-+ .pos = pos,
-+ .dataoffs = *(addr+4),
-+ .datalen = readlen,
-+ .databuf.in = buf,
-+ .mode = MTD_OPS_AUTO_OOB,
-+ };
-+
-+ ret = spinand_load_page_op(spinand, &req);
-+ if (ret)
-+ return ret;
-+
-+ ret = spinand_wait(spinand, &status);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = spi_mem_exec_op(spinand->spimem, &op);
-+
-+ return 0;
-+}
-+
- static int spinand_id_detect(struct spinand_device *spinand)
- {
- u8 *id = spinand->id.data;
-@@ -1228,6 +1278,10 @@ static int spinand_init(struct spinand_d
- if (!spinand->scratchbuf)
- return -ENOMEM;
-
-+ ret = spi_mem_do_calibration(spinand->spimem, spinand_cal_read, spinand);
-+ if (ret)
-+ dev_err(dev, "Failed to calibrate SPI-NAND (err = %d)\n", ret);
-+
- ret = spinand_detect(spinand);
- if (ret)
- goto err_free_bufs;
+++ /dev/null
-From f3fe3b15eca7908eaac57f9b8387a5dbc45ec5b2 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:40:59 +0800
-Subject: [PATCH 6/6] drivers: mtd: spi-nor: Add calibration support for
- spi-nor
-
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
----
- drivers/mtd/nand/spi/core.c | 5 ++++-
- drivers/mtd/spi-nor/core.c | 15 +++++++++++++++
- 2 files changed, 19 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/spi/core.c
-+++ b/drivers/mtd/nand/spi/core.c
-@@ -1019,7 +1019,10 @@ int spinand_cal_read(void *priv, u32 *ad
- if (ret)
- return ret;
-
-- ret = spinand_wait(spinand, &status);
-+ ret = spinand_wait(spinand,
-+ SPINAND_READ_INITIAL_DELAY_US,
-+ SPINAND_READ_POLL_DELAY_US,
-+ &status);
- if (ret < 0)
- return ret;
-
---- a/drivers/mtd/spi-nor/core.c
-+++ b/drivers/mtd/spi-nor/core.c
-@@ -2922,6 +2922,18 @@ static const struct flash_info *spi_nor_
- return NULL;
- }
-
-+static int spi_nor_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen)
-+{
-+ struct spi_nor *nor = (struct spi_nor *)priv;
-+
-+ nor->reg_proto = SNOR_PROTO_1_1_1;
-+ nor->read_proto = SNOR_PROTO_1_1_1;
-+ nor->read_opcode = SPINOR_OP_READ;
-+ nor->read_dummy = 0;
-+
-+ return nor->controller_ops->read(nor, *addr, readlen, buf);
-+}
-+
- static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
- const char *name)
- {
-@@ -3025,6 +3037,9 @@ int spi_nor_scan(struct spi_nor *nor, co
- if (!nor->bouncebuf)
- return -ENOMEM;
-
-+ if(nor->spimem)
-+ spi_mem_do_calibration(nor->spimem, spi_nor_cal_read, nor);
-+
- info = spi_nor_get_flash_info(nor, name);
- if (IS_ERR(info))
- return PTR_ERR(info);
+++ /dev/null
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -384,6 +384,12 @@ config ROCKCHIP_PHY
- help
- Currently supports the integrated Ethernet PHY.
-
-+config RTL8367S_GSW
-+ tristate "rtl8367 Gigabit Switch support for mt7622"
-+ depends on NET_VENDOR_MEDIATEK
-+ help
-+ This driver supports rtl8367s in mt7622
-+
- config SMSC_PHY
- tristate "SMSC PHYs"
- help
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -95,6 +95,7 @@ obj-$(CONFIG_QSEMI_PHY) += qsemi.o
- obj-$(CONFIG_REALTEK_PHY) += realtek.o
- obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
- obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
-+obj-$(CONFIG_RTL8367S_GSW) += rtk/
- obj-$(CONFIG_SMSC_PHY) += smsc.o
- obj-$(CONFIG_STE10XP) += ste10Xp.o
- obj-$(CONFIG_TERANETICS_PHY) += teranetics.o
+++ /dev/null
-From: qizhong cheng <qizhong.cheng@mediatek.com>
-Date: Mon, 27 Dec 2021 21:31:10 +0800
-Subject: [PATCH] PCI: mediatek: Assert PERST# for 100ms for power and clock to
- stabilize
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Described in PCIe CEM specification sections 2.2 (PERST# Signal) and
-2.2.1 (Initial Power-Up (G3 to S0)). The deassertion of PERST# should
-be delayed 100ms (TPVPERL) for the power and clock to become stable.
-
-Link: https://lore.kernel.org/r/20211227133110.14500-1-qizhong.cheng@mediatek.com
-Signed-off-by: qizhong cheng <qizhong.cheng@mediatek.com>
-Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
-Acked-by: Pali Rohár <pali@kernel.org>
----
-
---- a/drivers/pci/controller/pcie-mediatek.c
-+++ b/drivers/pci/controller/pcie-mediatek.c
-@@ -708,6 +708,13 @@ static int mtk_pcie_startup_port_v2(stru
- */
- msleep(100);
-
-+ /*
-+ * Described in PCIe CEM specification sections 2.2 (PERST# Signal) and
-+ * 2.2.1 (Initial Power-Up (G3 to S0)). The deassertion of PERST# should
-+ * be delayed 100ms (TPVPERL) for the power and clock to become stable.
-+ */
-+ msleep(100);
-+
- /* De-assert PHY, PE, PIPE, MAC and configuration reset */
- val = readl(port->base + PCIE_RST_CTRL);
- val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB |
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -849,6 +849,12 @@
- #address-cells = <0>;
- #interrupt-cells = <1>;
- };
-+
-+ slot0: pcie@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ };
- };
-
- pcie1: pcie@1a145000 {
-@@ -887,6 +893,12 @@
- #address-cells = <0>;
- #interrupt-cells = <1>;
- };
-+
-+ slot1: pcie@1,0 {
-+ reg = <0x0800 0 0 0 0>;
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ };
- };
-
- sata: sata@1a200000 {
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 4 Sep 2020 18:33:27 +0200
-Subject: [PATCH] pcie-mediatek: fix clearing interrupt status
-
-Clearing the status needs to happen after running the handler, otherwise
-we will get an extra spurious interrupt after the cause has been cleared
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/pci/controller/pcie-mediatek.c
-+++ b/drivers/pci/controller/pcie-mediatek.c
-@@ -607,9 +607,9 @@ static void mtk_pcie_intr_handler(struct
- if (status & INTX_MASK) {
- for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) {
- /* Clear the INTx */
-- writel(1 << bit, port->base + PCIE_INT_STATUS);
- generic_handle_domain_irq(port->irq_domain,
- bit - INTX_SHIFT);
-+ writel(1 << bit, port->base + PCIE_INT_STATUS);
- }
- }
-
+++ /dev/null
---- a/drivers/pci/controller/pcie-mediatek-gen3.c
-+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
-@@ -375,7 +375,13 @@ static int mtk_pcie_startup_port(struct
- msleep(100);
-
- /* De-assert reset signals */
-- val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB);
-+ val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB);
-+ writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
-+
-+ msleep(100);
-+
-+ /* De-assert PERST# signals */
-+ val &= ~(PCIE_PE_RSTB);
- writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
-
- /* Check if the link is up or not */
+++ /dev/null
-From 50cefacc6c001eea1d9b1c78ba27304566f304f1 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 2 Jun 2023 13:06:26 +0800
-Subject: [PATCH] phy: mediatek: xsphy: support type switch by pericfg
-
-Patch from Sam Shih <sam.shih@mediatek.com> found in MediaTek SDK
-released under GPL.
-
-Get syscon and use it to set the PHY type.
-Extend support to PCIe and SGMII mode in addition to USB2 and USB3.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/phy/mediatek/phy-mtk-xsphy.c | 81 +++++++++++++++++++++++++++-
- 1 file changed, 80 insertions(+), 1 deletion(-)
-
---- a/drivers/phy/mediatek/phy-mtk-xsphy.c
-+++ b/drivers/phy/mediatek/phy-mtk-xsphy.c
-@@ -11,10 +11,12 @@
- #include <linux/clk.h>
- #include <linux/delay.h>
- #include <linux/iopoll.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/module.h>
- #include <linux/of_address.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
-+#include <linux/regmap.h>
-
- #include "phy-mtk-io.h"
-
-@@ -81,12 +83,22 @@
- #define XSP_SR_COEF_DIVISOR 1000
- #define XSP_FM_DET_CYCLE_CNT 1024
-
-+/* PHY switch between pcie/usb3/sgmii */
-+#define USB_PHY_SWITCH_CTRL 0x0
-+#define RG_PHY_SW_TYPE GENMASK(3, 0)
-+#define RG_PHY_SW_PCIE 0x0
-+#define RG_PHY_SW_USB3 0x1
-+#define RG_PHY_SW_SGMII 0x2
-+
- struct xsphy_instance {
- struct phy *phy;
- void __iomem *port_base;
- struct clk *ref_clk; /* reference clock of anolog phy */
- u32 index;
- u32 type;
-+ struct regmap *type_sw;
-+ u32 type_sw_reg;
-+ u32 type_sw_index;
- /* only for HQA test */
- int efuse_intr;
- int efuse_tx_imp;
-@@ -259,6 +271,10 @@ static void phy_parse_property(struct mt
- inst->efuse_intr, inst->efuse_tx_imp,
- inst->efuse_rx_imp);
- break;
-+ case PHY_TYPE_PCIE:
-+ case PHY_TYPE_SGMII:
-+ /* nothing to do */
-+ break;
- default:
- dev_err(xsphy->dev, "incompatible phy type\n");
- return;
-@@ -305,6 +321,62 @@ static void u3_phy_props_set(struct mtk_
- RG_XTP_LN0_RX_IMPSEL, inst->efuse_rx_imp);
- }
-
-+/* type switch for usb3/pcie/sgmii */
-+static int phy_type_syscon_get(struct xsphy_instance *instance,
-+ struct device_node *dn)
-+{
-+ struct of_phandle_args args;
-+ int ret;
-+
-+ /* type switch function is optional */
-+ if (!of_property_read_bool(dn, "mediatek,syscon-type"))
-+ return 0;
-+
-+ ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type",
-+ 2, 0, &args);
-+ if (ret)
-+ return ret;
-+
-+ instance->type_sw_reg = args.args[0];
-+ instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
-+ instance->type_sw = syscon_node_to_regmap(args.np);
-+ of_node_put(args.np);
-+ dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n",
-+ instance->type_sw_reg, instance->type_sw_index);
-+
-+ return PTR_ERR_OR_ZERO(instance->type_sw);
-+}
-+
-+static int phy_type_set(struct xsphy_instance *instance)
-+{
-+ int type;
-+ u32 offset;
-+
-+ if (!instance->type_sw)
-+ return 0;
-+
-+ switch (instance->type) {
-+ case PHY_TYPE_USB3:
-+ type = RG_PHY_SW_USB3;
-+ break;
-+ case PHY_TYPE_PCIE:
-+ type = RG_PHY_SW_PCIE;
-+ break;
-+ case PHY_TYPE_SGMII:
-+ type = RG_PHY_SW_SGMII;
-+ break;
-+ case PHY_TYPE_USB2:
-+ default:
-+ return 0;
-+ }
-+
-+ offset = instance->type_sw_index * BITS_PER_BYTE;
-+ regmap_update_bits(instance->type_sw, instance->type_sw_reg,
-+ RG_PHY_SW_TYPE << offset, type << offset);
-+
-+ return 0;
-+}
-+
- static int mtk_phy_init(struct phy *phy)
- {
- struct xsphy_instance *inst = phy_get_drvdata(phy);
-@@ -325,6 +397,10 @@ static int mtk_phy_init(struct phy *phy)
- case PHY_TYPE_USB3:
- u3_phy_props_set(xsphy, inst);
- break;
-+ case PHY_TYPE_PCIE:
-+ case PHY_TYPE_SGMII:
-+ /* nothing to do, only used to set type */
-+ break;
- default:
- dev_err(xsphy->dev, "incompatible phy type\n");
- clk_disable_unprepare(inst->ref_clk);
-@@ -403,12 +479,15 @@ static struct phy *mtk_phy_xlate(struct
-
- inst->type = args->args[0];
- if (!(inst->type == PHY_TYPE_USB2 ||
-- inst->type == PHY_TYPE_USB3)) {
-+ inst->type == PHY_TYPE_USB3 ||
-+ inst->type == PHY_TYPE_PCIE ||
-+ inst->type == PHY_TYPE_SGMII)) {
- dev_err(dev, "unsupported phy type: %d\n", inst->type);
- return ERR_PTR(-EINVAL);
- }
-
- phy_parse_property(xsphy, inst);
-+ phy_type_set(inst);
-
- return inst->phy;
- }
-@@ -515,6 +594,10 @@ static int mtk_xsphy_probe(struct platfo
- retval = PTR_ERR(inst->ref_clk);
- goto put_child;
- }
-+
-+ retval = phy_type_syscon_get(inst, child_np);
-+ if (retval)
-+ goto put_child;
- }
-
- provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 4 Sep 2020 18:42:42 +0200
-Subject: [PATCH] pci: pcie-mediatek: add support for coherent DMA
-
-It improves performance by eliminating the need for a cache flush for DMA on
-attached devices
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -837,6 +837,9 @@
- bus-range = <0x00 0xff>;
- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
- status = "disabled";
-+ dma-coherent;
-+ mediatek,hifsys = <&hifsys>;
-+ mediatek,cci-control = <&cci_control2>;
-
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 7>;
-@@ -881,6 +884,9 @@
- bus-range = <0x00 0xff>;
- ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
- status = "disabled";
-+ dma-coherent;
-+ mediatek,hifsys = <&hifsys>;
-+ mediatek,cci-control = <&cci_control2>;
-
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 7>;
---- a/drivers/pci/controller/pcie-mediatek.c
-+++ b/drivers/pci/controller/pcie-mediatek.c
-@@ -20,6 +20,7 @@
- #include <linux/of_address.h>
- #include <linux/of_pci.h>
- #include <linux/of_platform.h>
-+#include <linux/of_address.h>
- #include <linux/pci.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
-@@ -139,6 +140,11 @@
- #define PCIE_LINK_STATUS_V2 0x804
- #define PCIE_PORT_LINKUP_V2 BIT(10)
-
-+/* DMA channel mapping */
-+#define HIFSYS_DMA_AG_MAP 0x008
-+#define HIFSYS_DMA_AG_MAP_PCIE0 BIT(0)
-+#define HIFSYS_DMA_AG_MAP_PCIE1 BIT(1)
-+
- struct mtk_pcie_port;
-
- /**
-@@ -1060,6 +1066,27 @@ static int mtk_pcie_setup(struct mtk_pci
- struct mtk_pcie_port *port, *tmp;
- int err, slot;
-
-+ if (of_dma_is_coherent(node)) {
-+ struct regmap *con;
-+ u32 mask;
-+
-+ con = syscon_regmap_lookup_by_phandle(node,
-+ "mediatek,cci-control");
-+ /* enable CPU/bus coherency */
-+ if (!IS_ERR(con))
-+ regmap_write(con, 0, 3);
-+
-+ con = syscon_regmap_lookup_by_phandle(node,
-+ "mediatek,hifsys");
-+ if (IS_ERR(con)) {
-+ dev_err(dev, "missing hifsys node\n");
-+ return PTR_ERR(con);
-+ }
-+
-+ mask = HIFSYS_DMA_AG_MAP_PCIE0 | HIFSYS_DMA_AG_MAP_PCIE1;
-+ regmap_update_bits(con, HIFSYS_DMA_AG_MAP, mask, mask);
-+ }
-+
- slot = of_get_pci_domain_nr(dev->of_node);
- if (slot < 0) {
- for_each_available_child_of_node(node, child) {
+++ /dev/null
-From: Jip de Beer <gpk6x3591g0l@opayq.com>
-Date: Sun, 9 Jan 2022 13:14:04 +0100
-Subject: [PATCH] mediatek mt7622: fix 300mhz typo in dts
-
-The lowest frequency should be 300MHz, since that is the label
-assigned to the OPP in the mt7622.dtsi device tree, while there is one
-missing zero in the actual value.
-
-To be clear, the lowest frequency should be 300MHz instead of 30MHz.
-
-As mentioned @dangowrt on the OpenWrt forum there is no benefit in
-leaving 30MHz as the lowest frequency.
-
-Signed-off-by: Jip de Beer <gpk6x3591g0l@opayq.com>
-Signed-off-by: Fritz D. Ansel <fdansel@yandex.ru>
----
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -24,7 +24,7 @@
- compatible = "operating-points-v2";
- opp-shared;
- opp-300000000 {
-- opp-hz = /bits/ 64 <30000000>;
-+ opp-hz = /bits/ 64 <300000000>;
- opp-microvolt = <950000>;
- };
-
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -23,11 +23,17 @@
- cpu_opp_table: opp-table {
- compatible = "operating-points-v2";
- opp-shared;
-- opp-300000000 {
-- opp-hz = /bits/ 64 <300000000>;
-- opp-microvolt = <950000>;
-- };
--
-+ /* Due to the bug described at the link below, remove the 300 MHz clock to avoid a low
-+ * voltage condition that can cause a hang when rebooting the RT3200/E8450.
-+ *
-+ * https://forum.openwrt.org/t/belkin-rt3200-linksys-e8450-wifi-ax-discussion/94302/1490
-+ *
-+ * opp-300000000 {
-+ * opp-hz = /bits/ 64 <300000000>;
-+ * opp-microvolt = <950000>;
-+ * };
-+ *
-+ */
- opp-437500000 {
- opp-hz = /bits/ 64 <437500000>;
- opp-microvolt = <1000000>;
+++ /dev/null
-From 98c485eaf509bc0e2a85f9b58d17cd501f274c4e Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 11 Jun 2023 00:48:10 +0100
-Subject: [PATCH] net: phy: add driver for MediaTek SoC built-in GE PHYs
-
-Some of MediaTek's Filogic SoCs come with built-in gigabit Ethernet
-PHYs which require calibration data from the SoC's efuse.
-Despite the similar design the driver doesn't share any code with the
-existing mediatek-ge.c.
-Add support for such PHYs by introducing a new driver with basic
-support for MediaTek SoCs MT7981 and MT7988 built-in 1GE PHYs.
-
-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 | 9 +
- drivers/net/phy/Kconfig | 12 +
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/mediatek-ge-soc.c | 1116 +++++++++++++++++++++++++++++
- drivers/net/phy/mediatek-ge.c | 3 +-
- 5 files changed, 1140 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/phy/mediatek-ge-soc.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -12945,6 +12945,15 @@ F: drivers/net/pcs/pcs-mtk-usxgmii.c
- F: include/linux/pcs/pcs-mtk-lynxi.h
- F: include/linux/pcs/pcs-mtk-usxgmii.h
-
-+MEDIATEK ETHERNET PHY DRIVERS
-+M: Daniel Golle <daniel@makrotopia.org>
-+M: Qingfang Deng <dqfext@gmail.com>
-+M: SkyLake Huang <SkyLake.Huang@mediatek.com>
-+L: netdev@vger.kernel.org
-+S: Maintained
-+F: drivers/net/phy/mediatek-ge-soc.c
-+F: drivers/net/phy/mediatek-ge.c
-+
- MEDIATEK I2C CONTROLLER DRIVER
- M: Qii Wang <qii.wang@mediatek.com>
- L: linux-i2c@vger.kernel.org
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -314,6 +314,18 @@ config MEDIATEK_GE_PHY
- help
- Supports the MediaTek 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.
-+
- config MICREL_PHY
- tristate "Micrel PHYs"
- depends on PTP_1588_CLOCK_OPTIONAL
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -80,6 +80,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.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-$(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-ge-soc.c
-@@ -0,0 +1,1116 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+#include <linux/bitfield.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>
-+
-+#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
-+
-+#define MTK_PHY_RG_BG_RASEL 0x115
-+#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
-+
-+/* 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 {
-+ GPHY_PORT0,
-+ GPHY_PORT1,
-+ GPHY_PORT2,
-+ GPHY_PORT3,
-+};
-+
-+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
-+};
-+
-+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 = -2;
-+
-+ 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);
-+ /* 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);
-+
-+ /* TrFreeze = 0 */
-+ __phy_write(phydev, 0x11, 0x0);
-+ __phy_write(phydev, 0x12, 0x0);
-+ __phy_write(phydev, 0x10, 0x9686);
-+
-+ /* SSTrKp1000Slv = 5 */
-+ __phy_write(phydev, 0x11, 0xbaef);
-+ __phy_write(phydev, 0x12, 0x2e);
-+ __phy_write(phydev, 0x10, 0x968c);
-+
-+ /* 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 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);
-+ /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
-+ __phy_write(phydev, 0x11, 0xc71);
-+ __phy_write(phydev, 0x12, 0xc);
-+ __phy_write(phydev, 0x10, 0x8fae);
-+
-+ /* 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);
-+
-+ /* FfeUpdGainForce = 4 */
-+ __phy_write(phydev, 0x11, 0x240);
-+ __phy_write(phydev, 0x12, 0x0);
-+ __phy_write(phydev, 0x10, 0x9680);
-+
-+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+}
-+
-+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);
-+
-+ /* Disable TX power saving */
-+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
-+ MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
-+
-+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
-+
-+ /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */
-+ __phy_write(phydev, 0x11, 0x671);
-+ __phy_write(phydev, 0x12, 0xc);
-+ __phy_write(phydev, 0x10, 0x8fae);
-+
-+ /* ResetSyncOffset = 5 */
-+ __phy_write(phydev, 0x11, 0x500);
-+ __phy_write(phydev, 0x12, 0x0);
-+ __phy_write(phydev, 0x10, 0x8fc0);
-+
-+ /* VgaDecRate is 1 at default on mt7988 */
-+
-+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+
-+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
-+ /* TxClkOffset = 2 */
-+ __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
-+ FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
-+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+}
-+
-+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));
-+
-+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
-+ MTK_PHY_LPI_SEND_LOC_TIMER_MASK |
-+ MTK_PHY_LPI_TXPCS_LOC_RCV,
-+ FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117));
-+
-+ 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 = 3 */
-+ __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 = 1 */
-+ __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 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 = mt798x_phy_calibration,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
-+ .read_page = mtk_socphy_read_page,
-+ .write_page = mtk_socphy_write_page,
-+ },
-+ {
-+ 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 = mt798x_phy_calibration,
-+ .suspend = genphy_suspend,
-+ .resume = genphy_resume,
-+ .read_page = mtk_socphy_read_page,
-+ .write_page = mtk_socphy_write_page,
-+ },
-+};
-+
-+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
-+++ b/drivers/net/phy/mediatek-ge.c
-@@ -136,7 +136,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_VENDOR(0x03a29400) },
-+ { PHY_ID_MATCH_EXACT(0x03a29441) },
-+ { PHY_ID_MATCH_EXACT(0x03a29412) },
- { }
- };
-
+++ /dev/null
-From c66937b0f8dbb4c6c043663c702b1053fb47fab2 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 14 Aug 2023 02:58:14 +0100
-Subject: [PATCH] net: phy: mediatek-ge-soc: support PHY LEDs
-
-Implement netdev trigger and primitive bliking offloading as well as
-simple set_brigthness function for both PHY LEDs of the in-SoC PHYs
-found in MT7981 and MT7988.
-
-For MT7988, read boottrap register and apply LED polarities accordingly
-to get uniform behavior from all LEDs on MT7988.
-This requires syscon phandle 'mediatek,pio' present in parenting MDIO bus
-which should point to the syscon holding the boottrap register.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/dc324d48c00cd7350f3a506eaa785324cae97372.1691977904.git.daniel@makrotopia.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/phy/mediatek-ge-soc.c | 435 +++++++++++++++++++++++++++++-
- 1 file changed, 426 insertions(+), 9 deletions(-)
-
---- a/drivers/net/phy/mediatek-ge-soc.c
-+++ b/drivers/net/phy/mediatek-ge-soc.c
-@@ -1,11 +1,14 @@
- // 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/of_address.h>
- #include <linux/of_platform.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
-@@ -208,9 +211,42 @@
- #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_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_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))
-@@ -238,13 +274,6 @@ enum {
- PAIR_D,
- };
-
--enum {
-- GPHY_PORT0,
-- GPHY_PORT1,
-- GPHY_PORT2,
-- GPHY_PORT3,
--};
--
- enum calibration_mode {
- EFUSE_K,
- SW_K
-@@ -263,6 +292,19 @@ 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;
-+};
-+
-+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);
-@@ -1073,6 +1115,371 @@ 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)
-+{
-+ 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_LINK1000 | MTK_PHY_LED_ON_LINK100 |
-+ MTK_PHY_LED_ON_LINK10)) ||
-+ (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX |
-+ MTK_PHY_LED_BLINK_10RX | MTK_PHY_LED_BLINK_1000TX |
-+ MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX)))
-+ 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_LINK1000 | MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK10))
-+ *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_1000RX | MTK_PHY_LED_BLINK_100RX | MTK_PHY_LED_BLINK_10RX))
-+ *rules |= BIT(TRIGGER_NETDEV_RX);
-+
-+ if (blink & (MTK_PHY_LED_BLINK_1000TX | MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX))
-+ *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 |= MTK_PHY_LED_BLINK_10RX |
-+ MTK_PHY_LED_BLINK_100RX |
-+ MTK_PHY_LED_BLINK_1000RX;
-+ }
-+
-+ if (rules & BIT(TRIGGER_NETDEV_TX)) {
-+ blink |= MTK_PHY_LED_BLINK_10TX |
-+ MTK_PHY_LED_BLINK_100TX |
-+ MTK_PHY_LED_BLINK_1000TX;
-+ }
-+
-+ 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_LINK10 |
-+ MTK_PHY_LED_ON_LINK100 |
-+ MTK_PHY_LED_ON_LINK1000,
-+ 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, ®);
-+ 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;
-+
-+ 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),
-@@ -1080,11 +1487,16 @@ static struct phy_driver mtk_socphy_driv
- .config_init = mt798x_phy_config_init,
- .config_intr = genphy_no_config_intr,
- .handle_interrupt = genphy_handle_interrupt_no_ack,
-- .probe = mt798x_phy_calibration,
-+ .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),
-@@ -1092,11 +1504,16 @@ static struct phy_driver mtk_socphy_driv
- .config_init = mt798x_phy_config_init,
- .config_intr = genphy_no_config_intr,
- .handle_interrupt = genphy_handle_interrupt_no_ack,
-- .probe = mt798x_phy_calibration,
-+ .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,
- },
- };
-
+++ /dev/null
-From a969b663c866129ed9eb217785a6574fbe826f1d Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 6 Apr 2023 23:36:50 +0100
-Subject: [PATCH] net: phy: mxl-gpy: don't use SGMII AN if using phylink
-
-MAC drivers using phylink expect SGMII in-band-status to be switched off
-when attached to a PHY. Make sure this is the case also for mxl-gpy which
-keeps SGMII in-band-status in case of SGMII interface mode is used.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/mxl-gpy.c | 19 ++++++++++++++++---
- 1 file changed, 16 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/mxl-gpy.c
-+++ b/drivers/net/phy/mxl-gpy.c
-@@ -371,8 +371,11 @@ static bool gpy_2500basex_chk(struct phy
-
- phydev->speed = SPEED_2500;
- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-- phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-- VSPEC1_SGMII_CTRL_ANEN, 0);
-+
-+ if (!phydev->phylink)
-+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-+ VSPEC1_SGMII_CTRL_ANEN, 0);
-+
- return true;
- }
-
-@@ -396,6 +399,14 @@ static int gpy_config_aneg(struct phy_de
- u32 adv;
- int ret;
-
-+ /* Disable SGMII auto-negotiation if using phylink */
-+ if (phydev->phylink) {
-+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
-+ VSPEC1_SGMII_CTRL_ANEN, 0);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
- if (phydev->autoneg == AUTONEG_DISABLE) {
- /* Configure half duplex with genphy_setup_forced,
- * because genphy_c45_pma_setup_forced does not support.
-@@ -486,6 +497,8 @@ static void gpy_update_interface(struct
- switch (phydev->speed) {
- case SPEED_2500:
- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ if (phydev->phylink)
-+ break;
- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
- VSPEC1_SGMII_CTRL_ANEN, 0);
- if (ret < 0)
-@@ -497,7 +510,7 @@ static void gpy_update_interface(struct
- case SPEED_100:
- case SPEED_10:
- phydev->interface = PHY_INTERFACE_MODE_SGMII;
-- if (gpy_sgmii_aneg_en(phydev))
-+ if (phydev->phylink || gpy_sgmii_aneg_en(phydev))
- break;
- /* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed
- * if ANEG is disabled (in 2500-BaseX mode).
+++ /dev/null
-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
-@@ -326,6 +326,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
-@@ -79,6 +79,7 @@ obj-$(CONFIG_MARVELL_10G_PHY) += marvell
- obj-$(CONFIG_MARVELL_PHY) += marvell.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
+++ /dev/null
-From f2195279c234c0f618946424b8236026126bc595 Mon Sep 17 00:00:00 2001
-Message-ID: <f2195279c234c0f618946424b8236026126bc595.1706071311.git.daniel@makrotopia.org>
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 24 Jan 2024 02:27:04 +0000
-Subject: [PATCH net] net: phy: mediatek-ge-soc: sync driver with MediaTek SDK
-To: Daniel Golle <daniel@makrotopia.org>,
- Qingfang Deng <dqfext@gmail.com>,
- SkyLake Huang <SkyLake.Huang@mediatek.com>,
- 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>,
- 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
-
-Sync initialization and calibration routines with MediaTek's reference
-driver. Improves compliance and resolves link stability issues with
-CH340 IoT devices connected to MT798x built-in PHYs.
-
-Fixes: 98c485eaf509 ("net: phy: add driver for MediaTek SoC built-in GE PHYs")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/mediatek-ge-soc.c | 147 ++++++++++++++++--------------
- 1 file changed, 81 insertions(+), 66 deletions(-)
-
---- a/drivers/net/phy/mediatek-ge-soc.c
-+++ b/drivers/net/phy/mediatek-ge-soc.c
-@@ -491,7 +491,7 @@ static int tx_r50_fill_result(struct phy
- u16 reg, val;
-
- if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
-- bias = -2;
-+ bias = -1;
-
- val = clamp_val(bias + tx_r50_cal_val, 0, 63);
-
-@@ -707,6 +707,11 @@ 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);
-@@ -717,15 +722,56 @@ static void mt798x_phy_common_finetune(s
- __phy_write(phydev, 0x12, 0x0);
- __phy_write(phydev, 0x10, 0x83aa);
-
-- /* TrFreeze = 0 */
-+ /* 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
-@@ -740,7 +786,7 @@ static void mt798x_phy_common_finetune(s
- __phy_write(phydev, 0x10, 0x8ec0);
- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-
-- /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
-+ /* 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));
-@@ -773,48 +819,6 @@ static void mt798x_phy_common_finetune(s
- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
- }
-
--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);
-- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
-- __phy_write(phydev, 0x11, 0xc71);
-- __phy_write(phydev, 0x12, 0xc);
-- __phy_write(phydev, 0x10, 0x8fae);
--
-- /* 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);
--
-- /* FfeUpdGainForce = 4 */
-- __phy_write(phydev, 0x11, 0x240);
-- __phy_write(phydev, 0x12, 0x0);
-- __phy_write(phydev, 0x10, 0x9680);
--
-- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
--}
--
- static void mt7988_phy_finetune(struct phy_device *phydev)
- {
- u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
-@@ -829,17 +833,7 @@ static void mt7988_phy_finetune(struct p
- /* TCT finetune */
- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
-
-- /* Disable TX power saving */
-- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
-- MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
--
- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
--
-- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */
-- __phy_write(phydev, 0x11, 0x671);
-- __phy_write(phydev, 0x12, 0xc);
-- __phy_write(phydev, 0x10, 0x8fae);
--
- /* ResetSyncOffset = 5 */
- __phy_write(phydev, 0x11, 0x500);
- __phy_write(phydev, 0x12, 0x0);
-@@ -847,13 +841,27 @@ static void mt7988_phy_finetune(struct p
-
- /* VgaDecRate is 1 at default on mt7988 */
-
-- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-+ /* 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_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
-- /* TxClkOffset = 2 */
-- __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
-- FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
- 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)
-@@ -886,11 +894,11 @@ static void mt798x_phy_eee(struct phy_de
- MTK_PHY_LPI_SLV_SEND_TX_EN,
- FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
-
-- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
-- MTK_PHY_LPI_SEND_LOC_TIMER_MASK |
-- MTK_PHY_LPI_TXPCS_LOC_RCV,
-- FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117));
-+ /* 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) |
-@@ -924,7 +932,7 @@ static void mt798x_phy_eee(struct phy_de
- __phy_write(phydev, 0x12, 0x0);
- __phy_write(phydev, 0x10, 0x9690);
-
-- /* REG_EEE_st2TrKf1000 = 3 */
-+ /* REG_EEE_st2TrKf1000 = 2 */
- __phy_write(phydev, 0x11, 0x114f);
- __phy_write(phydev, 0x12, 0x2);
- __phy_write(phydev, 0x10, 0x969a);
-@@ -949,7 +957,7 @@ static void mt798x_phy_eee(struct phy_de
- __phy_write(phydev, 0x12, 0x0);
- __phy_write(phydev, 0x10, 0x96b8);
-
-- /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */
-+ /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
- __phy_write(phydev, 0x11, 0x1463);
- __phy_write(phydev, 0x12, 0x0);
- __phy_write(phydev, 0x10, 0x96ca);
-@@ -1461,6 +1469,13 @@ static int mt7988_phy_probe(struct phy_d
- 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);
- }
-
+++ /dev/null
-From 5314e73cb941b47e6866b49b3b78c25e32d62df8 Mon Sep 17 00:00:00 2001
-From: Robert Marko <robert.marko@sartura.hr>
-Date: Sat, 23 Mar 2024 20:21:14 +0100
-Subject: [PATCH] net: phy: add Airoha EN8801SC PHY
-
-Airoha EN8801SC Gigabit PHY is used on Edgecore EAP111, so include a
-modified version of MTK SDK driver.
-
-Signed-off-by: Robert Marko <robert.marko@sartura.hr>
----
- drivers/net/phy/Kconfig | 5 +++++
- drivers/net/phy/Makefile | 1 +
- 2 files changed, 6 insertions(+)
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -143,6 +143,11 @@ endif # RTL8366_SMI
-
- comment "MII PHY device drivers"
-
-+config AIROHA_EN8801SC_PHY
-+ tristate "Airoha EN8801SC Gigabit PHY"
-+ help
-+ Currently supports the Airoha EN8801SC PHY.
-+
- config AIR_EN8811H_PHY
- tristate "Airoha EN8811H 2.5 Gigabit PHY"
- help
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -47,6 +47,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m)
-
- obj-$(CONFIG_ADIN_PHY) += adin.o
- obj-$(CONFIG_ADIN1100_PHY) += adin1100.o
-+obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o
- obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o
- obj-$(CONFIG_AMD_PHY) += amd.o
- obj-$(CONFIG_AQUANTIA_PHY) += aquantia/
+++ /dev/null
---- a/drivers/pwm/pwm-mediatek.c
-+++ b/drivers/pwm/pwm-mediatek.c
-@@ -329,6 +329,12 @@ static const struct pwm_mediatek_of_data
- .has_ck_26m_sel = true,
- };
-
-+static const struct pwm_mediatek_of_data mt7986_pwm_data = {
-+ .num_pwms = 2,
-+ .pwm45_fixup = false,
-+ .has_ck_26m_sel = true,
-+};
-+
- static const struct pwm_mediatek_of_data mt8516_pwm_data = {
- .num_pwms = 5,
- .pwm45_fixup = false,
-@@ -342,6 +348,7 @@ static const struct of_device_id pwm_med
- { .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
- { .compatible = "mediatek,mt7628-pwm", .data = &mt7628_pwm_data },
- { .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
-+ { .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
- { .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
- { .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
- { .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
+++ /dev/null
-From 967da67a745fb73fd0fc7aa61fd197b76fceb273 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 21 Apr 2023 00:23:21 +0100
-Subject: [PATCH] pwm: mediatek: Add support for MT7981
-
-The PWM unit on MT7981 uses different register offsets than previous
-MediaTek PWM units. Add support for these new offsets and add support
-for PWM on MT7981 which has 3 PWM channels, one of them is typically
-used for a temperature controlled fan.
-While at it, also reorder pwm_mediatek_of_data entries to restore
-alphabetic order.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
-Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
----
- drivers/pwm/pwm-mediatek.c | 39 ++++++++++++++++++++++++++++++--------
- 1 file changed, 31 insertions(+), 8 deletions(-)
-
---- a/drivers/pwm/pwm-mediatek.c
-+++ b/drivers/pwm/pwm-mediatek.c
-@@ -38,6 +38,7 @@ struct pwm_mediatek_of_data {
- unsigned int num_pwms;
- bool pwm45_fixup;
- bool has_ck_26m_sel;
-+ const unsigned int *reg_offset;
- };
-
- /**
-@@ -59,10 +60,14 @@ struct pwm_mediatek_chip {
- const struct pwm_mediatek_of_data *soc;
- };
-
--static const unsigned int pwm_mediatek_reg_offset[] = {
-+static const unsigned int mtk_pwm_reg_offset_v1[] = {
- 0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
- };
-
-+static const unsigned int mtk_pwm_reg_offset_v2[] = {
-+ 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240
-+};
-+
- static inline struct pwm_mediatek_chip *
- to_pwm_mediatek_chip(struct pwm_chip *chip)
- {
-@@ -111,7 +116,7 @@ static inline void pwm_mediatek_writel(s
- unsigned int num, unsigned int offset,
- u32 value)
- {
-- writel(value, chip->regs + pwm_mediatek_reg_offset[num] + offset);
-+ writel(value, chip->regs + chip->soc->reg_offset[num] + offset);
- }
-
- static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
-@@ -285,60 +290,77 @@ static const struct pwm_mediatek_of_data
- .num_pwms = 8,
- .pwm45_fixup = false,
- .has_ck_26m_sel = false,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
- static const struct pwm_mediatek_of_data mt6795_pwm_data = {
- .num_pwms = 7,
- .pwm45_fixup = false,
- .has_ck_26m_sel = false,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
- static const struct pwm_mediatek_of_data mt7622_pwm_data = {
- .num_pwms = 6,
- .pwm45_fixup = false,
- .has_ck_26m_sel = true,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
- static const struct pwm_mediatek_of_data mt7623_pwm_data = {
- .num_pwms = 5,
- .pwm45_fixup = true,
- .has_ck_26m_sel = false,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
- static const struct pwm_mediatek_of_data mt7628_pwm_data = {
- .num_pwms = 4,
- .pwm45_fixup = true,
- .has_ck_26m_sel = false,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
- static const struct pwm_mediatek_of_data mt7629_pwm_data = {
- .num_pwms = 1,
- .pwm45_fixup = false,
- .has_ck_26m_sel = false,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
--static const struct pwm_mediatek_of_data mt8183_pwm_data = {
-- .num_pwms = 4,
-+static const struct pwm_mediatek_of_data mt7981_pwm_data = {
-+ .num_pwms = 3,
- .pwm45_fixup = false,
- .has_ck_26m_sel = true,
-+ .reg_offset = mtk_pwm_reg_offset_v2,
- };
-
--static const struct pwm_mediatek_of_data mt8365_pwm_data = {
-- .num_pwms = 3,
-+static const struct pwm_mediatek_of_data mt7986_pwm_data = {
-+ .num_pwms = 2,
- .pwm45_fixup = false,
- .has_ck_26m_sel = true,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
--static const struct pwm_mediatek_of_data mt7986_pwm_data = {
-- .num_pwms = 2,
-+static const struct pwm_mediatek_of_data mt8183_pwm_data = {
-+ .num_pwms = 4,
-+ .pwm45_fixup = false,
-+ .has_ck_26m_sel = true,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
-+};
-+
-+static const struct pwm_mediatek_of_data mt8365_pwm_data = {
-+ .num_pwms = 3,
- .pwm45_fixup = false,
- .has_ck_26m_sel = true,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
- static const struct pwm_mediatek_of_data mt8516_pwm_data = {
- .num_pwms = 5,
- .pwm45_fixup = false,
- .has_ck_26m_sel = true,
-+ .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
- static const struct of_device_id pwm_mediatek_of_match[] = {
-@@ -348,6 +370,7 @@ static const struct of_device_id pwm_med
- { .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
- { .compatible = "mediatek,mt7628-pwm", .data = &mt7628_pwm_data },
- { .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
-+ { .compatible = "mediatek,mt7981-pwm", .data = &mt7981_pwm_data },
- { .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
- { .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
- { .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
+++ /dev/null
-From eb58bf4afd708eb3c64c7b9b2c5fbfacdcdee3e5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 14 Feb 2024 15:04:54 +0100
-Subject: [PATCH] pwm: mediatek: add support for MT7988
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-MT7988 uses new registers layout just like MT7981 but it supports 8 PWM
-interfaces.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20240214140454.6438-2-zajec5@gmail.com
-Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
----
- drivers/pwm/pwm-mediatek.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/pwm/pwm-mediatek.c
-+++ b/drivers/pwm/pwm-mediatek.c
-@@ -342,6 +342,13 @@ static const struct pwm_mediatek_of_data
- .reg_offset = mtk_pwm_reg_offset_v1,
- };
-
-+static const struct pwm_mediatek_of_data mt7988_pwm_data = {
-+ .num_pwms = 8,
-+ .pwm45_fixup = false,
-+ .has_ck_26m_sel = false,
-+ .reg_offset = mtk_pwm_reg_offset_v2,
-+};
-+
- static const struct pwm_mediatek_of_data mt8183_pwm_data = {
- .num_pwms = 4,
- .pwm45_fixup = false,
-@@ -372,6 +379,7 @@ static const struct of_device_id pwm_med
- { .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
- { .compatible = "mediatek,mt7981-pwm", .data = &mt7981_pwm_data },
- { .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
-+ { .compatible = "mediatek,mt7988-pwm", .data = &mt7988_pwm_data },
- { .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
- { .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
- { .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
+++ /dev/null
-From fae82621ac33e2a4a96220c56e90d1ec6237d394 Mon Sep 17 00:00:00 2001
-From: Sam Shih <sam.shih@mediatek.com>
-Date: Sun, 6 Nov 2022 09:01:12 +0100
-Subject: [PATCH] pinctrl: mediatek: extend pinctrl-moore to support new bias
- functions
-
-Commit fb34a9ae383a ("pinctrl: mediatek: support rsel feature")
-introduced SoC specify 'pull_type' attribute to mtk_pinconf_bias_set_combo
-and mtk_pinconf_bias_get_combo, and make the functions able to support
-almost all Mediatek SoCs that use pinctrl-mtk-common-v2.c.
-
-This patch enables pinctrl_moore to support these functions.
-
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221106080114.7426-6-linux@fw-web.de
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/pinctrl/mediatek/pinctrl-moore.c | 49 ++++++++++++++++++++----
- 1 file changed, 42 insertions(+), 7 deletions(-)
-
---- a/drivers/pinctrl/mediatek/pinctrl-moore.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
-@@ -8,6 +8,7 @@
- *
- */
-
-+#include <dt-bindings/pinctrl/mt65xx.h>
- #include <linux/gpio/driver.h>
- #include "pinctrl-moore.h"
-
-@@ -105,7 +106,7 @@ static int mtk_pinconf_get(struct pinctr
- {
- struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
- u32 param = pinconf_to_config_param(*config);
-- int val, val2, err, reg, ret = 1;
-+ int val, val2, err, pullup, reg, ret = 1;
- const struct mtk_pin_desc *desc;
-
- desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
-@@ -114,7 +115,13 @@ static int mtk_pinconf_get(struct pinctr
-
- switch (param) {
- case PIN_CONFIG_BIAS_DISABLE:
-- if (hw->soc->bias_disable_get) {
-+ if (hw->soc->bias_get_combo) {
-+ err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
-+ if (err)
-+ return err;
-+ if (ret != MTK_PUPD_SET_R1R0_00 && ret != MTK_DISABLE)
-+ return -EINVAL;
-+ } else if (hw->soc->bias_disable_get) {
- err = hw->soc->bias_disable_get(hw, desc, &ret);
- if (err)
- return err;
-@@ -123,7 +130,15 @@ static int mtk_pinconf_get(struct pinctr
- }
- break;
- case PIN_CONFIG_BIAS_PULL_UP:
-- if (hw->soc->bias_get) {
-+ if (hw->soc->bias_get_combo) {
-+ err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
-+ if (err)
-+ return err;
-+ if (ret == MTK_PUPD_SET_R1R0_00 || ret == MTK_DISABLE)
-+ return -EINVAL;
-+ if (!pullup)
-+ return -EINVAL;
-+ } else if (hw->soc->bias_get) {
- err = hw->soc->bias_get(hw, desc, 1, &ret);
- if (err)
- return err;
-@@ -132,7 +147,15 @@ static int mtk_pinconf_get(struct pinctr
- }
- break;
- case PIN_CONFIG_BIAS_PULL_DOWN:
-- if (hw->soc->bias_get) {
-+ if (hw->soc->bias_get_combo) {
-+ err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
-+ if (err)
-+ return err;
-+ if (ret == MTK_PUPD_SET_R1R0_00 || ret == MTK_DISABLE)
-+ return -EINVAL;
-+ if (pullup)
-+ return -EINVAL;
-+ } else if (hw->soc->bias_get) {
- err = hw->soc->bias_get(hw, desc, 0, &ret);
- if (err)
- return err;
-@@ -235,7 +258,11 @@ static int mtk_pinconf_set(struct pinctr
-
- switch (param) {
- case PIN_CONFIG_BIAS_DISABLE:
-- if (hw->soc->bias_disable_set) {
-+ if (hw->soc->bias_set_combo) {
-+ err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
-+ if (err)
-+ return err;
-+ } else if (hw->soc->bias_disable_set) {
- err = hw->soc->bias_disable_set(hw, desc);
- if (err)
- return err;
-@@ -244,7 +271,11 @@ static int mtk_pinconf_set(struct pinctr
- }
- break;
- case PIN_CONFIG_BIAS_PULL_UP:
-- if (hw->soc->bias_set) {
-+ if (hw->soc->bias_set_combo) {
-+ err = hw->soc->bias_set_combo(hw, desc, 1, arg);
-+ if (err)
-+ return err;
-+ } else if (hw->soc->bias_set) {
- err = hw->soc->bias_set(hw, desc, 1);
- if (err)
- return err;
-@@ -253,7 +284,11 @@ static int mtk_pinconf_set(struct pinctr
- }
- break;
- case PIN_CONFIG_BIAS_PULL_DOWN:
-- if (hw->soc->bias_set) {
-+ if (hw->soc->bias_set_combo) {
-+ err = hw->soc->bias_set_combo(hw, desc, 0, arg);
-+ if (err)
-+ return err;
-+ } else if (hw->soc->bias_set) {
- err = hw->soc->bias_set(hw, desc, 0);
- if (err)
- return err;
+++ /dev/null
-From f167da186acf90847e1a6d3716e253825a6218ec Mon Sep 17 00:00:00 2001
-From: Randy Dunlap <rdunlap@infradead.org>
-Date: Thu, 12 Jan 2023 22:44:49 -0800
-Subject: [PATCH 01/42] thermal/drivers/mtk_thermal: Fix kernel-doc function
- name
-
-Use the correct function name in a kernel-doc comment to prevent
-a warning:
-
-drivers/thermal/mtk_thermal.c:562: warning: expecting prototype for raw_to_mcelsius(). Prototype was for raw_to_mcelsius_v1() instead
-
-Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
-Cc: "Rafael J. Wysocki" <rafael@kernel.org>
-Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
-Cc: Amit Kucheria <amitk@kernel.org>
-Cc: Zhang Rui <rui.zhang@intel.com>
-Cc: Matthias Brugger <matthias.bgg@gmail.com>
-Cc: linux-pm@vger.kernel.org
-Cc: linux-arm-kernel@lists.infradead.org
-Cc: linux-mediatek@lists.infradead.org
-Link: https://lore.kernel.org/r/20230113064449.15061-1-rdunlap@infradead.org
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
----
- drivers/thermal/mtk_thermal.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/thermal/mtk_thermal.c
-+++ b/drivers/thermal/mtk_thermal.c
-@@ -550,7 +550,7 @@ static const struct mtk_thermal_data mt8
- };
-
- /**
-- * raw_to_mcelsius - convert a raw ADC value to mcelsius
-+ * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
- * @mt: The thermal controller
- * @sensno: sensor number
- * @raw: raw ADC value
+++ /dev/null
-From 255509232417ee71fd606cb957d44cf6544f0c43 Mon Sep 17 00:00:00 2001
-From: ye xingchen <ye.xingchen@zte.com.cn>
-Date: Wed, 18 Jan 2023 16:37:47 +0800
-Subject: [PATCH 02/42] thermal/drivers/mtk_thermal: 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: ye xingchen <ye.xingchen@zte.com.cn>
-Link: https://lore.kernel.org/r/202301181637472073620@zte.com.cn
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
----
- drivers/thermal/mtk_thermal.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
---- a/drivers/thermal/mtk_thermal.c
-+++ b/drivers/thermal/mtk_thermal.c
-@@ -990,7 +990,6 @@ static int mtk_thermal_probe(struct plat
- int ret, i, ctrl_id;
- struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
- struct mtk_thermal *mt;
-- struct resource *res;
- u64 auxadc_phys_base, apmixed_phys_base;
- struct thermal_zone_device *tzdev;
- void __iomem *apmixed_base, *auxadc_base;
-@@ -1009,8 +1008,7 @@ static int mtk_thermal_probe(struct plat
- if (IS_ERR(mt->clk_auxadc))
- return PTR_ERR(mt->clk_auxadc);
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- mt->thermal_base = devm_ioremap_resource(&pdev->dev, res);
-+ mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
- if (IS_ERR(mt->thermal_base))
- return PTR_ERR(mt->thermal_base);
-
+++ /dev/null
-From ca86dbd309ba03bef38ae91f037e2030bb671ab7 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 18 Jan 2023 15:40:39 +0000
-Subject: [PATCH 03/42] thermal/drivers/mtk: Use function pointer for
- raw_to_mcelsius
-
-Instead of having if-else logic selecting either raw_to_mcelsius_v1 or
-raw_to_mcelsius_v2 in mtk_thermal_bank_temperature introduce a function
-pointer raw_to_mcelsius to struct mtk_thermal which is initialized in the
-probe function.
-
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
-Link: https://lore.kernel.org/r/69c17529e8418da3eec703dde31e1b01e5b0f7e8.1674055882.git.daniel@makrotopia.org
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
----
- drivers/thermal/mtk_thermal.c | 17 ++++++++++-------
- 1 file changed, 10 insertions(+), 7 deletions(-)
-
---- a/drivers/thermal/mtk_thermal.c
-+++ b/drivers/thermal/mtk_thermal.c
-@@ -292,6 +292,8 @@ struct mtk_thermal {
-
- const struct mtk_thermal_data *conf;
- struct mtk_thermal_bank banks[MAX_NUM_ZONES];
-+
-+ int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
- };
-
- /* MT8183 thermal sensor data */
-@@ -656,13 +658,9 @@ static int mtk_thermal_bank_temperature(
- for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
- raw = readl(mt->thermal_base + conf->msr[i]);
-
-- if (mt->conf->version == MTK_THERMAL_V1) {
-- temp = raw_to_mcelsius_v1(
-- mt, conf->bank_data[bank->id].sensors[i], raw);
-- } else {
-- temp = raw_to_mcelsius_v2(
-- mt, conf->bank_data[bank->id].sensors[i], raw);
-- }
-+ temp = mt->raw_to_mcelsius(
-+ mt, conf->bank_data[bank->id].sensors[i], raw);
-+
-
- /*
- * The first read of a sensor often contains very high bogus
-@@ -1073,6 +1071,11 @@ static int mtk_thermal_probe(struct plat
- mtk_thermal_release_periodic_ts(mt, auxadc_base);
- }
-
-+ if (mt->conf->version == MTK_THERMAL_V1)
-+ mt->raw_to_mcelsius = raw_to_mcelsius_v1;
-+ else
-+ mt->raw_to_mcelsius = raw_to_mcelsius_v2;
-+
- for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
- for (i = 0; i < mt->conf->num_banks; i++)
- mtk_thermal_init_bank(mt, i, apmixed_phys_base,
+++ /dev/null
-From aec1d89dccc7cba04fdb3e52dfda328f3302ba17 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 18 Jan 2023 15:40:58 +0000
-Subject: [PATCH 04/42] thermal/drivers/mtk: Add support for MT7986 and MT7981
-
-Add support for V3 generation thermal found in MT7986 and MT7981 SoCs.
-Brings code to assign values from efuse as well as new function to
-convert raw temperature to millidegree celsius, as found in MediaTek's
-SDK sources (but cleaned up and de-duplicated)
-
-[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/baf36c7eef477aae1f8f2653b6c29e2caf48475b
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/2d341fc45266217249586eb4bd3be3ac4ca83a12.1674055882.git.daniel@makrotopia.org
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
----
- drivers/thermal/mtk_thermal.c | 128 ++++++++++++++++++++++++++++++++--
- 1 file changed, 124 insertions(+), 4 deletions(-)
-
---- a/drivers/thermal/mtk_thermal.c
-+++ b/drivers/thermal/mtk_thermal.c
-@@ -150,6 +150,20 @@
- #define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1)
- #define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
-
-+/*
-+ * Layout of the fuses providing the calibration data
-+ * These macros can be used for MT7981 and MT7986.
-+ */
-+#define CALIB_BUF0_ADC_GE_V3(x) (((x) >> 0) & 0x3ff)
-+#define CALIB_BUF0_DEGC_CALI_V3(x) (((x) >> 20) & 0x3f)
-+#define CALIB_BUF0_O_SLOPE_V3(x) (((x) >> 26) & 0x3f)
-+#define CALIB_BUF1_VTS_TS1_V3(x) (((x) >> 0) & 0x1ff)
-+#define CALIB_BUF1_VTS_TS2_V3(x) (((x) >> 21) & 0x1ff)
-+#define CALIB_BUF1_VTS_TSABB_V3(x) (((x) >> 9) & 0x1ff)
-+#define CALIB_BUF1_VALID_V3(x) (((x) >> 18) & 0x1)
-+#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
-+#define CALIB_BUF1_ID_V3(x) (((x) >> 20) & 0x1)
-+
- enum {
- VTS1,
- VTS2,
-@@ -163,6 +177,7 @@ enum {
- enum mtk_thermal_version {
- MTK_THERMAL_V1 = 1,
- MTK_THERMAL_V2,
-+ MTK_THERMAL_V3,
- };
-
- /* MT2701 thermal sensors */
-@@ -245,6 +260,27 @@ enum mtk_thermal_version {
- /* The calibration coefficient of sensor */
- #define MT8183_CALIBRATION 153
-
-+/* AUXADC channel 11 is used for the temperature sensors */
-+#define MT7986_TEMP_AUXADC_CHANNEL 11
-+
-+/* The total number of temperature sensors in the MT7986 */
-+#define MT7986_NUM_SENSORS 1
-+
-+/* The number of banks in the MT7986 */
-+#define MT7986_NUM_ZONES 1
-+
-+/* The number of sensing points per bank */
-+#define MT7986_NUM_SENSORS_PER_ZONE 1
-+
-+/* MT7986 thermal sensors */
-+#define MT7986_TS1 0
-+
-+/* The number of controller in the MT7986 */
-+#define MT7986_NUM_CONTROLLER 1
-+
-+/* The calibration coefficient of sensor */
-+#define MT7986_CALIBRATION 165
-+
- struct mtk_thermal;
-
- struct thermal_bank_cfg {
-@@ -388,6 +424,14 @@ static const int mt7622_mux_values[MT762
- static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
- static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
-
-+/* MT7986 thermal sensor data */
-+static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
-+static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
-+static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
-+static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
-+static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
-+static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
-+
- /*
- * The MT8173 thermal controller has four banks. Each bank can read up to
- * four temperature sensors simultaneously. The MT8173 has a total of 5
-@@ -551,6 +595,30 @@ static const struct mtk_thermal_data mt8
- .version = MTK_THERMAL_V1,
- };
-
-+/*
-+ * MT7986 uses AUXADC Channel 11 for raw data access.
-+ */
-+static const struct mtk_thermal_data mt7986_thermal_data = {
-+ .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
-+ .num_banks = MT7986_NUM_ZONES,
-+ .num_sensors = MT7986_NUM_SENSORS,
-+ .vts_index = mt7986_vts_index,
-+ .cali_val = MT7986_CALIBRATION,
-+ .num_controller = MT7986_NUM_CONTROLLER,
-+ .controller_offset = mt7986_tc_offset,
-+ .need_switch_bank = true,
-+ .bank_data = {
-+ {
-+ .num_sensors = 1,
-+ .sensors = mt7986_bank_data,
-+ },
-+ },
-+ .msr = mt7986_msr,
-+ .adcpnp = mt7986_adcpnp,
-+ .sensor_mux_values = mt7986_mux_values,
-+ .version = MTK_THERMAL_V3,
-+};
-+
- /**
- * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
- * @mt: The thermal controller
-@@ -605,6 +673,22 @@ static int raw_to_mcelsius_v2(struct mtk
- return (format_2 - tmp) * 100;
- }
-
-+static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
-+{
-+ s32 tmp;
-+
-+ if (raw == 0)
-+ return 0;
-+
-+ raw &= 0xfff;
-+ tmp = 100000 * 15 / 16 * 10000;
-+ tmp /= 4096 - 512 + mt->adc_ge;
-+ tmp /= 1490;
-+ tmp *= raw - mt->vts[sensno] - 2900;
-+
-+ return mt->degc_cali * 500 - tmp;
-+}
-+
- /**
- * mtk_thermal_get_bank - get bank
- * @bank: The bank
-@@ -885,6 +969,25 @@ static int mtk_thermal_extract_efuse_v2(
- return 0;
- }
-
-+static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
-+{
-+ if (!CALIB_BUF1_VALID_V3(buf[1]))
-+ return -EINVAL;
-+
-+ mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
-+ mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
-+ mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
-+ mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
-+ mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
-+ mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
-+ mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
-+
-+ if (CALIB_BUF1_ID_V3(buf[1]) == 0)
-+ mt->o_slope = 0;
-+
-+ return 0;
-+}
-+
- static int mtk_thermal_get_calibration_data(struct device *dev,
- struct mtk_thermal *mt)
- {
-@@ -895,6 +998,7 @@ static int mtk_thermal_get_calibration_d
-
- /* Start with default values */
- mt->adc_ge = 512;
-+ mt->adc_oe = 512;
- for (i = 0; i < mt->conf->num_sensors; i++)
- mt->vts[i] = 260;
- mt->degc_cali = 40;
-@@ -920,10 +1024,20 @@ static int mtk_thermal_get_calibration_d
- goto out;
- }
-
-- if (mt->conf->version == MTK_THERMAL_V1)
-+ switch (mt->conf->version) {
-+ case MTK_THERMAL_V1:
- ret = mtk_thermal_extract_efuse_v1(mt, buf);
-- else
-+ break;
-+ case MTK_THERMAL_V2:
- ret = mtk_thermal_extract_efuse_v2(mt, buf);
-+ break;
-+ case MTK_THERMAL_V3:
-+ ret = mtk_thermal_extract_efuse_v3(mt, buf);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ break;
-+ }
-
- if (ret) {
- dev_info(dev, "Device not calibrated, using default calibration values\n");
-@@ -954,6 +1068,10 @@ static const struct of_device_id mtk_the
- .data = (void *)&mt7622_thermal_data,
- },
- {
-+ .compatible = "mediatek,mt7986-thermal",
-+ .data = (void *)&mt7986_thermal_data,
-+ },
-+ {
- .compatible = "mediatek,mt8183-thermal",
- .data = (void *)&mt8183_thermal_data,
- }, {
-@@ -1066,15 +1184,17 @@ static int mtk_thermal_probe(struct plat
- goto err_disable_clk_auxadc;
- }
-
-- if (mt->conf->version == MTK_THERMAL_V2) {
-+ if (mt->conf->version != MTK_THERMAL_V1) {
- mtk_thermal_turn_on_buffer(apmixed_base);
- mtk_thermal_release_periodic_ts(mt, auxadc_base);
- }
-
- if (mt->conf->version == MTK_THERMAL_V1)
- mt->raw_to_mcelsius = raw_to_mcelsius_v1;
-- else
-+ else if (mt->conf->version == MTK_THERMAL_V2)
- mt->raw_to_mcelsius = raw_to_mcelsius_v2;
-+ else
-+ mt->raw_to_mcelsius = raw_to_mcelsius_v3;
-
- for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
- for (i = 0; i < mt->conf->num_banks; i++)
+++ /dev/null
-From 5e3aac197a74914ccec2732a89c29d960730d28f Mon Sep 17 00:00:00 2001
-From: Balsam CHIHI <bchihi@baylibre.com>
-Date: Thu, 9 Feb 2023 11:56:23 +0100
-Subject: [PATCH 05/42] thermal/drivers/mediatek: Relocate driver to mediatek
- folder
-
-Add MediaTek proprietary folder to upstream more thermal zone and cooler
-drivers, relocate the original thermal controller driver to it, and rename it
-as "auxadc_thermal.c" to show its purpose more clearly.
-
-Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230209105628.50294-2-bchihi@baylibre.com
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/thermal/Kconfig | 14 ++++---------
- drivers/thermal/Makefile | 2 +-
- drivers/thermal/mediatek/Kconfig | 21 +++++++++++++++++++
- drivers/thermal/mediatek/Makefile | 1 +
- .../auxadc_thermal.c} | 2 +-
- 5 files changed, 28 insertions(+), 12 deletions(-)
- create mode 100644 drivers/thermal/mediatek/Kconfig
- create mode 100644 drivers/thermal/mediatek/Makefile
- rename drivers/thermal/{mtk_thermal.c => mediatek/auxadc_thermal.c} (99%)
-
---- a/drivers/thermal/Kconfig
-+++ b/drivers/thermal/Kconfig
-@@ -412,16 +412,10 @@ config DA9062_THERMAL
- zone.
- Compatible with the DA9062 and DA9061 PMICs.
-
--config MTK_THERMAL
-- tristate "Temperature sensor driver for mediatek SoCs"
-- depends on ARCH_MEDIATEK || COMPILE_TEST
-- depends on HAS_IOMEM
-- depends on NVMEM || NVMEM=n
-- depends on RESET_CONTROLLER
-- default y
-- help
-- Enable this option if you want to have support for thermal management
-- controller present in Mediatek SoCs
-+menu "Mediatek thermal drivers"
-+depends on ARCH_MEDIATEK || COMPILE_TEST
-+source "drivers/thermal/mediatek/Kconfig"
-+endmenu
-
- config AMLOGIC_THERMAL
- tristate "Amlogic Thermal Support"
---- a/drivers/thermal/Makefile
-+++ b/drivers/thermal/Makefile
-@@ -55,7 +55,7 @@ obj-y += st/
- obj-y += qcom/
- obj-y += tegra/
- obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
--obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
-+obj-y += mediatek/
- obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
- obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
- obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o
---- /dev/null
-+++ b/drivers/thermal/mediatek/Kconfig
-@@ -0,0 +1,21 @@
-+config MTK_THERMAL
-+ tristate "MediaTek thermal drivers"
-+ depends on THERMAL_OF
-+ help
-+ This is the option for MediaTek thermal software solutions.
-+ Please enable corresponding options to get temperature
-+ information from thermal sensors or turn on throttle
-+ mechaisms for thermal mitigation.
-+
-+if MTK_THERMAL
-+
-+config MTK_SOC_THERMAL
-+ tristate "AUXADC temperature sensor driver for MediaTek SoCs"
-+ depends on HAS_IOMEM
-+ help
-+ Enable this option if you want to get SoC temperature
-+ information for MediaTek platforms.
-+ This driver configures thermal controllers to collect
-+ temperature via AUXADC interface.
-+
-+endif
---- /dev/null
-+++ b/drivers/thermal/mediatek/Makefile
-@@ -0,0 +1 @@
-+obj-$(CONFIG_MTK_SOC_THERMAL) += auxadc_thermal.o
---- a/drivers/thermal/mtk_thermal.c
-+++ /dev/null
-@@ -1,1254 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-only
--/*
-- * Copyright (c) 2015 MediaTek Inc.
-- * Author: Hanyi Wu <hanyi.wu@mediatek.com>
-- * Sascha Hauer <s.hauer@pengutronix.de>
-- * Dawei Chien <dawei.chien@mediatek.com>
-- * Louis Yu <louis.yu@mediatek.com>
-- */
--
--#include <linux/clk.h>
--#include <linux/delay.h>
--#include <linux/interrupt.h>
--#include <linux/kernel.h>
--#include <linux/module.h>
--#include <linux/nvmem-consumer.h>
--#include <linux/of.h>
--#include <linux/of_address.h>
--#include <linux/of_device.h>
--#include <linux/platform_device.h>
--#include <linux/slab.h>
--#include <linux/io.h>
--#include <linux/thermal.h>
--#include <linux/reset.h>
--#include <linux/types.h>
--
--#include "thermal_hwmon.h"
--
--/* AUXADC Registers */
--#define AUXADC_CON1_SET_V 0x008
--#define AUXADC_CON1_CLR_V 0x00c
--#define AUXADC_CON2_V 0x010
--#define AUXADC_DATA(channel) (0x14 + (channel) * 4)
--
--#define APMIXED_SYS_TS_CON1 0x604
--
--/* Thermal Controller Registers */
--#define TEMP_MONCTL0 0x000
--#define TEMP_MONCTL1 0x004
--#define TEMP_MONCTL2 0x008
--#define TEMP_MONIDET0 0x014
--#define TEMP_MONIDET1 0x018
--#define TEMP_MSRCTL0 0x038
--#define TEMP_MSRCTL1 0x03c
--#define TEMP_AHBPOLL 0x040
--#define TEMP_AHBTO 0x044
--#define TEMP_ADCPNP0 0x048
--#define TEMP_ADCPNP1 0x04c
--#define TEMP_ADCPNP2 0x050
--#define TEMP_ADCPNP3 0x0b4
--
--#define TEMP_ADCMUX 0x054
--#define TEMP_ADCEN 0x060
--#define TEMP_PNPMUXADDR 0x064
--#define TEMP_ADCMUXADDR 0x068
--#define TEMP_ADCENADDR 0x074
--#define TEMP_ADCVALIDADDR 0x078
--#define TEMP_ADCVOLTADDR 0x07c
--#define TEMP_RDCTRL 0x080
--#define TEMP_ADCVALIDMASK 0x084
--#define TEMP_ADCVOLTAGESHIFT 0x088
--#define TEMP_ADCWRITECTRL 0x08c
--#define TEMP_MSR0 0x090
--#define TEMP_MSR1 0x094
--#define TEMP_MSR2 0x098
--#define TEMP_MSR3 0x0B8
--
--#define TEMP_SPARE0 0x0f0
--
--#define TEMP_ADCPNP0_1 0x148
--#define TEMP_ADCPNP1_1 0x14c
--#define TEMP_ADCPNP2_1 0x150
--#define TEMP_MSR0_1 0x190
--#define TEMP_MSR1_1 0x194
--#define TEMP_MSR2_1 0x198
--#define TEMP_ADCPNP3_1 0x1b4
--#define TEMP_MSR3_1 0x1B8
--
--#define PTPCORESEL 0x400
--
--#define TEMP_MONCTL1_PERIOD_UNIT(x) ((x) & 0x3ff)
--
--#define TEMP_MONCTL2_FILTER_INTERVAL(x) (((x) & 0x3ff) << 16)
--#define TEMP_MONCTL2_SENSOR_INTERVAL(x) ((x) & 0x3ff)
--
--#define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x) (x)
--
--#define TEMP_ADCWRITECTRL_ADC_PNP_WRITE BIT(0)
--#define TEMP_ADCWRITECTRL_ADC_MUX_WRITE BIT(1)
--
--#define TEMP_ADCVALIDMASK_VALID_HIGH BIT(5)
--#define TEMP_ADCVALIDMASK_VALID_POS(bit) (bit)
--
--/* MT8173 thermal sensors */
--#define MT8173_TS1 0
--#define MT8173_TS2 1
--#define MT8173_TS3 2
--#define MT8173_TS4 3
--#define MT8173_TSABB 4
--
--/* AUXADC channel 11 is used for the temperature sensors */
--#define MT8173_TEMP_AUXADC_CHANNEL 11
--
--/* The total number of temperature sensors in the MT8173 */
--#define MT8173_NUM_SENSORS 5
--
--/* The number of banks in the MT8173 */
--#define MT8173_NUM_ZONES 4
--
--/* The number of sensing points per bank */
--#define MT8173_NUM_SENSORS_PER_ZONE 4
--
--/* The number of controller in the MT8173 */
--#define MT8173_NUM_CONTROLLER 1
--
--/* The calibration coefficient of sensor */
--#define MT8173_CALIBRATION 165
--
--/*
-- * Layout of the fuses providing the calibration data
-- * These macros could be used for MT8183, MT8173, MT2701, and MT2712.
-- * MT8183 has 6 sensors and needs 6 VTS calibration data.
-- * MT8173 has 5 sensors and needs 5 VTS calibration data.
-- * MT2701 has 3 sensors and needs 3 VTS calibration data.
-- * MT2712 has 4 sensors and needs 4 VTS calibration data.
-- */
--#define CALIB_BUF0_VALID_V1 BIT(0)
--#define CALIB_BUF1_ADC_GE_V1(x) (((x) >> 22) & 0x3ff)
--#define CALIB_BUF0_VTS_TS1_V1(x) (((x) >> 17) & 0x1ff)
--#define CALIB_BUF0_VTS_TS2_V1(x) (((x) >> 8) & 0x1ff)
--#define CALIB_BUF1_VTS_TS3_V1(x) (((x) >> 0) & 0x1ff)
--#define CALIB_BUF2_VTS_TS4_V1(x) (((x) >> 23) & 0x1ff)
--#define CALIB_BUF2_VTS_TS5_V1(x) (((x) >> 5) & 0x1ff)
--#define CALIB_BUF2_VTS_TSABB_V1(x) (((x) >> 14) & 0x1ff)
--#define CALIB_BUF0_DEGC_CALI_V1(x) (((x) >> 1) & 0x3f)
--#define CALIB_BUF0_O_SLOPE_V1(x) (((x) >> 26) & 0x3f)
--#define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1)
--#define CALIB_BUF1_ID_V1(x) (((x) >> 9) & 0x1)
--
--/*
-- * Layout of the fuses providing the calibration data
-- * These macros could be used for MT7622.
-- */
--#define CALIB_BUF0_ADC_OE_V2(x) (((x) >> 22) & 0x3ff)
--#define CALIB_BUF0_ADC_GE_V2(x) (((x) >> 12) & 0x3ff)
--#define CALIB_BUF0_DEGC_CALI_V2(x) (((x) >> 6) & 0x3f)
--#define CALIB_BUF0_O_SLOPE_V2(x) (((x) >> 0) & 0x3f)
--#define CALIB_BUF1_VTS_TS1_V2(x) (((x) >> 23) & 0x1ff)
--#define CALIB_BUF1_VTS_TS2_V2(x) (((x) >> 14) & 0x1ff)
--#define CALIB_BUF1_VTS_TSABB_V2(x) (((x) >> 5) & 0x1ff)
--#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1)
--#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
--
--/*
-- * Layout of the fuses providing the calibration data
-- * These macros can be used for MT7981 and MT7986.
-- */
--#define CALIB_BUF0_ADC_GE_V3(x) (((x) >> 0) & 0x3ff)
--#define CALIB_BUF0_DEGC_CALI_V3(x) (((x) >> 20) & 0x3f)
--#define CALIB_BUF0_O_SLOPE_V3(x) (((x) >> 26) & 0x3f)
--#define CALIB_BUF1_VTS_TS1_V3(x) (((x) >> 0) & 0x1ff)
--#define CALIB_BUF1_VTS_TS2_V3(x) (((x) >> 21) & 0x1ff)
--#define CALIB_BUF1_VTS_TSABB_V3(x) (((x) >> 9) & 0x1ff)
--#define CALIB_BUF1_VALID_V3(x) (((x) >> 18) & 0x1)
--#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
--#define CALIB_BUF1_ID_V3(x) (((x) >> 20) & 0x1)
--
--enum {
-- VTS1,
-- VTS2,
-- VTS3,
-- VTS4,
-- VTS5,
-- VTSABB,
-- MAX_NUM_VTS,
--};
--
--enum mtk_thermal_version {
-- MTK_THERMAL_V1 = 1,
-- MTK_THERMAL_V2,
-- MTK_THERMAL_V3,
--};
--
--/* MT2701 thermal sensors */
--#define MT2701_TS1 0
--#define MT2701_TS2 1
--#define MT2701_TSABB 2
--
--/* AUXADC channel 11 is used for the temperature sensors */
--#define MT2701_TEMP_AUXADC_CHANNEL 11
--
--/* The total number of temperature sensors in the MT2701 */
--#define MT2701_NUM_SENSORS 3
--
--/* The number of sensing points per bank */
--#define MT2701_NUM_SENSORS_PER_ZONE 3
--
--/* The number of controller in the MT2701 */
--#define MT2701_NUM_CONTROLLER 1
--
--/* The calibration coefficient of sensor */
--#define MT2701_CALIBRATION 165
--
--/* MT2712 thermal sensors */
--#define MT2712_TS1 0
--#define MT2712_TS2 1
--#define MT2712_TS3 2
--#define MT2712_TS4 3
--
--/* AUXADC channel 11 is used for the temperature sensors */
--#define MT2712_TEMP_AUXADC_CHANNEL 11
--
--/* The total number of temperature sensors in the MT2712 */
--#define MT2712_NUM_SENSORS 4
--
--/* The number of sensing points per bank */
--#define MT2712_NUM_SENSORS_PER_ZONE 4
--
--/* The number of controller in the MT2712 */
--#define MT2712_NUM_CONTROLLER 1
--
--/* The calibration coefficient of sensor */
--#define MT2712_CALIBRATION 165
--
--#define MT7622_TEMP_AUXADC_CHANNEL 11
--#define MT7622_NUM_SENSORS 1
--#define MT7622_NUM_ZONES 1
--#define MT7622_NUM_SENSORS_PER_ZONE 1
--#define MT7622_TS1 0
--#define MT7622_NUM_CONTROLLER 1
--
--/* The maximum number of banks */
--#define MAX_NUM_ZONES 8
--
--/* The calibration coefficient of sensor */
--#define MT7622_CALIBRATION 165
--
--/* MT8183 thermal sensors */
--#define MT8183_TS1 0
--#define MT8183_TS2 1
--#define MT8183_TS3 2
--#define MT8183_TS4 3
--#define MT8183_TS5 4
--#define MT8183_TSABB 5
--
--/* AUXADC channel is used for the temperature sensors */
--#define MT8183_TEMP_AUXADC_CHANNEL 11
--
--/* The total number of temperature sensors in the MT8183 */
--#define MT8183_NUM_SENSORS 6
--
--/* The number of banks in the MT8183 */
--#define MT8183_NUM_ZONES 1
--
--/* The number of sensing points per bank */
--#define MT8183_NUM_SENSORS_PER_ZONE 6
--
--/* The number of controller in the MT8183 */
--#define MT8183_NUM_CONTROLLER 2
--
--/* The calibration coefficient of sensor */
--#define MT8183_CALIBRATION 153
--
--/* AUXADC channel 11 is used for the temperature sensors */
--#define MT7986_TEMP_AUXADC_CHANNEL 11
--
--/* The total number of temperature sensors in the MT7986 */
--#define MT7986_NUM_SENSORS 1
--
--/* The number of banks in the MT7986 */
--#define MT7986_NUM_ZONES 1
--
--/* The number of sensing points per bank */
--#define MT7986_NUM_SENSORS_PER_ZONE 1
--
--/* MT7986 thermal sensors */
--#define MT7986_TS1 0
--
--/* The number of controller in the MT7986 */
--#define MT7986_NUM_CONTROLLER 1
--
--/* The calibration coefficient of sensor */
--#define MT7986_CALIBRATION 165
--
--struct mtk_thermal;
--
--struct thermal_bank_cfg {
-- unsigned int num_sensors;
-- const int *sensors;
--};
--
--struct mtk_thermal_bank {
-- struct mtk_thermal *mt;
-- int id;
--};
--
--struct mtk_thermal_data {
-- s32 num_banks;
-- s32 num_sensors;
-- s32 auxadc_channel;
-- const int *vts_index;
-- const int *sensor_mux_values;
-- const int *msr;
-- const int *adcpnp;
-- const int cali_val;
-- const int num_controller;
-- const int *controller_offset;
-- bool need_switch_bank;
-- struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
-- enum mtk_thermal_version version;
--};
--
--struct mtk_thermal {
-- struct device *dev;
-- void __iomem *thermal_base;
--
-- struct clk *clk_peri_therm;
-- struct clk *clk_auxadc;
-- /* lock: for getting and putting banks */
-- struct mutex lock;
--
-- /* Calibration values */
-- s32 adc_ge;
-- s32 adc_oe;
-- s32 degc_cali;
-- s32 o_slope;
-- s32 o_slope_sign;
-- s32 vts[MAX_NUM_VTS];
--
-- const struct mtk_thermal_data *conf;
-- struct mtk_thermal_bank banks[MAX_NUM_ZONES];
--
-- int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
--};
--
--/* MT8183 thermal sensor data */
--static const int mt8183_bank_data[MT8183_NUM_SENSORS] = {
-- MT8183_TS1, MT8183_TS2, MT8183_TS3, MT8183_TS4, MT8183_TS5, MT8183_TSABB
--};
--
--static const int mt8183_msr[MT8183_NUM_SENSORS_PER_ZONE] = {
-- TEMP_MSR0_1, TEMP_MSR1_1, TEMP_MSR2_1, TEMP_MSR1, TEMP_MSR0, TEMP_MSR3_1
--};
--
--static const int mt8183_adcpnp[MT8183_NUM_SENSORS_PER_ZONE] = {
-- TEMP_ADCPNP0_1, TEMP_ADCPNP1_1, TEMP_ADCPNP2_1,
-- TEMP_ADCPNP1, TEMP_ADCPNP0, TEMP_ADCPNP3_1
--};
--
--static const int mt8183_mux_values[MT8183_NUM_SENSORS] = { 0, 1, 2, 3, 4, 0 };
--static const int mt8183_tc_offset[MT8183_NUM_CONTROLLER] = {0x0, 0x100};
--
--static const int mt8183_vts_index[MT8183_NUM_SENSORS] = {
-- VTS1, VTS2, VTS3, VTS4, VTS5, VTSABB
--};
--
--/* MT8173 thermal sensor data */
--static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
-- { MT8173_TS2, MT8173_TS3 },
-- { MT8173_TS2, MT8173_TS4 },
-- { MT8173_TS1, MT8173_TS2, MT8173_TSABB },
-- { MT8173_TS2 },
--};
--
--static const int mt8173_msr[MT8173_NUM_SENSORS_PER_ZONE] = {
-- TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
--};
--
--static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = {
-- TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
--};
--
--static const int mt8173_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
--static const int mt8173_tc_offset[MT8173_NUM_CONTROLLER] = { 0x0, };
--
--static const int mt8173_vts_index[MT8173_NUM_SENSORS] = {
-- VTS1, VTS2, VTS3, VTS4, VTSABB
--};
--
--/* MT2701 thermal sensor data */
--static const int mt2701_bank_data[MT2701_NUM_SENSORS] = {
-- MT2701_TS1, MT2701_TS2, MT2701_TSABB
--};
--
--static const int mt2701_msr[MT2701_NUM_SENSORS_PER_ZONE] = {
-- TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
--};
--
--static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = {
-- TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
--};
--
--static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 };
--static const int mt2701_tc_offset[MT2701_NUM_CONTROLLER] = { 0x0, };
--
--static const int mt2701_vts_index[MT2701_NUM_SENSORS] = {
-- VTS1, VTS2, VTS3
--};
--
--/* MT2712 thermal sensor data */
--static const int mt2712_bank_data[MT2712_NUM_SENSORS] = {
-- MT2712_TS1, MT2712_TS2, MT2712_TS3, MT2712_TS4
--};
--
--static const int mt2712_msr[MT2712_NUM_SENSORS_PER_ZONE] = {
-- TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
--};
--
--static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = {
-- TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
--};
--
--static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 };
--static const int mt2712_tc_offset[MT2712_NUM_CONTROLLER] = { 0x0, };
--
--static const int mt2712_vts_index[MT2712_NUM_SENSORS] = {
-- VTS1, VTS2, VTS3, VTS4
--};
--
--/* MT7622 thermal sensor data */
--static const int mt7622_bank_data[MT7622_NUM_SENSORS] = { MT7622_TS1, };
--static const int mt7622_msr[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
--static const int mt7622_adcpnp[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
--static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, };
--static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
--static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
--
--/* MT7986 thermal sensor data */
--static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
--static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
--static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
--static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
--static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
--static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
--
--/*
-- * The MT8173 thermal controller has four banks. Each bank can read up to
-- * four temperature sensors simultaneously. The MT8173 has a total of 5
-- * temperature sensors. We use each bank to measure a certain area of the
-- * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple
-- * areas, hence is used in different banks.
-- *
-- * The thermal core only gets the maximum temperature of all banks, so
-- * the bank concept wouldn't be necessary here. However, the SVS (Smart
-- * Voltage Scaling) unit makes its decisions based on the same bank
-- * data, and this indeed needs the temperatures of the individual banks
-- * for making better decisions.
-- */
--static const struct mtk_thermal_data mt8173_thermal_data = {
-- .auxadc_channel = MT8173_TEMP_AUXADC_CHANNEL,
-- .num_banks = MT8173_NUM_ZONES,
-- .num_sensors = MT8173_NUM_SENSORS,
-- .vts_index = mt8173_vts_index,
-- .cali_val = MT8173_CALIBRATION,
-- .num_controller = MT8173_NUM_CONTROLLER,
-- .controller_offset = mt8173_tc_offset,
-- .need_switch_bank = true,
-- .bank_data = {
-- {
-- .num_sensors = 2,
-- .sensors = mt8173_bank_data[0],
-- }, {
-- .num_sensors = 2,
-- .sensors = mt8173_bank_data[1],
-- }, {
-- .num_sensors = 3,
-- .sensors = mt8173_bank_data[2],
-- }, {
-- .num_sensors = 1,
-- .sensors = mt8173_bank_data[3],
-- },
-- },
-- .msr = mt8173_msr,
-- .adcpnp = mt8173_adcpnp,
-- .sensor_mux_values = mt8173_mux_values,
-- .version = MTK_THERMAL_V1,
--};
--
--/*
-- * The MT2701 thermal controller has one bank, which can read up to
-- * three temperature sensors simultaneously. The MT2701 has a total of 3
-- * temperature sensors.
-- *
-- * The thermal core only gets the maximum temperature of this one bank,
-- * so the bank concept wouldn't be necessary here. However, the SVS (Smart
-- * Voltage Scaling) unit makes its decisions based on the same bank
-- * data.
-- */
--static const struct mtk_thermal_data mt2701_thermal_data = {
-- .auxadc_channel = MT2701_TEMP_AUXADC_CHANNEL,
-- .num_banks = 1,
-- .num_sensors = MT2701_NUM_SENSORS,
-- .vts_index = mt2701_vts_index,
-- .cali_val = MT2701_CALIBRATION,
-- .num_controller = MT2701_NUM_CONTROLLER,
-- .controller_offset = mt2701_tc_offset,
-- .need_switch_bank = true,
-- .bank_data = {
-- {
-- .num_sensors = 3,
-- .sensors = mt2701_bank_data,
-- },
-- },
-- .msr = mt2701_msr,
-- .adcpnp = mt2701_adcpnp,
-- .sensor_mux_values = mt2701_mux_values,
-- .version = MTK_THERMAL_V1,
--};
--
--/*
-- * The MT2712 thermal controller has one bank, which can read up to
-- * four temperature sensors simultaneously. The MT2712 has a total of 4
-- * temperature sensors.
-- *
-- * The thermal core only gets the maximum temperature of this one bank,
-- * so the bank concept wouldn't be necessary here. However, the SVS (Smart
-- * Voltage Scaling) unit makes its decisions based on the same bank
-- * data.
-- */
--static const struct mtk_thermal_data mt2712_thermal_data = {
-- .auxadc_channel = MT2712_TEMP_AUXADC_CHANNEL,
-- .num_banks = 1,
-- .num_sensors = MT2712_NUM_SENSORS,
-- .vts_index = mt2712_vts_index,
-- .cali_val = MT2712_CALIBRATION,
-- .num_controller = MT2712_NUM_CONTROLLER,
-- .controller_offset = mt2712_tc_offset,
-- .need_switch_bank = true,
-- .bank_data = {
-- {
-- .num_sensors = 4,
-- .sensors = mt2712_bank_data,
-- },
-- },
-- .msr = mt2712_msr,
-- .adcpnp = mt2712_adcpnp,
-- .sensor_mux_values = mt2712_mux_values,
-- .version = MTK_THERMAL_V1,
--};
--
--/*
-- * MT7622 have only one sensing point which uses AUXADC Channel 11 for raw data
-- * access.
-- */
--static const struct mtk_thermal_data mt7622_thermal_data = {
-- .auxadc_channel = MT7622_TEMP_AUXADC_CHANNEL,
-- .num_banks = MT7622_NUM_ZONES,
-- .num_sensors = MT7622_NUM_SENSORS,
-- .vts_index = mt7622_vts_index,
-- .cali_val = MT7622_CALIBRATION,
-- .num_controller = MT7622_NUM_CONTROLLER,
-- .controller_offset = mt7622_tc_offset,
-- .need_switch_bank = true,
-- .bank_data = {
-- {
-- .num_sensors = 1,
-- .sensors = mt7622_bank_data,
-- },
-- },
-- .msr = mt7622_msr,
-- .adcpnp = mt7622_adcpnp,
-- .sensor_mux_values = mt7622_mux_values,
-- .version = MTK_THERMAL_V2,
--};
--
--/*
-- * The MT8183 thermal controller has one bank for the current SW framework.
-- * The MT8183 has a total of 6 temperature sensors.
-- * There are two thermal controller to control the six sensor.
-- * The first one bind 2 sensor, and the other bind 4 sensors.
-- * The thermal core only gets the maximum temperature of all sensor, so
-- * the bank concept wouldn't be necessary here. However, the SVS (Smart
-- * Voltage Scaling) unit makes its decisions based on the same bank
-- * data, and this indeed needs the temperatures of the individual banks
-- * for making better decisions.
-- */
--static const struct mtk_thermal_data mt8183_thermal_data = {
-- .auxadc_channel = MT8183_TEMP_AUXADC_CHANNEL,
-- .num_banks = MT8183_NUM_ZONES,
-- .num_sensors = MT8183_NUM_SENSORS,
-- .vts_index = mt8183_vts_index,
-- .cali_val = MT8183_CALIBRATION,
-- .num_controller = MT8183_NUM_CONTROLLER,
-- .controller_offset = mt8183_tc_offset,
-- .need_switch_bank = false,
-- .bank_data = {
-- {
-- .num_sensors = 6,
-- .sensors = mt8183_bank_data,
-- },
-- },
--
-- .msr = mt8183_msr,
-- .adcpnp = mt8183_adcpnp,
-- .sensor_mux_values = mt8183_mux_values,
-- .version = MTK_THERMAL_V1,
--};
--
--/*
-- * MT7986 uses AUXADC Channel 11 for raw data access.
-- */
--static const struct mtk_thermal_data mt7986_thermal_data = {
-- .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
-- .num_banks = MT7986_NUM_ZONES,
-- .num_sensors = MT7986_NUM_SENSORS,
-- .vts_index = mt7986_vts_index,
-- .cali_val = MT7986_CALIBRATION,
-- .num_controller = MT7986_NUM_CONTROLLER,
-- .controller_offset = mt7986_tc_offset,
-- .need_switch_bank = true,
-- .bank_data = {
-- {
-- .num_sensors = 1,
-- .sensors = mt7986_bank_data,
-- },
-- },
-- .msr = mt7986_msr,
-- .adcpnp = mt7986_adcpnp,
-- .sensor_mux_values = mt7986_mux_values,
-- .version = MTK_THERMAL_V3,
--};
--
--/**
-- * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
-- * @mt: The thermal controller
-- * @sensno: sensor number
-- * @raw: raw ADC value
-- *
-- * This converts the raw ADC value to mcelsius using the SoC specific
-- * calibration constants
-- */
--static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw)
--{
-- s32 tmp;
--
-- raw &= 0xfff;
--
-- tmp = 203450520 << 3;
-- tmp /= mt->conf->cali_val + mt->o_slope;
-- tmp /= 10000 + mt->adc_ge;
-- tmp *= raw - mt->vts[sensno] - 3350;
-- tmp >>= 3;
--
-- return mt->degc_cali * 500 - tmp;
--}
--
--static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
--{
-- s32 format_1;
-- s32 format_2;
-- s32 g_oe;
-- s32 g_gain;
-- s32 g_x_roomt;
-- s32 tmp;
--
-- if (raw == 0)
-- return 0;
--
-- raw &= 0xfff;
-- g_gain = 10000 + (((mt->adc_ge - 512) * 10000) >> 12);
-- g_oe = mt->adc_oe - 512;
-- format_1 = mt->vts[VTS2] + 3105 - g_oe;
-- format_2 = (mt->degc_cali * 10) >> 1;
-- g_x_roomt = (((format_1 * 10000) >> 12) * 10000) / g_gain;
--
-- tmp = (((((raw - g_oe) * 10000) >> 12) * 10000) / g_gain) - g_x_roomt;
-- tmp = tmp * 10 * 100 / 11;
--
-- if (mt->o_slope_sign == 0)
-- tmp = tmp / (165 - mt->o_slope);
-- else
-- tmp = tmp / (165 + mt->o_slope);
--
-- return (format_2 - tmp) * 100;
--}
--
--static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
--{
-- s32 tmp;
--
-- if (raw == 0)
-- return 0;
--
-- raw &= 0xfff;
-- tmp = 100000 * 15 / 16 * 10000;
-- tmp /= 4096 - 512 + mt->adc_ge;
-- tmp /= 1490;
-- tmp *= raw - mt->vts[sensno] - 2900;
--
-- return mt->degc_cali * 500 - tmp;
--}
--
--/**
-- * mtk_thermal_get_bank - get bank
-- * @bank: The bank
-- *
-- * The bank registers are banked, we have to select a bank in the
-- * PTPCORESEL register to access it.
-- */
--static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank)
--{
-- struct mtk_thermal *mt = bank->mt;
-- u32 val;
--
-- if (mt->conf->need_switch_bank) {
-- mutex_lock(&mt->lock);
--
-- val = readl(mt->thermal_base + PTPCORESEL);
-- val &= ~0xf;
-- val |= bank->id;
-- writel(val, mt->thermal_base + PTPCORESEL);
-- }
--}
--
--/**
-- * mtk_thermal_put_bank - release bank
-- * @bank: The bank
-- *
-- * release a bank previously taken with mtk_thermal_get_bank,
-- */
--static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
--{
-- struct mtk_thermal *mt = bank->mt;
--
-- if (mt->conf->need_switch_bank)
-- mutex_unlock(&mt->lock);
--}
--
--/**
-- * mtk_thermal_bank_temperature - get the temperature of a bank
-- * @bank: The bank
-- *
-- * The temperature of a bank is considered the maximum temperature of
-- * the sensors associated to the bank.
-- */
--static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
--{
-- struct mtk_thermal *mt = bank->mt;
-- const struct mtk_thermal_data *conf = mt->conf;
-- int i, temp = INT_MIN, max = INT_MIN;
-- u32 raw;
--
-- for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
-- raw = readl(mt->thermal_base + conf->msr[i]);
--
-- temp = mt->raw_to_mcelsius(
-- mt, conf->bank_data[bank->id].sensors[i], raw);
--
--
-- /*
-- * The first read of a sensor often contains very high bogus
-- * temperature value. Filter these out so that the system does
-- * not immediately shut down.
-- */
-- if (temp > 200000)
-- temp = 0;
--
-- if (temp > max)
-- max = temp;
-- }
--
-- return max;
--}
--
--static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature)
--{
-- struct mtk_thermal *mt = tz->devdata;
-- int i;
-- int tempmax = INT_MIN;
--
-- for (i = 0; i < mt->conf->num_banks; i++) {
-- struct mtk_thermal_bank *bank = &mt->banks[i];
--
-- mtk_thermal_get_bank(bank);
--
-- tempmax = max(tempmax, mtk_thermal_bank_temperature(bank));
--
-- mtk_thermal_put_bank(bank);
-- }
--
-- *temperature = tempmax;
--
-- return 0;
--}
--
--static const struct thermal_zone_device_ops mtk_thermal_ops = {
-- .get_temp = mtk_read_temp,
--};
--
--static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
-- u32 apmixed_phys_base, u32 auxadc_phys_base,
-- int ctrl_id)
--{
-- struct mtk_thermal_bank *bank = &mt->banks[num];
-- const struct mtk_thermal_data *conf = mt->conf;
-- int i;
--
-- int offset = mt->conf->controller_offset[ctrl_id];
-- void __iomem *controller_base = mt->thermal_base + offset;
--
-- bank->id = num;
-- bank->mt = mt;
--
-- mtk_thermal_get_bank(bank);
--
-- /* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
-- writel(TEMP_MONCTL1_PERIOD_UNIT(12), controller_base + TEMP_MONCTL1);
--
-- /*
-- * filt interval is 1 * 46.540us = 46.54us,
-- * sen interval is 429 * 46.540us = 19.96ms
-- */
-- writel(TEMP_MONCTL2_FILTER_INTERVAL(1) |
-- TEMP_MONCTL2_SENSOR_INTERVAL(429),
-- controller_base + TEMP_MONCTL2);
--
-- /* poll is set to 10u */
-- writel(TEMP_AHBPOLL_ADC_POLL_INTERVAL(768),
-- controller_base + TEMP_AHBPOLL);
--
-- /* temperature sampling control, 1 sample */
-- writel(0x0, controller_base + TEMP_MSRCTL0);
--
-- /* exceed this polling time, IRQ would be inserted */
-- writel(0xffffffff, controller_base + TEMP_AHBTO);
--
-- /* number of interrupts per event, 1 is enough */
-- writel(0x0, controller_base + TEMP_MONIDET0);
-- writel(0x0, controller_base + TEMP_MONIDET1);
--
-- /*
-- * The MT8173 thermal controller does not have its own ADC. Instead it
-- * uses AHB bus accesses to control the AUXADC. To do this the thermal
-- * controller has to be programmed with the physical addresses of the
-- * AUXADC registers and with the various bit positions in the AUXADC.
-- * Also the thermal controller controls a mux in the APMIXEDSYS register
-- * space.
-- */
--
-- /*
-- * this value will be stored to TEMP_PNPMUXADDR (TEMP_SPARE0)
-- * automatically by hw
-- */
-- writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCMUX);
--
-- /* AHB address for auxadc mux selection */
-- writel(auxadc_phys_base + AUXADC_CON1_CLR_V,
-- controller_base + TEMP_ADCMUXADDR);
--
-- if (mt->conf->version == MTK_THERMAL_V1) {
-- /* AHB address for pnp sensor mux selection */
-- writel(apmixed_phys_base + APMIXED_SYS_TS_CON1,
-- controller_base + TEMP_PNPMUXADDR);
-- }
--
-- /* AHB value for auxadc enable */
-- writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCEN);
--
-- /* AHB address for auxadc enable (channel 0 immediate mode selected) */
-- writel(auxadc_phys_base + AUXADC_CON1_SET_V,
-- controller_base + TEMP_ADCENADDR);
--
-- /* AHB address for auxadc valid bit */
-- writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
-- controller_base + TEMP_ADCVALIDADDR);
--
-- /* AHB address for auxadc voltage output */
-- writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
-- controller_base + TEMP_ADCVOLTADDR);
--
-- /* read valid & voltage are at the same register */
-- writel(0x0, controller_base + TEMP_RDCTRL);
--
-- /* indicate where the valid bit is */
-- writel(TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS(12),
-- controller_base + TEMP_ADCVALIDMASK);
--
-- /* no shift */
-- writel(0x0, controller_base + TEMP_ADCVOLTAGESHIFT);
--
-- /* enable auxadc mux write transaction */
-- writel(TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
-- controller_base + TEMP_ADCWRITECTRL);
--
-- for (i = 0; i < conf->bank_data[num].num_sensors; i++)
-- writel(conf->sensor_mux_values[conf->bank_data[num].sensors[i]],
-- mt->thermal_base + conf->adcpnp[i]);
--
-- writel((1 << conf->bank_data[num].num_sensors) - 1,
-- controller_base + TEMP_MONCTL0);
--
-- writel(TEMP_ADCWRITECTRL_ADC_PNP_WRITE |
-- TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
-- controller_base + TEMP_ADCWRITECTRL);
--
-- mtk_thermal_put_bank(bank);
--}
--
--static u64 of_get_phys_base(struct device_node *np)
--{
-- u64 size64;
-- const __be32 *regaddr_p;
--
-- regaddr_p = of_get_address(np, 0, &size64, NULL);
-- if (!regaddr_p)
-- return OF_BAD_ADDR;
--
-- return of_translate_address(np, regaddr_p);
--}
--
--static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf)
--{
-- int i;
--
-- if (!(buf[0] & CALIB_BUF0_VALID_V1))
-- return -EINVAL;
--
-- mt->adc_ge = CALIB_BUF1_ADC_GE_V1(buf[1]);
--
-- for (i = 0; i < mt->conf->num_sensors; i++) {
-- switch (mt->conf->vts_index[i]) {
-- case VTS1:
-- mt->vts[VTS1] = CALIB_BUF0_VTS_TS1_V1(buf[0]);
-- break;
-- case VTS2:
-- mt->vts[VTS2] = CALIB_BUF0_VTS_TS2_V1(buf[0]);
-- break;
-- case VTS3:
-- mt->vts[VTS3] = CALIB_BUF1_VTS_TS3_V1(buf[1]);
-- break;
-- case VTS4:
-- mt->vts[VTS4] = CALIB_BUF2_VTS_TS4_V1(buf[2]);
-- break;
-- case VTS5:
-- mt->vts[VTS5] = CALIB_BUF2_VTS_TS5_V1(buf[2]);
-- break;
-- case VTSABB:
-- mt->vts[VTSABB] =
-- CALIB_BUF2_VTS_TSABB_V1(buf[2]);
-- break;
-- default:
-- break;
-- }
-- }
--
-- mt->degc_cali = CALIB_BUF0_DEGC_CALI_V1(buf[0]);
-- if (CALIB_BUF1_ID_V1(buf[1]) &
-- CALIB_BUF0_O_SLOPE_SIGN_V1(buf[0]))
-- mt->o_slope = -CALIB_BUF0_O_SLOPE_V1(buf[0]);
-- else
-- mt->o_slope = CALIB_BUF0_O_SLOPE_V1(buf[0]);
--
-- return 0;
--}
--
--static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf)
--{
-- if (!CALIB_BUF1_VALID_V2(buf[1]))
-- return -EINVAL;
--
-- mt->adc_oe = CALIB_BUF0_ADC_OE_V2(buf[0]);
-- mt->adc_ge = CALIB_BUF0_ADC_GE_V2(buf[0]);
-- mt->degc_cali = CALIB_BUF0_DEGC_CALI_V2(buf[0]);
-- mt->o_slope = CALIB_BUF0_O_SLOPE_V2(buf[0]);
-- mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V2(buf[1]);
-- mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V2(buf[1]);
-- mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V2(buf[1]);
-- mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V2(buf[1]);
--
-- return 0;
--}
--
--static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
--{
-- if (!CALIB_BUF1_VALID_V3(buf[1]))
-- return -EINVAL;
--
-- mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
-- mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
-- mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
-- mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
-- mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
-- mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
-- mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
--
-- if (CALIB_BUF1_ID_V3(buf[1]) == 0)
-- mt->o_slope = 0;
--
-- return 0;
--}
--
--static int mtk_thermal_get_calibration_data(struct device *dev,
-- struct mtk_thermal *mt)
--{
-- struct nvmem_cell *cell;
-- u32 *buf;
-- size_t len;
-- int i, ret = 0;
--
-- /* Start with default values */
-- mt->adc_ge = 512;
-- mt->adc_oe = 512;
-- for (i = 0; i < mt->conf->num_sensors; i++)
-- mt->vts[i] = 260;
-- mt->degc_cali = 40;
-- mt->o_slope = 0;
--
-- cell = nvmem_cell_get(dev, "calibration-data");
-- if (IS_ERR(cell)) {
-- if (PTR_ERR(cell) == -EPROBE_DEFER)
-- return PTR_ERR(cell);
-- return 0;
-- }
--
-- buf = (u32 *)nvmem_cell_read(cell, &len);
--
-- nvmem_cell_put(cell);
--
-- if (IS_ERR(buf))
-- return PTR_ERR(buf);
--
-- if (len < 3 * sizeof(u32)) {
-- dev_warn(dev, "invalid calibration data\n");
-- ret = -EINVAL;
-- goto out;
-- }
--
-- switch (mt->conf->version) {
-- case MTK_THERMAL_V1:
-- ret = mtk_thermal_extract_efuse_v1(mt, buf);
-- break;
-- case MTK_THERMAL_V2:
-- ret = mtk_thermal_extract_efuse_v2(mt, buf);
-- break;
-- case MTK_THERMAL_V3:
-- ret = mtk_thermal_extract_efuse_v3(mt, buf);
-- break;
-- default:
-- ret = -EINVAL;
-- break;
-- }
--
-- if (ret) {
-- dev_info(dev, "Device not calibrated, using default calibration values\n");
-- ret = 0;
-- }
--
--out:
-- kfree(buf);
--
-- return ret;
--}
--
--static const struct of_device_id mtk_thermal_of_match[] = {
-- {
-- .compatible = "mediatek,mt8173-thermal",
-- .data = (void *)&mt8173_thermal_data,
-- },
-- {
-- .compatible = "mediatek,mt2701-thermal",
-- .data = (void *)&mt2701_thermal_data,
-- },
-- {
-- .compatible = "mediatek,mt2712-thermal",
-- .data = (void *)&mt2712_thermal_data,
-- },
-- {
-- .compatible = "mediatek,mt7622-thermal",
-- .data = (void *)&mt7622_thermal_data,
-- },
-- {
-- .compatible = "mediatek,mt7986-thermal",
-- .data = (void *)&mt7986_thermal_data,
-- },
-- {
-- .compatible = "mediatek,mt8183-thermal",
-- .data = (void *)&mt8183_thermal_data,
-- }, {
-- },
--};
--MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
--
--static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base)
--{
-- int tmp;
--
-- tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1);
-- tmp &= ~(0x37);
-- tmp |= 0x1;
-- writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1);
-- udelay(200);
--}
--
--static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt,
-- void __iomem *auxadc_base)
--{
-- int tmp;
--
-- writel(0x800, auxadc_base + AUXADC_CON1_SET_V);
-- writel(0x1, mt->thermal_base + TEMP_MONCTL0);
-- tmp = readl(mt->thermal_base + TEMP_MSRCTL1);
-- writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1);
--}
--
--static int mtk_thermal_probe(struct platform_device *pdev)
--{
-- int ret, i, ctrl_id;
-- struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
-- struct mtk_thermal *mt;
-- u64 auxadc_phys_base, apmixed_phys_base;
-- struct thermal_zone_device *tzdev;
-- void __iomem *apmixed_base, *auxadc_base;
--
-- mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
-- if (!mt)
-- return -ENOMEM;
--
-- mt->conf = of_device_get_match_data(&pdev->dev);
--
-- mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
-- if (IS_ERR(mt->clk_peri_therm))
-- return PTR_ERR(mt->clk_peri_therm);
--
-- mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
-- if (IS_ERR(mt->clk_auxadc))
-- return PTR_ERR(mt->clk_auxadc);
--
-- mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
-- if (IS_ERR(mt->thermal_base))
-- return PTR_ERR(mt->thermal_base);
--
-- ret = mtk_thermal_get_calibration_data(&pdev->dev, mt);
-- if (ret)
-- return ret;
--
-- mutex_init(&mt->lock);
--
-- mt->dev = &pdev->dev;
--
-- auxadc = of_parse_phandle(np, "mediatek,auxadc", 0);
-- if (!auxadc) {
-- dev_err(&pdev->dev, "missing auxadc node\n");
-- return -ENODEV;
-- }
--
-- auxadc_base = of_iomap(auxadc, 0);
-- auxadc_phys_base = of_get_phys_base(auxadc);
--
-- of_node_put(auxadc);
--
-- if (auxadc_phys_base == OF_BAD_ADDR) {
-- dev_err(&pdev->dev, "Can't get auxadc phys address\n");
-- return -EINVAL;
-- }
--
-- apmixedsys = of_parse_phandle(np, "mediatek,apmixedsys", 0);
-- if (!apmixedsys) {
-- dev_err(&pdev->dev, "missing apmixedsys node\n");
-- return -ENODEV;
-- }
--
-- apmixed_base = of_iomap(apmixedsys, 0);
-- apmixed_phys_base = of_get_phys_base(apmixedsys);
--
-- of_node_put(apmixedsys);
--
-- if (apmixed_phys_base == OF_BAD_ADDR) {
-- dev_err(&pdev->dev, "Can't get auxadc phys address\n");
-- return -EINVAL;
-- }
--
-- ret = device_reset_optional(&pdev->dev);
-- if (ret)
-- return ret;
--
-- ret = clk_prepare_enable(mt->clk_auxadc);
-- if (ret) {
-- dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
-- return ret;
-- }
--
-- ret = clk_prepare_enable(mt->clk_peri_therm);
-- if (ret) {
-- dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
-- goto err_disable_clk_auxadc;
-- }
--
-- if (mt->conf->version != MTK_THERMAL_V1) {
-- mtk_thermal_turn_on_buffer(apmixed_base);
-- mtk_thermal_release_periodic_ts(mt, auxadc_base);
-- }
--
-- if (mt->conf->version == MTK_THERMAL_V1)
-- mt->raw_to_mcelsius = raw_to_mcelsius_v1;
-- else if (mt->conf->version == MTK_THERMAL_V2)
-- mt->raw_to_mcelsius = raw_to_mcelsius_v2;
-- else
-- mt->raw_to_mcelsius = raw_to_mcelsius_v3;
--
-- for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
-- for (i = 0; i < mt->conf->num_banks; i++)
-- mtk_thermal_init_bank(mt, i, apmixed_phys_base,
-- auxadc_phys_base, ctrl_id);
--
-- platform_set_drvdata(pdev, mt);
--
-- tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
-- &mtk_thermal_ops);
-- if (IS_ERR(tzdev)) {
-- ret = PTR_ERR(tzdev);
-- goto err_disable_clk_peri_therm;
-- }
--
-- ret = devm_thermal_add_hwmon_sysfs(tzdev);
-- if (ret)
-- dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
--
-- return 0;
--
--err_disable_clk_peri_therm:
-- clk_disable_unprepare(mt->clk_peri_therm);
--err_disable_clk_auxadc:
-- clk_disable_unprepare(mt->clk_auxadc);
--
-- return ret;
--}
--
--static int mtk_thermal_remove(struct platform_device *pdev)
--{
-- struct mtk_thermal *mt = platform_get_drvdata(pdev);
--
-- clk_disable_unprepare(mt->clk_peri_therm);
-- clk_disable_unprepare(mt->clk_auxadc);
--
-- return 0;
--}
--
--static struct platform_driver mtk_thermal_driver = {
-- .probe = mtk_thermal_probe,
-- .remove = mtk_thermal_remove,
-- .driver = {
-- .name = "mtk-thermal",
-- .of_match_table = mtk_thermal_of_match,
-- },
--};
--
--module_platform_driver(mtk_thermal_driver);
--
--MODULE_AUTHOR("Michael Kao <michael.kao@mediatek.com>");
--MODULE_AUTHOR("Louis Yu <louis.yu@mediatek.com>");
--MODULE_AUTHOR("Dawei Chien <dawei.chien@mediatek.com>");
--MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
--MODULE_AUTHOR("Hanyi Wu <hanyi.wu@mediatek.com>");
--MODULE_DESCRIPTION("Mediatek thermal driver");
--MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -0,0 +1,1254 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2015 MediaTek Inc.
-+ * Author: Hanyi Wu <hanyi.wu@mediatek.com>
-+ * Sascha Hauer <s.hauer@pengutronix.de>
-+ * Dawei Chien <dawei.chien@mediatek.com>
-+ * Louis Yu <louis.yu@mediatek.com>
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/io.h>
-+#include <linux/thermal.h>
-+#include <linux/reset.h>
-+#include <linux/types.h>
-+
-+#include "../thermal_hwmon.h"
-+
-+/* AUXADC Registers */
-+#define AUXADC_CON1_SET_V 0x008
-+#define AUXADC_CON1_CLR_V 0x00c
-+#define AUXADC_CON2_V 0x010
-+#define AUXADC_DATA(channel) (0x14 + (channel) * 4)
-+
-+#define APMIXED_SYS_TS_CON1 0x604
-+
-+/* Thermal Controller Registers */
-+#define TEMP_MONCTL0 0x000
-+#define TEMP_MONCTL1 0x004
-+#define TEMP_MONCTL2 0x008
-+#define TEMP_MONIDET0 0x014
-+#define TEMP_MONIDET1 0x018
-+#define TEMP_MSRCTL0 0x038
-+#define TEMP_MSRCTL1 0x03c
-+#define TEMP_AHBPOLL 0x040
-+#define TEMP_AHBTO 0x044
-+#define TEMP_ADCPNP0 0x048
-+#define TEMP_ADCPNP1 0x04c
-+#define TEMP_ADCPNP2 0x050
-+#define TEMP_ADCPNP3 0x0b4
-+
-+#define TEMP_ADCMUX 0x054
-+#define TEMP_ADCEN 0x060
-+#define TEMP_PNPMUXADDR 0x064
-+#define TEMP_ADCMUXADDR 0x068
-+#define TEMP_ADCENADDR 0x074
-+#define TEMP_ADCVALIDADDR 0x078
-+#define TEMP_ADCVOLTADDR 0x07c
-+#define TEMP_RDCTRL 0x080
-+#define TEMP_ADCVALIDMASK 0x084
-+#define TEMP_ADCVOLTAGESHIFT 0x088
-+#define TEMP_ADCWRITECTRL 0x08c
-+#define TEMP_MSR0 0x090
-+#define TEMP_MSR1 0x094
-+#define TEMP_MSR2 0x098
-+#define TEMP_MSR3 0x0B8
-+
-+#define TEMP_SPARE0 0x0f0
-+
-+#define TEMP_ADCPNP0_1 0x148
-+#define TEMP_ADCPNP1_1 0x14c
-+#define TEMP_ADCPNP2_1 0x150
-+#define TEMP_MSR0_1 0x190
-+#define TEMP_MSR1_1 0x194
-+#define TEMP_MSR2_1 0x198
-+#define TEMP_ADCPNP3_1 0x1b4
-+#define TEMP_MSR3_1 0x1B8
-+
-+#define PTPCORESEL 0x400
-+
-+#define TEMP_MONCTL1_PERIOD_UNIT(x) ((x) & 0x3ff)
-+
-+#define TEMP_MONCTL2_FILTER_INTERVAL(x) (((x) & 0x3ff) << 16)
-+#define TEMP_MONCTL2_SENSOR_INTERVAL(x) ((x) & 0x3ff)
-+
-+#define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x) (x)
-+
-+#define TEMP_ADCWRITECTRL_ADC_PNP_WRITE BIT(0)
-+#define TEMP_ADCWRITECTRL_ADC_MUX_WRITE BIT(1)
-+
-+#define TEMP_ADCVALIDMASK_VALID_HIGH BIT(5)
-+#define TEMP_ADCVALIDMASK_VALID_POS(bit) (bit)
-+
-+/* MT8173 thermal sensors */
-+#define MT8173_TS1 0
-+#define MT8173_TS2 1
-+#define MT8173_TS3 2
-+#define MT8173_TS4 3
-+#define MT8173_TSABB 4
-+
-+/* AUXADC channel 11 is used for the temperature sensors */
-+#define MT8173_TEMP_AUXADC_CHANNEL 11
-+
-+/* The total number of temperature sensors in the MT8173 */
-+#define MT8173_NUM_SENSORS 5
-+
-+/* The number of banks in the MT8173 */
-+#define MT8173_NUM_ZONES 4
-+
-+/* The number of sensing points per bank */
-+#define MT8173_NUM_SENSORS_PER_ZONE 4
-+
-+/* The number of controller in the MT8173 */
-+#define MT8173_NUM_CONTROLLER 1
-+
-+/* The calibration coefficient of sensor */
-+#define MT8173_CALIBRATION 165
-+
-+/*
-+ * Layout of the fuses providing the calibration data
-+ * These macros could be used for MT8183, MT8173, MT2701, and MT2712.
-+ * MT8183 has 6 sensors and needs 6 VTS calibration data.
-+ * MT8173 has 5 sensors and needs 5 VTS calibration data.
-+ * MT2701 has 3 sensors and needs 3 VTS calibration data.
-+ * MT2712 has 4 sensors and needs 4 VTS calibration data.
-+ */
-+#define CALIB_BUF0_VALID_V1 BIT(0)
-+#define CALIB_BUF1_ADC_GE_V1(x) (((x) >> 22) & 0x3ff)
-+#define CALIB_BUF0_VTS_TS1_V1(x) (((x) >> 17) & 0x1ff)
-+#define CALIB_BUF0_VTS_TS2_V1(x) (((x) >> 8) & 0x1ff)
-+#define CALIB_BUF1_VTS_TS3_V1(x) (((x) >> 0) & 0x1ff)
-+#define CALIB_BUF2_VTS_TS4_V1(x) (((x) >> 23) & 0x1ff)
-+#define CALIB_BUF2_VTS_TS5_V1(x) (((x) >> 5) & 0x1ff)
-+#define CALIB_BUF2_VTS_TSABB_V1(x) (((x) >> 14) & 0x1ff)
-+#define CALIB_BUF0_DEGC_CALI_V1(x) (((x) >> 1) & 0x3f)
-+#define CALIB_BUF0_O_SLOPE_V1(x) (((x) >> 26) & 0x3f)
-+#define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1)
-+#define CALIB_BUF1_ID_V1(x) (((x) >> 9) & 0x1)
-+
-+/*
-+ * Layout of the fuses providing the calibration data
-+ * These macros could be used for MT7622.
-+ */
-+#define CALIB_BUF0_ADC_OE_V2(x) (((x) >> 22) & 0x3ff)
-+#define CALIB_BUF0_ADC_GE_V2(x) (((x) >> 12) & 0x3ff)
-+#define CALIB_BUF0_DEGC_CALI_V2(x) (((x) >> 6) & 0x3f)
-+#define CALIB_BUF0_O_SLOPE_V2(x) (((x) >> 0) & 0x3f)
-+#define CALIB_BUF1_VTS_TS1_V2(x) (((x) >> 23) & 0x1ff)
-+#define CALIB_BUF1_VTS_TS2_V2(x) (((x) >> 14) & 0x1ff)
-+#define CALIB_BUF1_VTS_TSABB_V2(x) (((x) >> 5) & 0x1ff)
-+#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1)
-+#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
-+
-+/*
-+ * Layout of the fuses providing the calibration data
-+ * These macros can be used for MT7981 and MT7986.
-+ */
-+#define CALIB_BUF0_ADC_GE_V3(x) (((x) >> 0) & 0x3ff)
-+#define CALIB_BUF0_DEGC_CALI_V3(x) (((x) >> 20) & 0x3f)
-+#define CALIB_BUF0_O_SLOPE_V3(x) (((x) >> 26) & 0x3f)
-+#define CALIB_BUF1_VTS_TS1_V3(x) (((x) >> 0) & 0x1ff)
-+#define CALIB_BUF1_VTS_TS2_V3(x) (((x) >> 21) & 0x1ff)
-+#define CALIB_BUF1_VTS_TSABB_V3(x) (((x) >> 9) & 0x1ff)
-+#define CALIB_BUF1_VALID_V3(x) (((x) >> 18) & 0x1)
-+#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
-+#define CALIB_BUF1_ID_V3(x) (((x) >> 20) & 0x1)
-+
-+enum {
-+ VTS1,
-+ VTS2,
-+ VTS3,
-+ VTS4,
-+ VTS5,
-+ VTSABB,
-+ MAX_NUM_VTS,
-+};
-+
-+enum mtk_thermal_version {
-+ MTK_THERMAL_V1 = 1,
-+ MTK_THERMAL_V2,
-+ MTK_THERMAL_V3,
-+};
-+
-+/* MT2701 thermal sensors */
-+#define MT2701_TS1 0
-+#define MT2701_TS2 1
-+#define MT2701_TSABB 2
-+
-+/* AUXADC channel 11 is used for the temperature sensors */
-+#define MT2701_TEMP_AUXADC_CHANNEL 11
-+
-+/* The total number of temperature sensors in the MT2701 */
-+#define MT2701_NUM_SENSORS 3
-+
-+/* The number of sensing points per bank */
-+#define MT2701_NUM_SENSORS_PER_ZONE 3
-+
-+/* The number of controller in the MT2701 */
-+#define MT2701_NUM_CONTROLLER 1
-+
-+/* The calibration coefficient of sensor */
-+#define MT2701_CALIBRATION 165
-+
-+/* MT2712 thermal sensors */
-+#define MT2712_TS1 0
-+#define MT2712_TS2 1
-+#define MT2712_TS3 2
-+#define MT2712_TS4 3
-+
-+/* AUXADC channel 11 is used for the temperature sensors */
-+#define MT2712_TEMP_AUXADC_CHANNEL 11
-+
-+/* The total number of temperature sensors in the MT2712 */
-+#define MT2712_NUM_SENSORS 4
-+
-+/* The number of sensing points per bank */
-+#define MT2712_NUM_SENSORS_PER_ZONE 4
-+
-+/* The number of controller in the MT2712 */
-+#define MT2712_NUM_CONTROLLER 1
-+
-+/* The calibration coefficient of sensor */
-+#define MT2712_CALIBRATION 165
-+
-+#define MT7622_TEMP_AUXADC_CHANNEL 11
-+#define MT7622_NUM_SENSORS 1
-+#define MT7622_NUM_ZONES 1
-+#define MT7622_NUM_SENSORS_PER_ZONE 1
-+#define MT7622_TS1 0
-+#define MT7622_NUM_CONTROLLER 1
-+
-+/* The maximum number of banks */
-+#define MAX_NUM_ZONES 8
-+
-+/* The calibration coefficient of sensor */
-+#define MT7622_CALIBRATION 165
-+
-+/* MT8183 thermal sensors */
-+#define MT8183_TS1 0
-+#define MT8183_TS2 1
-+#define MT8183_TS3 2
-+#define MT8183_TS4 3
-+#define MT8183_TS5 4
-+#define MT8183_TSABB 5
-+
-+/* AUXADC channel is used for the temperature sensors */
-+#define MT8183_TEMP_AUXADC_CHANNEL 11
-+
-+/* The total number of temperature sensors in the MT8183 */
-+#define MT8183_NUM_SENSORS 6
-+
-+/* The number of banks in the MT8183 */
-+#define MT8183_NUM_ZONES 1
-+
-+/* The number of sensing points per bank */
-+#define MT8183_NUM_SENSORS_PER_ZONE 6
-+
-+/* The number of controller in the MT8183 */
-+#define MT8183_NUM_CONTROLLER 2
-+
-+/* The calibration coefficient of sensor */
-+#define MT8183_CALIBRATION 153
-+
-+/* AUXADC channel 11 is used for the temperature sensors */
-+#define MT7986_TEMP_AUXADC_CHANNEL 11
-+
-+/* The total number of temperature sensors in the MT7986 */
-+#define MT7986_NUM_SENSORS 1
-+
-+/* The number of banks in the MT7986 */
-+#define MT7986_NUM_ZONES 1
-+
-+/* The number of sensing points per bank */
-+#define MT7986_NUM_SENSORS_PER_ZONE 1
-+
-+/* MT7986 thermal sensors */
-+#define MT7986_TS1 0
-+
-+/* The number of controller in the MT7986 */
-+#define MT7986_NUM_CONTROLLER 1
-+
-+/* The calibration coefficient of sensor */
-+#define MT7986_CALIBRATION 165
-+
-+struct mtk_thermal;
-+
-+struct thermal_bank_cfg {
-+ unsigned int num_sensors;
-+ const int *sensors;
-+};
-+
-+struct mtk_thermal_bank {
-+ struct mtk_thermal *mt;
-+ int id;
-+};
-+
-+struct mtk_thermal_data {
-+ s32 num_banks;
-+ s32 num_sensors;
-+ s32 auxadc_channel;
-+ const int *vts_index;
-+ const int *sensor_mux_values;
-+ const int *msr;
-+ const int *adcpnp;
-+ const int cali_val;
-+ const int num_controller;
-+ const int *controller_offset;
-+ bool need_switch_bank;
-+ struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
-+ enum mtk_thermal_version version;
-+};
-+
-+struct mtk_thermal {
-+ struct device *dev;
-+ void __iomem *thermal_base;
-+
-+ struct clk *clk_peri_therm;
-+ struct clk *clk_auxadc;
-+ /* lock: for getting and putting banks */
-+ struct mutex lock;
-+
-+ /* Calibration values */
-+ s32 adc_ge;
-+ s32 adc_oe;
-+ s32 degc_cali;
-+ s32 o_slope;
-+ s32 o_slope_sign;
-+ s32 vts[MAX_NUM_VTS];
-+
-+ const struct mtk_thermal_data *conf;
-+ struct mtk_thermal_bank banks[MAX_NUM_ZONES];
-+
-+ int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
-+};
-+
-+/* MT8183 thermal sensor data */
-+static const int mt8183_bank_data[MT8183_NUM_SENSORS] = {
-+ MT8183_TS1, MT8183_TS2, MT8183_TS3, MT8183_TS4, MT8183_TS5, MT8183_TSABB
-+};
-+
-+static const int mt8183_msr[MT8183_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_MSR0_1, TEMP_MSR1_1, TEMP_MSR2_1, TEMP_MSR1, TEMP_MSR0, TEMP_MSR3_1
-+};
-+
-+static const int mt8183_adcpnp[MT8183_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_ADCPNP0_1, TEMP_ADCPNP1_1, TEMP_ADCPNP2_1,
-+ TEMP_ADCPNP1, TEMP_ADCPNP0, TEMP_ADCPNP3_1
-+};
-+
-+static const int mt8183_mux_values[MT8183_NUM_SENSORS] = { 0, 1, 2, 3, 4, 0 };
-+static const int mt8183_tc_offset[MT8183_NUM_CONTROLLER] = {0x0, 0x100};
-+
-+static const int mt8183_vts_index[MT8183_NUM_SENSORS] = {
-+ VTS1, VTS2, VTS3, VTS4, VTS5, VTSABB
-+};
-+
-+/* MT8173 thermal sensor data */
-+static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
-+ { MT8173_TS2, MT8173_TS3 },
-+ { MT8173_TS2, MT8173_TS4 },
-+ { MT8173_TS1, MT8173_TS2, MT8173_TSABB },
-+ { MT8173_TS2 },
-+};
-+
-+static const int mt8173_msr[MT8173_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
-+};
-+
-+static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
-+};
-+
-+static const int mt8173_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
-+static const int mt8173_tc_offset[MT8173_NUM_CONTROLLER] = { 0x0, };
-+
-+static const int mt8173_vts_index[MT8173_NUM_SENSORS] = {
-+ VTS1, VTS2, VTS3, VTS4, VTSABB
-+};
-+
-+/* MT2701 thermal sensor data */
-+static const int mt2701_bank_data[MT2701_NUM_SENSORS] = {
-+ MT2701_TS1, MT2701_TS2, MT2701_TSABB
-+};
-+
-+static const int mt2701_msr[MT2701_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
-+};
-+
-+static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
-+};
-+
-+static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 };
-+static const int mt2701_tc_offset[MT2701_NUM_CONTROLLER] = { 0x0, };
-+
-+static const int mt2701_vts_index[MT2701_NUM_SENSORS] = {
-+ VTS1, VTS2, VTS3
-+};
-+
-+/* MT2712 thermal sensor data */
-+static const int mt2712_bank_data[MT2712_NUM_SENSORS] = {
-+ MT2712_TS1, MT2712_TS2, MT2712_TS3, MT2712_TS4
-+};
-+
-+static const int mt2712_msr[MT2712_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
-+};
-+
-+static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
-+};
-+
-+static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 };
-+static const int mt2712_tc_offset[MT2712_NUM_CONTROLLER] = { 0x0, };
-+
-+static const int mt2712_vts_index[MT2712_NUM_SENSORS] = {
-+ VTS1, VTS2, VTS3, VTS4
-+};
-+
-+/* MT7622 thermal sensor data */
-+static const int mt7622_bank_data[MT7622_NUM_SENSORS] = { MT7622_TS1, };
-+static const int mt7622_msr[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
-+static const int mt7622_adcpnp[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
-+static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, };
-+static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
-+static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
-+
-+/* MT7986 thermal sensor data */
-+static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
-+static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
-+static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
-+static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
-+static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
-+static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
-+
-+/*
-+ * The MT8173 thermal controller has four banks. Each bank can read up to
-+ * four temperature sensors simultaneously. The MT8173 has a total of 5
-+ * temperature sensors. We use each bank to measure a certain area of the
-+ * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple
-+ * areas, hence is used in different banks.
-+ *
-+ * The thermal core only gets the maximum temperature of all banks, so
-+ * the bank concept wouldn't be necessary here. However, the SVS (Smart
-+ * Voltage Scaling) unit makes its decisions based on the same bank
-+ * data, and this indeed needs the temperatures of the individual banks
-+ * for making better decisions.
-+ */
-+static const struct mtk_thermal_data mt8173_thermal_data = {
-+ .auxadc_channel = MT8173_TEMP_AUXADC_CHANNEL,
-+ .num_banks = MT8173_NUM_ZONES,
-+ .num_sensors = MT8173_NUM_SENSORS,
-+ .vts_index = mt8173_vts_index,
-+ .cali_val = MT8173_CALIBRATION,
-+ .num_controller = MT8173_NUM_CONTROLLER,
-+ .controller_offset = mt8173_tc_offset,
-+ .need_switch_bank = true,
-+ .bank_data = {
-+ {
-+ .num_sensors = 2,
-+ .sensors = mt8173_bank_data[0],
-+ }, {
-+ .num_sensors = 2,
-+ .sensors = mt8173_bank_data[1],
-+ }, {
-+ .num_sensors = 3,
-+ .sensors = mt8173_bank_data[2],
-+ }, {
-+ .num_sensors = 1,
-+ .sensors = mt8173_bank_data[3],
-+ },
-+ },
-+ .msr = mt8173_msr,
-+ .adcpnp = mt8173_adcpnp,
-+ .sensor_mux_values = mt8173_mux_values,
-+ .version = MTK_THERMAL_V1,
-+};
-+
-+/*
-+ * The MT2701 thermal controller has one bank, which can read up to
-+ * three temperature sensors simultaneously. The MT2701 has a total of 3
-+ * temperature sensors.
-+ *
-+ * The thermal core only gets the maximum temperature of this one bank,
-+ * so the bank concept wouldn't be necessary here. However, the SVS (Smart
-+ * Voltage Scaling) unit makes its decisions based on the same bank
-+ * data.
-+ */
-+static const struct mtk_thermal_data mt2701_thermal_data = {
-+ .auxadc_channel = MT2701_TEMP_AUXADC_CHANNEL,
-+ .num_banks = 1,
-+ .num_sensors = MT2701_NUM_SENSORS,
-+ .vts_index = mt2701_vts_index,
-+ .cali_val = MT2701_CALIBRATION,
-+ .num_controller = MT2701_NUM_CONTROLLER,
-+ .controller_offset = mt2701_tc_offset,
-+ .need_switch_bank = true,
-+ .bank_data = {
-+ {
-+ .num_sensors = 3,
-+ .sensors = mt2701_bank_data,
-+ },
-+ },
-+ .msr = mt2701_msr,
-+ .adcpnp = mt2701_adcpnp,
-+ .sensor_mux_values = mt2701_mux_values,
-+ .version = MTK_THERMAL_V1,
-+};
-+
-+/*
-+ * The MT2712 thermal controller has one bank, which can read up to
-+ * four temperature sensors simultaneously. The MT2712 has a total of 4
-+ * temperature sensors.
-+ *
-+ * The thermal core only gets the maximum temperature of this one bank,
-+ * so the bank concept wouldn't be necessary here. However, the SVS (Smart
-+ * Voltage Scaling) unit makes its decisions based on the same bank
-+ * data.
-+ */
-+static const struct mtk_thermal_data mt2712_thermal_data = {
-+ .auxadc_channel = MT2712_TEMP_AUXADC_CHANNEL,
-+ .num_banks = 1,
-+ .num_sensors = MT2712_NUM_SENSORS,
-+ .vts_index = mt2712_vts_index,
-+ .cali_val = MT2712_CALIBRATION,
-+ .num_controller = MT2712_NUM_CONTROLLER,
-+ .controller_offset = mt2712_tc_offset,
-+ .need_switch_bank = true,
-+ .bank_data = {
-+ {
-+ .num_sensors = 4,
-+ .sensors = mt2712_bank_data,
-+ },
-+ },
-+ .msr = mt2712_msr,
-+ .adcpnp = mt2712_adcpnp,
-+ .sensor_mux_values = mt2712_mux_values,
-+ .version = MTK_THERMAL_V1,
-+};
-+
-+/*
-+ * MT7622 have only one sensing point which uses AUXADC Channel 11 for raw data
-+ * access.
-+ */
-+static const struct mtk_thermal_data mt7622_thermal_data = {
-+ .auxadc_channel = MT7622_TEMP_AUXADC_CHANNEL,
-+ .num_banks = MT7622_NUM_ZONES,
-+ .num_sensors = MT7622_NUM_SENSORS,
-+ .vts_index = mt7622_vts_index,
-+ .cali_val = MT7622_CALIBRATION,
-+ .num_controller = MT7622_NUM_CONTROLLER,
-+ .controller_offset = mt7622_tc_offset,
-+ .need_switch_bank = true,
-+ .bank_data = {
-+ {
-+ .num_sensors = 1,
-+ .sensors = mt7622_bank_data,
-+ },
-+ },
-+ .msr = mt7622_msr,
-+ .adcpnp = mt7622_adcpnp,
-+ .sensor_mux_values = mt7622_mux_values,
-+ .version = MTK_THERMAL_V2,
-+};
-+
-+/*
-+ * The MT8183 thermal controller has one bank for the current SW framework.
-+ * The MT8183 has a total of 6 temperature sensors.
-+ * There are two thermal controller to control the six sensor.
-+ * The first one bind 2 sensor, and the other bind 4 sensors.
-+ * The thermal core only gets the maximum temperature of all sensor, so
-+ * the bank concept wouldn't be necessary here. However, the SVS (Smart
-+ * Voltage Scaling) unit makes its decisions based on the same bank
-+ * data, and this indeed needs the temperatures of the individual banks
-+ * for making better decisions.
-+ */
-+static const struct mtk_thermal_data mt8183_thermal_data = {
-+ .auxadc_channel = MT8183_TEMP_AUXADC_CHANNEL,
-+ .num_banks = MT8183_NUM_ZONES,
-+ .num_sensors = MT8183_NUM_SENSORS,
-+ .vts_index = mt8183_vts_index,
-+ .cali_val = MT8183_CALIBRATION,
-+ .num_controller = MT8183_NUM_CONTROLLER,
-+ .controller_offset = mt8183_tc_offset,
-+ .need_switch_bank = false,
-+ .bank_data = {
-+ {
-+ .num_sensors = 6,
-+ .sensors = mt8183_bank_data,
-+ },
-+ },
-+
-+ .msr = mt8183_msr,
-+ .adcpnp = mt8183_adcpnp,
-+ .sensor_mux_values = mt8183_mux_values,
-+ .version = MTK_THERMAL_V1,
-+};
-+
-+/*
-+ * MT7986 uses AUXADC Channel 11 for raw data access.
-+ */
-+static const struct mtk_thermal_data mt7986_thermal_data = {
-+ .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
-+ .num_banks = MT7986_NUM_ZONES,
-+ .num_sensors = MT7986_NUM_SENSORS,
-+ .vts_index = mt7986_vts_index,
-+ .cali_val = MT7986_CALIBRATION,
-+ .num_controller = MT7986_NUM_CONTROLLER,
-+ .controller_offset = mt7986_tc_offset,
-+ .need_switch_bank = true,
-+ .bank_data = {
-+ {
-+ .num_sensors = 1,
-+ .sensors = mt7986_bank_data,
-+ },
-+ },
-+ .msr = mt7986_msr,
-+ .adcpnp = mt7986_adcpnp,
-+ .sensor_mux_values = mt7986_mux_values,
-+ .version = MTK_THERMAL_V3,
-+};
-+
-+/**
-+ * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
-+ * @mt: The thermal controller
-+ * @sensno: sensor number
-+ * @raw: raw ADC value
-+ *
-+ * This converts the raw ADC value to mcelsius using the SoC specific
-+ * calibration constants
-+ */
-+static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw)
-+{
-+ s32 tmp;
-+
-+ raw &= 0xfff;
-+
-+ tmp = 203450520 << 3;
-+ tmp /= mt->conf->cali_val + mt->o_slope;
-+ tmp /= 10000 + mt->adc_ge;
-+ tmp *= raw - mt->vts[sensno] - 3350;
-+ tmp >>= 3;
-+
-+ return mt->degc_cali * 500 - tmp;
-+}
-+
-+static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
-+{
-+ s32 format_1;
-+ s32 format_2;
-+ s32 g_oe;
-+ s32 g_gain;
-+ s32 g_x_roomt;
-+ s32 tmp;
-+
-+ if (raw == 0)
-+ return 0;
-+
-+ raw &= 0xfff;
-+ g_gain = 10000 + (((mt->adc_ge - 512) * 10000) >> 12);
-+ g_oe = mt->adc_oe - 512;
-+ format_1 = mt->vts[VTS2] + 3105 - g_oe;
-+ format_2 = (mt->degc_cali * 10) >> 1;
-+ g_x_roomt = (((format_1 * 10000) >> 12) * 10000) / g_gain;
-+
-+ tmp = (((((raw - g_oe) * 10000) >> 12) * 10000) / g_gain) - g_x_roomt;
-+ tmp = tmp * 10 * 100 / 11;
-+
-+ if (mt->o_slope_sign == 0)
-+ tmp = tmp / (165 - mt->o_slope);
-+ else
-+ tmp = tmp / (165 + mt->o_slope);
-+
-+ return (format_2 - tmp) * 100;
-+}
-+
-+static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
-+{
-+ s32 tmp;
-+
-+ if (raw == 0)
-+ return 0;
-+
-+ raw &= 0xfff;
-+ tmp = 100000 * 15 / 16 * 10000;
-+ tmp /= 4096 - 512 + mt->adc_ge;
-+ tmp /= 1490;
-+ tmp *= raw - mt->vts[sensno] - 2900;
-+
-+ return mt->degc_cali * 500 - tmp;
-+}
-+
-+/**
-+ * mtk_thermal_get_bank - get bank
-+ * @bank: The bank
-+ *
-+ * The bank registers are banked, we have to select a bank in the
-+ * PTPCORESEL register to access it.
-+ */
-+static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank)
-+{
-+ struct mtk_thermal *mt = bank->mt;
-+ u32 val;
-+
-+ if (mt->conf->need_switch_bank) {
-+ mutex_lock(&mt->lock);
-+
-+ val = readl(mt->thermal_base + PTPCORESEL);
-+ val &= ~0xf;
-+ val |= bank->id;
-+ writel(val, mt->thermal_base + PTPCORESEL);
-+ }
-+}
-+
-+/**
-+ * mtk_thermal_put_bank - release bank
-+ * @bank: The bank
-+ *
-+ * release a bank previously taken with mtk_thermal_get_bank,
-+ */
-+static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
-+{
-+ struct mtk_thermal *mt = bank->mt;
-+
-+ if (mt->conf->need_switch_bank)
-+ mutex_unlock(&mt->lock);
-+}
-+
-+/**
-+ * mtk_thermal_bank_temperature - get the temperature of a bank
-+ * @bank: The bank
-+ *
-+ * The temperature of a bank is considered the maximum temperature of
-+ * the sensors associated to the bank.
-+ */
-+static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
-+{
-+ struct mtk_thermal *mt = bank->mt;
-+ const struct mtk_thermal_data *conf = mt->conf;
-+ int i, temp = INT_MIN, max = INT_MIN;
-+ u32 raw;
-+
-+ for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
-+ raw = readl(mt->thermal_base + conf->msr[i]);
-+
-+ temp = mt->raw_to_mcelsius(
-+ mt, conf->bank_data[bank->id].sensors[i], raw);
-+
-+
-+ /*
-+ * The first read of a sensor often contains very high bogus
-+ * temperature value. Filter these out so that the system does
-+ * not immediately shut down.
-+ */
-+ if (temp > 200000)
-+ temp = 0;
-+
-+ if (temp > max)
-+ max = temp;
-+ }
-+
-+ return max;
-+}
-+
-+static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature)
-+{
-+ struct mtk_thermal *mt = tz->devdata;
-+ int i;
-+ int tempmax = INT_MIN;
-+
-+ for (i = 0; i < mt->conf->num_banks; i++) {
-+ struct mtk_thermal_bank *bank = &mt->banks[i];
-+
-+ mtk_thermal_get_bank(bank);
-+
-+ tempmax = max(tempmax, mtk_thermal_bank_temperature(bank));
-+
-+ mtk_thermal_put_bank(bank);
-+ }
-+
-+ *temperature = tempmax;
-+
-+ return 0;
-+}
-+
-+static const struct thermal_zone_device_ops mtk_thermal_ops = {
-+ .get_temp = mtk_read_temp,
-+};
-+
-+static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
-+ u32 apmixed_phys_base, u32 auxadc_phys_base,
-+ int ctrl_id)
-+{
-+ struct mtk_thermal_bank *bank = &mt->banks[num];
-+ const struct mtk_thermal_data *conf = mt->conf;
-+ int i;
-+
-+ int offset = mt->conf->controller_offset[ctrl_id];
-+ void __iomem *controller_base = mt->thermal_base + offset;
-+
-+ bank->id = num;
-+ bank->mt = mt;
-+
-+ mtk_thermal_get_bank(bank);
-+
-+ /* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
-+ writel(TEMP_MONCTL1_PERIOD_UNIT(12), controller_base + TEMP_MONCTL1);
-+
-+ /*
-+ * filt interval is 1 * 46.540us = 46.54us,
-+ * sen interval is 429 * 46.540us = 19.96ms
-+ */
-+ writel(TEMP_MONCTL2_FILTER_INTERVAL(1) |
-+ TEMP_MONCTL2_SENSOR_INTERVAL(429),
-+ controller_base + TEMP_MONCTL2);
-+
-+ /* poll is set to 10u */
-+ writel(TEMP_AHBPOLL_ADC_POLL_INTERVAL(768),
-+ controller_base + TEMP_AHBPOLL);
-+
-+ /* temperature sampling control, 1 sample */
-+ writel(0x0, controller_base + TEMP_MSRCTL0);
-+
-+ /* exceed this polling time, IRQ would be inserted */
-+ writel(0xffffffff, controller_base + TEMP_AHBTO);
-+
-+ /* number of interrupts per event, 1 is enough */
-+ writel(0x0, controller_base + TEMP_MONIDET0);
-+ writel(0x0, controller_base + TEMP_MONIDET1);
-+
-+ /*
-+ * The MT8173 thermal controller does not have its own ADC. Instead it
-+ * uses AHB bus accesses to control the AUXADC. To do this the thermal
-+ * controller has to be programmed with the physical addresses of the
-+ * AUXADC registers and with the various bit positions in the AUXADC.
-+ * Also the thermal controller controls a mux in the APMIXEDSYS register
-+ * space.
-+ */
-+
-+ /*
-+ * this value will be stored to TEMP_PNPMUXADDR (TEMP_SPARE0)
-+ * automatically by hw
-+ */
-+ writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCMUX);
-+
-+ /* AHB address for auxadc mux selection */
-+ writel(auxadc_phys_base + AUXADC_CON1_CLR_V,
-+ controller_base + TEMP_ADCMUXADDR);
-+
-+ if (mt->conf->version == MTK_THERMAL_V1) {
-+ /* AHB address for pnp sensor mux selection */
-+ writel(apmixed_phys_base + APMIXED_SYS_TS_CON1,
-+ controller_base + TEMP_PNPMUXADDR);
-+ }
-+
-+ /* AHB value for auxadc enable */
-+ writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCEN);
-+
-+ /* AHB address for auxadc enable (channel 0 immediate mode selected) */
-+ writel(auxadc_phys_base + AUXADC_CON1_SET_V,
-+ controller_base + TEMP_ADCENADDR);
-+
-+ /* AHB address for auxadc valid bit */
-+ writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
-+ controller_base + TEMP_ADCVALIDADDR);
-+
-+ /* AHB address for auxadc voltage output */
-+ writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
-+ controller_base + TEMP_ADCVOLTADDR);
-+
-+ /* read valid & voltage are at the same register */
-+ writel(0x0, controller_base + TEMP_RDCTRL);
-+
-+ /* indicate where the valid bit is */
-+ writel(TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS(12),
-+ controller_base + TEMP_ADCVALIDMASK);
-+
-+ /* no shift */
-+ writel(0x0, controller_base + TEMP_ADCVOLTAGESHIFT);
-+
-+ /* enable auxadc mux write transaction */
-+ writel(TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
-+ controller_base + TEMP_ADCWRITECTRL);
-+
-+ for (i = 0; i < conf->bank_data[num].num_sensors; i++)
-+ writel(conf->sensor_mux_values[conf->bank_data[num].sensors[i]],
-+ mt->thermal_base + conf->adcpnp[i]);
-+
-+ writel((1 << conf->bank_data[num].num_sensors) - 1,
-+ controller_base + TEMP_MONCTL0);
-+
-+ writel(TEMP_ADCWRITECTRL_ADC_PNP_WRITE |
-+ TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
-+ controller_base + TEMP_ADCWRITECTRL);
-+
-+ mtk_thermal_put_bank(bank);
-+}
-+
-+static u64 of_get_phys_base(struct device_node *np)
-+{
-+ u64 size64;
-+ const __be32 *regaddr_p;
-+
-+ regaddr_p = of_get_address(np, 0, &size64, NULL);
-+ if (!regaddr_p)
-+ return OF_BAD_ADDR;
-+
-+ return of_translate_address(np, regaddr_p);
-+}
-+
-+static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf)
-+{
-+ int i;
-+
-+ if (!(buf[0] & CALIB_BUF0_VALID_V1))
-+ return -EINVAL;
-+
-+ mt->adc_ge = CALIB_BUF1_ADC_GE_V1(buf[1]);
-+
-+ for (i = 0; i < mt->conf->num_sensors; i++) {
-+ switch (mt->conf->vts_index[i]) {
-+ case VTS1:
-+ mt->vts[VTS1] = CALIB_BUF0_VTS_TS1_V1(buf[0]);
-+ break;
-+ case VTS2:
-+ mt->vts[VTS2] = CALIB_BUF0_VTS_TS2_V1(buf[0]);
-+ break;
-+ case VTS3:
-+ mt->vts[VTS3] = CALIB_BUF1_VTS_TS3_V1(buf[1]);
-+ break;
-+ case VTS4:
-+ mt->vts[VTS4] = CALIB_BUF2_VTS_TS4_V1(buf[2]);
-+ break;
-+ case VTS5:
-+ mt->vts[VTS5] = CALIB_BUF2_VTS_TS5_V1(buf[2]);
-+ break;
-+ case VTSABB:
-+ mt->vts[VTSABB] =
-+ CALIB_BUF2_VTS_TSABB_V1(buf[2]);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ mt->degc_cali = CALIB_BUF0_DEGC_CALI_V1(buf[0]);
-+ if (CALIB_BUF1_ID_V1(buf[1]) &
-+ CALIB_BUF0_O_SLOPE_SIGN_V1(buf[0]))
-+ mt->o_slope = -CALIB_BUF0_O_SLOPE_V1(buf[0]);
-+ else
-+ mt->o_slope = CALIB_BUF0_O_SLOPE_V1(buf[0]);
-+
-+ return 0;
-+}
-+
-+static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf)
-+{
-+ if (!CALIB_BUF1_VALID_V2(buf[1]))
-+ return -EINVAL;
-+
-+ mt->adc_oe = CALIB_BUF0_ADC_OE_V2(buf[0]);
-+ mt->adc_ge = CALIB_BUF0_ADC_GE_V2(buf[0]);
-+ mt->degc_cali = CALIB_BUF0_DEGC_CALI_V2(buf[0]);
-+ mt->o_slope = CALIB_BUF0_O_SLOPE_V2(buf[0]);
-+ mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V2(buf[1]);
-+ mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V2(buf[1]);
-+ mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V2(buf[1]);
-+ mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V2(buf[1]);
-+
-+ return 0;
-+}
-+
-+static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
-+{
-+ if (!CALIB_BUF1_VALID_V3(buf[1]))
-+ return -EINVAL;
-+
-+ mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
-+ mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
-+ mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
-+ mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
-+ mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
-+ mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
-+ mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
-+
-+ if (CALIB_BUF1_ID_V3(buf[1]) == 0)
-+ mt->o_slope = 0;
-+
-+ return 0;
-+}
-+
-+static int mtk_thermal_get_calibration_data(struct device *dev,
-+ struct mtk_thermal *mt)
-+{
-+ struct nvmem_cell *cell;
-+ u32 *buf;
-+ size_t len;
-+ int i, ret = 0;
-+
-+ /* Start with default values */
-+ mt->adc_ge = 512;
-+ mt->adc_oe = 512;
-+ for (i = 0; i < mt->conf->num_sensors; i++)
-+ mt->vts[i] = 260;
-+ mt->degc_cali = 40;
-+ mt->o_slope = 0;
-+
-+ cell = nvmem_cell_get(dev, "calibration-data");
-+ if (IS_ERR(cell)) {
-+ if (PTR_ERR(cell) == -EPROBE_DEFER)
-+ return PTR_ERR(cell);
-+ return 0;
-+ }
-+
-+ buf = (u32 *)nvmem_cell_read(cell, &len);
-+
-+ nvmem_cell_put(cell);
-+
-+ if (IS_ERR(buf))
-+ return PTR_ERR(buf);
-+
-+ if (len < 3 * sizeof(u32)) {
-+ dev_warn(dev, "invalid calibration data\n");
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ switch (mt->conf->version) {
-+ case MTK_THERMAL_V1:
-+ ret = mtk_thermal_extract_efuse_v1(mt, buf);
-+ break;
-+ case MTK_THERMAL_V2:
-+ ret = mtk_thermal_extract_efuse_v2(mt, buf);
-+ break;
-+ case MTK_THERMAL_V3:
-+ ret = mtk_thermal_extract_efuse_v3(mt, buf);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ break;
-+ }
-+
-+ if (ret) {
-+ dev_info(dev, "Device not calibrated, using default calibration values\n");
-+ ret = 0;
-+ }
-+
-+out:
-+ kfree(buf);
-+
-+ return ret;
-+}
-+
-+static const struct of_device_id mtk_thermal_of_match[] = {
-+ {
-+ .compatible = "mediatek,mt8173-thermal",
-+ .data = (void *)&mt8173_thermal_data,
-+ },
-+ {
-+ .compatible = "mediatek,mt2701-thermal",
-+ .data = (void *)&mt2701_thermal_data,
-+ },
-+ {
-+ .compatible = "mediatek,mt2712-thermal",
-+ .data = (void *)&mt2712_thermal_data,
-+ },
-+ {
-+ .compatible = "mediatek,mt7622-thermal",
-+ .data = (void *)&mt7622_thermal_data,
-+ },
-+ {
-+ .compatible = "mediatek,mt7986-thermal",
-+ .data = (void *)&mt7986_thermal_data,
-+ },
-+ {
-+ .compatible = "mediatek,mt8183-thermal",
-+ .data = (void *)&mt8183_thermal_data,
-+ }, {
-+ },
-+};
-+MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
-+
-+static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base)
-+{
-+ int tmp;
-+
-+ tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1);
-+ tmp &= ~(0x37);
-+ tmp |= 0x1;
-+ writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1);
-+ udelay(200);
-+}
-+
-+static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt,
-+ void __iomem *auxadc_base)
-+{
-+ int tmp;
-+
-+ writel(0x800, auxadc_base + AUXADC_CON1_SET_V);
-+ writel(0x1, mt->thermal_base + TEMP_MONCTL0);
-+ tmp = readl(mt->thermal_base + TEMP_MSRCTL1);
-+ writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1);
-+}
-+
-+static int mtk_thermal_probe(struct platform_device *pdev)
-+{
-+ int ret, i, ctrl_id;
-+ struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
-+ struct mtk_thermal *mt;
-+ u64 auxadc_phys_base, apmixed_phys_base;
-+ struct thermal_zone_device *tzdev;
-+ void __iomem *apmixed_base, *auxadc_base;
-+
-+ mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
-+ if (!mt)
-+ return -ENOMEM;
-+
-+ mt->conf = of_device_get_match_data(&pdev->dev);
-+
-+ mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
-+ if (IS_ERR(mt->clk_peri_therm))
-+ return PTR_ERR(mt->clk_peri_therm);
-+
-+ mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
-+ if (IS_ERR(mt->clk_auxadc))
-+ return PTR_ERR(mt->clk_auxadc);
-+
-+ mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
-+ if (IS_ERR(mt->thermal_base))
-+ return PTR_ERR(mt->thermal_base);
-+
-+ ret = mtk_thermal_get_calibration_data(&pdev->dev, mt);
-+ if (ret)
-+ return ret;
-+
-+ mutex_init(&mt->lock);
-+
-+ mt->dev = &pdev->dev;
-+
-+ auxadc = of_parse_phandle(np, "mediatek,auxadc", 0);
-+ if (!auxadc) {
-+ dev_err(&pdev->dev, "missing auxadc node\n");
-+ return -ENODEV;
-+ }
-+
-+ auxadc_base = of_iomap(auxadc, 0);
-+ auxadc_phys_base = of_get_phys_base(auxadc);
-+
-+ of_node_put(auxadc);
-+
-+ if (auxadc_phys_base == OF_BAD_ADDR) {
-+ dev_err(&pdev->dev, "Can't get auxadc phys address\n");
-+ return -EINVAL;
-+ }
-+
-+ apmixedsys = of_parse_phandle(np, "mediatek,apmixedsys", 0);
-+ if (!apmixedsys) {
-+ dev_err(&pdev->dev, "missing apmixedsys node\n");
-+ return -ENODEV;
-+ }
-+
-+ apmixed_base = of_iomap(apmixedsys, 0);
-+ apmixed_phys_base = of_get_phys_base(apmixedsys);
-+
-+ of_node_put(apmixedsys);
-+
-+ if (apmixed_phys_base == OF_BAD_ADDR) {
-+ dev_err(&pdev->dev, "Can't get auxadc phys address\n");
-+ return -EINVAL;
-+ }
-+
-+ ret = device_reset_optional(&pdev->dev);
-+ if (ret)
-+ return ret;
-+
-+ ret = clk_prepare_enable(mt->clk_auxadc);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
-+ return ret;
-+ }
-+
-+ ret = clk_prepare_enable(mt->clk_peri_therm);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
-+ goto err_disable_clk_auxadc;
-+ }
-+
-+ if (mt->conf->version != MTK_THERMAL_V1) {
-+ mtk_thermal_turn_on_buffer(apmixed_base);
-+ mtk_thermal_release_periodic_ts(mt, auxadc_base);
-+ }
-+
-+ if (mt->conf->version == MTK_THERMAL_V1)
-+ mt->raw_to_mcelsius = raw_to_mcelsius_v1;
-+ else if (mt->conf->version == MTK_THERMAL_V2)
-+ mt->raw_to_mcelsius = raw_to_mcelsius_v2;
-+ else
-+ mt->raw_to_mcelsius = raw_to_mcelsius_v3;
-+
-+ for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
-+ for (i = 0; i < mt->conf->num_banks; i++)
-+ mtk_thermal_init_bank(mt, i, apmixed_phys_base,
-+ auxadc_phys_base, ctrl_id);
-+
-+ platform_set_drvdata(pdev, mt);
-+
-+ tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
-+ &mtk_thermal_ops);
-+ if (IS_ERR(tzdev)) {
-+ ret = PTR_ERR(tzdev);
-+ goto err_disable_clk_peri_therm;
-+ }
-+
-+ ret = devm_thermal_add_hwmon_sysfs(tzdev);
-+ if (ret)
-+ dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
-+
-+ return 0;
-+
-+err_disable_clk_peri_therm:
-+ clk_disable_unprepare(mt->clk_peri_therm);
-+err_disable_clk_auxadc:
-+ clk_disable_unprepare(mt->clk_auxadc);
-+
-+ return ret;
-+}
-+
-+static int mtk_thermal_remove(struct platform_device *pdev)
-+{
-+ struct mtk_thermal *mt = platform_get_drvdata(pdev);
-+
-+ clk_disable_unprepare(mt->clk_peri_therm);
-+ clk_disable_unprepare(mt->clk_auxadc);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver mtk_thermal_driver = {
-+ .probe = mtk_thermal_probe,
-+ .remove = mtk_thermal_remove,
-+ .driver = {
-+ .name = "mtk-thermal",
-+ .of_match_table = mtk_thermal_of_match,
-+ },
-+};
-+
-+module_platform_driver(mtk_thermal_driver);
-+
-+MODULE_AUTHOR("Michael Kao <michael.kao@mediatek.com>");
-+MODULE_AUTHOR("Louis Yu <louis.yu@mediatek.com>");
-+MODULE_AUTHOR("Dawei Chien <dawei.chien@mediatek.com>");
-+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-+MODULE_AUTHOR("Hanyi Wu <hanyi.wu@mediatek.com>");
-+MODULE_DESCRIPTION("Mediatek thermal driver");
-+MODULE_LICENSE("GPL v2");
+++ /dev/null
-From 325fadf27b21f7d79843c3cc282b7f3e6620ad3d Mon Sep 17 00:00:00 2001
-From: Balsam CHIHI <bchihi@baylibre.com>
-Date: Thu, 9 Feb 2023 11:56:26 +0100
-Subject: [PATCH 06/42] thermal/drivers/mediatek: Add the Low Voltage Thermal
- Sensor driver
-
-The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
-controllers contained in a thermal domain.
-
-A thermal domains can be the MCU or the AP.
-
-Each thermal domains contain up to seven controllers, each thermal
-controller handle up to four thermal sensors.
-
-The LVTS has two Finite State Machines (FSM), one to handle the
-functionin temperatures range like hot or cold temperature and another
-one to handle monitoring trip point. The FSM notifies via interrupts
-when a trip point is crossed.
-
-The interrupt is managed at the thermal controller level, so when an
-interrupt occurs, the driver has to find out which sensor triggered
-such an interrupt.
-
-The sampling of the thermal can be filtered or immediate. For the
-former, the LVTS measures several points and applies a low pass
-filter.
-
-Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-
-On MT8195 Tomato Chromebook:
-
-Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230209105628.50294-5-bchihi@baylibre.com
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/thermal/mediatek/Kconfig | 16 +
- drivers/thermal/mediatek/Makefile | 1 +
- drivers/thermal/mediatek/lvts_thermal.c | 1224 +++++++++++++++++++++++
- 3 files changed, 1241 insertions(+)
- create mode 100644 drivers/thermal/mediatek/lvts_thermal.c
-
---- a/drivers/thermal/mediatek/Kconfig
-+++ b/drivers/thermal/mediatek/Kconfig
-@@ -18,4 +18,20 @@ config MTK_SOC_THERMAL
- This driver configures thermal controllers to collect
- temperature via AUXADC interface.
-
-+config MTK_LVTS_THERMAL
-+ tristate "LVTS Thermal Driver for MediaTek SoCs"
-+ depends on HAS_IOMEM
-+ help
-+ Enable this option if you want to get SoC temperature
-+ information for supported MediaTek platforms.
-+ This driver configures LVTS (Low Voltage Thermal Sensor)
-+ thermal controllers to collect temperatures via ASIF
-+ (Analog Serial Interface).
-+
-+config MTK_LVTS_THERMAL_DEBUGFS
-+ bool "LVTS thermal debugfs"
-+ depends on MTK_LVTS_THERMAL && DEBUG_FS
-+ help
-+ Enable this option to debug the internals of the device driver.
-+
- endif
---- a/drivers/thermal/mediatek/Makefile
-+++ b/drivers/thermal/mediatek/Makefile
-@@ -1 +1,2 @@
- obj-$(CONFIG_MTK_SOC_THERMAL) += auxadc_thermal.o
-+obj-$(CONFIG_MTK_LVTS_THERMAL) += lvts_thermal.o
---- /dev/null
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -0,0 +1,1224 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Author: Balsam CHIHI <bchihi@baylibre.com>
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/delay.h>
-+#include <linux/debugfs.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/iopoll.h>
-+#include <linux/kernel.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+#include <linux/thermal.h>
-+#include <dt-bindings/thermal/mediatek,lvts-thermal.h>
-+
-+#define LVTS_MONCTL0(__base) (__base + 0x0000)
-+#define LVTS_MONCTL1(__base) (__base + 0x0004)
-+#define LVTS_MONCTL2(__base) (__base + 0x0008)
-+#define LVTS_MONINT(__base) (__base + 0x000C)
-+#define LVTS_MONINTSTS(__base) (__base + 0x0010)
-+#define LVTS_MONIDET0(__base) (__base + 0x0014)
-+#define LVTS_MONIDET1(__base) (__base + 0x0018)
-+#define LVTS_MONIDET2(__base) (__base + 0x001C)
-+#define LVTS_MONIDET3(__base) (__base + 0x0020)
-+#define LVTS_H2NTHRE(__base) (__base + 0x0024)
-+#define LVTS_HTHRE(__base) (__base + 0x0028)
-+#define LVTS_OFFSETH(__base) (__base + 0x0030)
-+#define LVTS_OFFSETL(__base) (__base + 0x0034)
-+#define LVTS_MSRCTL0(__base) (__base + 0x0038)
-+#define LVTS_MSRCTL1(__base) (__base + 0x003C)
-+#define LVTS_TSSEL(__base) (__base + 0x0040)
-+#define LVTS_CALSCALE(__base) (__base + 0x0048)
-+#define LVTS_ID(__base) (__base + 0x004C)
-+#define LVTS_CONFIG(__base) (__base + 0x0050)
-+#define LVTS_EDATA00(__base) (__base + 0x0054)
-+#define LVTS_EDATA01(__base) (__base + 0x0058)
-+#define LVTS_EDATA02(__base) (__base + 0x005C)
-+#define LVTS_EDATA03(__base) (__base + 0x0060)
-+#define LVTS_MSR0(__base) (__base + 0x0090)
-+#define LVTS_MSR1(__base) (__base + 0x0094)
-+#define LVTS_MSR2(__base) (__base + 0x0098)
-+#define LVTS_MSR3(__base) (__base + 0x009C)
-+#define LVTS_IMMD0(__base) (__base + 0x00A0)
-+#define LVTS_IMMD1(__base) (__base + 0x00A4)
-+#define LVTS_IMMD2(__base) (__base + 0x00A8)
-+#define LVTS_IMMD3(__base) (__base + 0x00AC)
-+#define LVTS_PROTCTL(__base) (__base + 0x00C0)
-+#define LVTS_PROTTA(__base) (__base + 0x00C4)
-+#define LVTS_PROTTB(__base) (__base + 0x00C8)
-+#define LVTS_PROTTC(__base) (__base + 0x00CC)
-+#define LVTS_CLKEN(__base) (__base + 0x00E4)
-+
-+#define LVTS_PERIOD_UNIT ((118 * 1000) / (256 * 38))
-+#define LVTS_GROUP_INTERVAL 1
-+#define LVTS_FILTER_INTERVAL 1
-+#define LVTS_SENSOR_INTERVAL 1
-+#define LVTS_HW_FILTER 0x2
-+#define LVTS_TSSEL_CONF 0x13121110
-+#define LVTS_CALSCALE_CONF 0x300
-+#define LVTS_MONINT_CONF 0x9FBF7BDE
-+
-+#define LVTS_INT_SENSOR0 0x0009001F
-+#define LVTS_INT_SENSOR1 0X000881F0
-+#define LVTS_INT_SENSOR2 0x00247C00
-+#define LVTS_INT_SENSOR3 0x1FC00000
-+
-+#define LVTS_SENSOR_MAX 4
-+#define LVTS_GOLDEN_TEMP_MAX 62
-+#define LVTS_GOLDEN_TEMP_DEFAULT 50
-+#define LVTS_COEFF_A -250460
-+#define LVTS_COEFF_B 250460
-+
-+#define LVTS_MSR_IMMEDIATE_MODE 0
-+#define LVTS_MSR_FILTERED_MODE 1
-+
-+#define LVTS_HW_SHUTDOWN_MT8195 105000
-+
-+static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
-+static int coeff_b = LVTS_COEFF_B;
-+
-+struct lvts_sensor_data {
-+ int dt_id;
-+};
-+
-+struct lvts_ctrl_data {
-+ struct lvts_sensor_data lvts_sensor[LVTS_SENSOR_MAX];
-+ int cal_offset[LVTS_SENSOR_MAX];
-+ int hw_tshut_temp;
-+ int num_lvts_sensor;
-+ int offset;
-+ int mode;
-+};
-+
-+struct lvts_data {
-+ const struct lvts_ctrl_data *lvts_ctrl;
-+ int num_lvts_ctrl;
-+};
-+
-+struct lvts_sensor {
-+ struct thermal_zone_device *tz;
-+ void __iomem *msr;
-+ void __iomem *base;
-+ int id;
-+ int dt_id;
-+};
-+
-+struct lvts_ctrl {
-+ struct lvts_sensor sensors[LVTS_SENSOR_MAX];
-+ u32 calibration[LVTS_SENSOR_MAX];
-+ u32 hw_tshut_raw_temp;
-+ int num_lvts_sensor;
-+ int mode;
-+ void __iomem *base;
-+};
-+
-+struct lvts_domain {
-+ struct lvts_ctrl *lvts_ctrl;
-+ struct reset_control *reset;
-+ struct clk *clk;
-+ int num_lvts_ctrl;
-+ void __iomem *base;
-+ size_t calib_len;
-+ u8 *calib;
-+#ifdef CONFIG_DEBUG_FS
-+ struct dentry *dom_dentry;
-+#endif
-+};
-+
-+#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
-+
-+#define LVTS_DEBUG_FS_REGS(__reg) \
-+{ \
-+ .name = __stringify(__reg), \
-+ .offset = __reg(0), \
-+}
-+
-+static const struct debugfs_reg32 lvts_regs[] = {
-+ LVTS_DEBUG_FS_REGS(LVTS_MONCTL0),
-+ LVTS_DEBUG_FS_REGS(LVTS_MONCTL1),
-+ LVTS_DEBUG_FS_REGS(LVTS_MONCTL2),
-+ LVTS_DEBUG_FS_REGS(LVTS_MONINT),
-+ LVTS_DEBUG_FS_REGS(LVTS_MONINTSTS),
-+ LVTS_DEBUG_FS_REGS(LVTS_MONIDET0),
-+ LVTS_DEBUG_FS_REGS(LVTS_MONIDET1),
-+ LVTS_DEBUG_FS_REGS(LVTS_MONIDET2),
-+ LVTS_DEBUG_FS_REGS(LVTS_MONIDET3),
-+ LVTS_DEBUG_FS_REGS(LVTS_H2NTHRE),
-+ LVTS_DEBUG_FS_REGS(LVTS_HTHRE),
-+ LVTS_DEBUG_FS_REGS(LVTS_OFFSETH),
-+ LVTS_DEBUG_FS_REGS(LVTS_OFFSETL),
-+ LVTS_DEBUG_FS_REGS(LVTS_MSRCTL0),
-+ LVTS_DEBUG_FS_REGS(LVTS_MSRCTL1),
-+ LVTS_DEBUG_FS_REGS(LVTS_TSSEL),
-+ LVTS_DEBUG_FS_REGS(LVTS_CALSCALE),
-+ LVTS_DEBUG_FS_REGS(LVTS_ID),
-+ LVTS_DEBUG_FS_REGS(LVTS_CONFIG),
-+ LVTS_DEBUG_FS_REGS(LVTS_EDATA00),
-+ LVTS_DEBUG_FS_REGS(LVTS_EDATA01),
-+ LVTS_DEBUG_FS_REGS(LVTS_EDATA02),
-+ LVTS_DEBUG_FS_REGS(LVTS_EDATA03),
-+ LVTS_DEBUG_FS_REGS(LVTS_MSR0),
-+ LVTS_DEBUG_FS_REGS(LVTS_MSR1),
-+ LVTS_DEBUG_FS_REGS(LVTS_MSR2),
-+ LVTS_DEBUG_FS_REGS(LVTS_MSR3),
-+ LVTS_DEBUG_FS_REGS(LVTS_IMMD0),
-+ LVTS_DEBUG_FS_REGS(LVTS_IMMD1),
-+ LVTS_DEBUG_FS_REGS(LVTS_IMMD2),
-+ LVTS_DEBUG_FS_REGS(LVTS_IMMD3),
-+ LVTS_DEBUG_FS_REGS(LVTS_PROTCTL),
-+ LVTS_DEBUG_FS_REGS(LVTS_PROTTA),
-+ LVTS_DEBUG_FS_REGS(LVTS_PROTTB),
-+ LVTS_DEBUG_FS_REGS(LVTS_PROTTC),
-+ LVTS_DEBUG_FS_REGS(LVTS_CLKEN),
-+};
-+
-+static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td)
-+{
-+ struct debugfs_regset32 *regset;
-+ struct lvts_ctrl *lvts_ctrl;
-+ struct dentry *dentry;
-+ char name[64];
-+ int i;
-+
-+ lvts_td->dom_dentry = debugfs_create_dir(dev_name(dev), NULL);
-+ if (!lvts_td->dom_dentry)
-+ return 0;
-+
-+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
-+
-+ lvts_ctrl = &lvts_td->lvts_ctrl[i];
-+
-+ sprintf(name, "controller%d", i);
-+ dentry = debugfs_create_dir(name, lvts_td->dom_dentry);
-+ if (!dentry)
-+ continue;
-+
-+ regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
-+ if (!regset)
-+ continue;
-+
-+ regset->base = lvts_ctrl->base;
-+ regset->regs = lvts_regs;
-+ regset->nregs = ARRAY_SIZE(lvts_regs);
-+
-+ debugfs_create_regset32("registers", 0400, dentry, regset);
-+ }
-+
-+ return 0;
-+}
-+
-+static void lvts_debugfs_exit(struct lvts_domain *lvts_td)
-+{
-+ debugfs_remove_recursive(lvts_td->dom_dentry);
-+}
-+
-+#else
-+
-+static inline int lvts_debugfs_init(struct device *dev,
-+ struct lvts_domain *lvts_td)
-+{
-+ return 0;
-+}
-+
-+static void lvts_debugfs_exit(struct lvts_domain *lvts_td) { }
-+
-+#endif
-+
-+static int lvts_raw_to_temp(u32 raw_temp)
-+{
-+ int temperature;
-+
-+ temperature = ((s64)(raw_temp & 0xFFFF) * LVTS_COEFF_A) >> 14;
-+ temperature += coeff_b;
-+
-+ return temperature;
-+}
-+
-+static u32 lvts_temp_to_raw(int temperature)
-+{
-+ u32 raw_temp = ((s64)(coeff_b - temperature)) << 14;
-+
-+ raw_temp = div_s64(raw_temp, -LVTS_COEFF_A);
-+
-+ return raw_temp;
-+}
-+
-+static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
-+{
-+ struct lvts_sensor *lvts_sensor = tz->devdata;
-+ void __iomem *msr = lvts_sensor->msr;
-+ u32 value;
-+
-+ /*
-+ * Measurement registers:
-+ *
-+ * LVTS_MSR[0-3] / LVTS_IMMD[0-3]
-+ *
-+ * Bits:
-+ *
-+ * 32-17: Unused
-+ * 16 : Valid temperature
-+ * 15-0 : Raw temperature
-+ */
-+ value = readl(msr);
-+
-+ /*
-+ * As the thermal zone temperature will read before the
-+ * hardware sensor is fully initialized, we have to check the
-+ * validity of the temperature returned when reading the
-+ * measurement register. The thermal controller will set the
-+ * valid bit temperature only when it is totally initialized.
-+ *
-+ * Otherwise, we may end up with garbage values out of the
-+ * functionning temperature and directly jump to a system
-+ * shutdown.
-+ */
-+ if (!(value & BIT(16)))
-+ return -EAGAIN;
-+
-+ *temp = lvts_raw_to_temp(value & 0xFFFF);
-+
-+ return 0;
-+}
-+
-+static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
-+{
-+ struct lvts_sensor *lvts_sensor = tz->devdata;
-+ void __iomem *base = lvts_sensor->base;
-+ u32 raw_low = lvts_temp_to_raw(low);
-+ u32 raw_high = lvts_temp_to_raw(high);
-+
-+ /*
-+ * Hot to normal temperature threshold
-+ *
-+ * LVTS_H2NTHRE
-+ *
-+ * Bits:
-+ *
-+ * 14-0 : Raw temperature for threshold
-+ */
-+ if (low != -INT_MAX) {
-+ dev_dbg(&tz->device, "Setting low limit temperature interrupt: %d\n", low);
-+ writel(raw_low, LVTS_H2NTHRE(base));
-+ }
-+
-+ /*
-+ * Hot temperature threshold
-+ *
-+ * LVTS_HTHRE
-+ *
-+ * Bits:
-+ *
-+ * 14-0 : Raw temperature for threshold
-+ */
-+ dev_dbg(&tz->device, "Setting high limit temperature interrupt: %d\n", high);
-+ writel(raw_high, LVTS_HTHRE(base));
-+
-+ return 0;
-+}
-+
-+static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
-+{
-+ irqreturn_t iret = IRQ_NONE;
-+ u32 value;
-+ u32 masks[] = {
-+ LVTS_INT_SENSOR0,
-+ LVTS_INT_SENSOR1,
-+ LVTS_INT_SENSOR2,
-+ LVTS_INT_SENSOR3
-+ };
-+ int i;
-+
-+ /*
-+ * Interrupt monitoring status
-+ *
-+ * LVTS_MONINTST
-+ *
-+ * Bits:
-+ *
-+ * 31 : Interrupt for stage 3
-+ * 30 : Interrupt for stage 2
-+ * 29 : Interrupt for state 1
-+ * 28 : Interrupt using filter on sensor 3
-+ *
-+ * 27 : Interrupt using immediate on sensor 3
-+ * 26 : Interrupt normal to hot on sensor 3
-+ * 25 : Interrupt high offset on sensor 3
-+ * 24 : Interrupt low offset on sensor 3
-+ *
-+ * 23 : Interrupt hot threshold on sensor 3
-+ * 22 : Interrupt cold threshold on sensor 3
-+ * 21 : Interrupt using filter on sensor 2
-+ * 20 : Interrupt using filter on sensor 1
-+ *
-+ * 19 : Interrupt using filter on sensor 0
-+ * 18 : Interrupt using immediate on sensor 2
-+ * 17 : Interrupt using immediate on sensor 1
-+ * 16 : Interrupt using immediate on sensor 0
-+ *
-+ * 15 : Interrupt device access timeout interrupt
-+ * 14 : Interrupt normal to hot on sensor 2
-+ * 13 : Interrupt high offset interrupt on sensor 2
-+ * 12 : Interrupt low offset interrupt on sensor 2
-+ *
-+ * 11 : Interrupt hot threshold on sensor 2
-+ * 10 : Interrupt cold threshold on sensor 2
-+ * 9 : Interrupt normal to hot on sensor 1
-+ * 8 : Interrupt high offset interrupt on sensor 1
-+ *
-+ * 7 : Interrupt low offset interrupt on sensor 1
-+ * 6 : Interrupt hot threshold on sensor 1
-+ * 5 : Interrupt cold threshold on sensor 1
-+ * 4 : Interrupt normal to hot on sensor 0
-+ *
-+ * 3 : Interrupt high offset interrupt on sensor 0
-+ * 2 : Interrupt low offset interrupt on sensor 0
-+ * 1 : Interrupt hot threshold on sensor 0
-+ * 0 : Interrupt cold threshold on sensor 0
-+ *
-+ * We are interested in the sensor(s) responsible of the
-+ * interrupt event. We update the thermal framework with the
-+ * thermal zone associated with the sensor. The framework will
-+ * take care of the rest whatever the kind of interrupt, we
-+ * are only interested in which sensor raised the interrupt.
-+ *
-+ * sensor 3 interrupt: 0001 1111 1100 0000 0000 0000 0000 0000
-+ * => 0x1FC00000
-+ * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000
-+ * => 0x00247C00
-+ * sensor 1 interrupt: 0000 0000 0001 0001 0000 0011 1110 0000
-+ * => 0X000881F0
-+ * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111
-+ * => 0x0009001F
-+ */
-+ value = readl(LVTS_MONINTSTS(lvts_ctrl->base));
-+
-+ /*
-+ * Let's figure out which sensors raised the interrupt
-+ *
-+ * NOTE: the masks array must be ordered with the index
-+ * corresponding to the sensor id eg. index=0, mask for
-+ * sensor0.
-+ */
-+ for (i = 0; i < ARRAY_SIZE(masks); i++) {
-+
-+ if (!(value & masks[i]))
-+ continue;
-+
-+ thermal_zone_device_update(lvts_ctrl->sensors[i].tz,
-+ THERMAL_TRIP_VIOLATED);
-+ iret = IRQ_HANDLED;
-+ }
-+
-+ /*
-+ * Write back to clear the interrupt status (W1C)
-+ */
-+ writel(value, LVTS_MONINTSTS(lvts_ctrl->base));
-+
-+ return iret;
-+}
-+
-+/*
-+ * Temperature interrupt handler. Even if the driver supports more
-+ * interrupt modes, we use the interrupt when the temperature crosses
-+ * the hot threshold the way up and the way down (modulo the
-+ * hysteresis).
-+ *
-+ * Each thermal domain has a couple of interrupts, one for hardware
-+ * reset and another one for all the thermal events happening on the
-+ * different sensors.
-+ *
-+ * The interrupt is configured for thermal events when crossing the
-+ * hot temperature limit. At each interrupt, we check in every
-+ * controller if there is an interrupt pending.
-+ */
-+static irqreturn_t lvts_irq_handler(int irq, void *data)
-+{
-+ struct lvts_domain *lvts_td = data;
-+ irqreturn_t aux, iret = IRQ_NONE;
-+ int i;
-+
-+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
-+
-+ aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl);
-+ if (aux != IRQ_HANDLED)
-+ continue;
-+
-+ iret = IRQ_HANDLED;
-+ }
-+
-+ return iret;
-+}
-+
-+static struct thermal_zone_device_ops lvts_ops = {
-+ .get_temp = lvts_get_temp,
-+ .set_trips = lvts_set_trips,
-+};
-+
-+static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
-+ const struct lvts_ctrl_data *lvts_ctrl_data)
-+{
-+ struct lvts_sensor *lvts_sensor = lvts_ctrl->sensors;
-+ void __iomem *msr_regs[] = {
-+ LVTS_MSR0(lvts_ctrl->base),
-+ LVTS_MSR1(lvts_ctrl->base),
-+ LVTS_MSR2(lvts_ctrl->base),
-+ LVTS_MSR3(lvts_ctrl->base)
-+ };
-+
-+ void __iomem *imm_regs[] = {
-+ LVTS_IMMD0(lvts_ctrl->base),
-+ LVTS_IMMD1(lvts_ctrl->base),
-+ LVTS_IMMD2(lvts_ctrl->base),
-+ LVTS_IMMD3(lvts_ctrl->base)
-+ };
-+
-+ int i;
-+
-+ for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++) {
-+
-+ int dt_id = lvts_ctrl_data->lvts_sensor[i].dt_id;
-+
-+ /*
-+ * At this point, we don't know which id matches which
-+ * sensor. Let's set arbitrally the id from the index.
-+ */
-+ lvts_sensor[i].id = i;
-+
-+ /*
-+ * The thermal zone registration will set the trip
-+ * point interrupt in the thermal controller
-+ * register. But this one will be reset in the
-+ * initialization after. So we need to post pone the
-+ * thermal zone creation after the controller is
-+ * setup. For this reason, we store the device tree
-+ * node id from the data in the sensor structure
-+ */
-+ lvts_sensor[i].dt_id = dt_id;
-+
-+ /*
-+ * We assign the base address of the thermal
-+ * controller as a back pointer. So it will be
-+ * accessible from the different thermal framework ops
-+ * as we pass the lvts_sensor pointer as thermal zone
-+ * private data.
-+ */
-+ lvts_sensor[i].base = lvts_ctrl->base;
-+
-+ /*
-+ * Each sensor has its own register address to read from.
-+ */
-+ lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
-+ imm_regs[i] : msr_regs[i];
-+ };
-+
-+ lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
-+
-+ return 0;
-+}
-+
-+/*
-+ * The efuse blob values follows the sensor enumeration per thermal
-+ * controller. The decoding of the stream is as follow:
-+ *
-+ * <--?-> <----big0 ???---> <-sensor0-> <-0->
-+ * ------------------------------------------
-+ * index in the stream: : | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 |
-+ * ------------------------------------------
-+ *
-+ * <--sensor1--><-0-> <----big1 ???---> <-sen
-+ * ------------------------------------------
-+ * | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
-+ * ------------------------------------------
-+ *
-+ * sor0-> <-0-> <-sensor1-> <-0-> ..........
-+ * ------------------------------------------
-+ * | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
-+ * ------------------------------------------
-+ *
-+ * And so on ...
-+ *
-+ * The data description gives the offset of the calibration data in
-+ * this bytes stream for each sensor.
-+ *
-+ * Each thermal controller can handle up to 4 sensors max, we don't
-+ * care if there are less as the array of calibration is sized to 4
-+ * anyway. The unused sensor slot will be zeroed.
-+ */
-+static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
-+ const struct lvts_ctrl_data *lvts_ctrl_data,
-+ u8 *efuse_calibration)
-+{
-+ int i;
-+
-+ for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++)
-+ memcpy(&lvts_ctrl->calibration[i],
-+ efuse_calibration + lvts_ctrl_data->cal_offset[i], 2);
-+
-+ return 0;
-+}
-+
-+/*
-+ * The efuse bytes stream can be split into different chunk of
-+ * nvmems. This function reads and concatenate those into a single
-+ * buffer so it can be read sequentially when initializing the
-+ * calibration data.
-+ */
-+static int lvts_calibration_read(struct device *dev, struct lvts_domain *lvts_td,
-+ const struct lvts_data *lvts_data)
-+{
-+ struct device_node *np = dev_of_node(dev);
-+ struct nvmem_cell *cell;
-+ struct property *prop;
-+ const char *cell_name;
-+
-+ of_property_for_each_string(np, "nvmem-cell-names", prop, cell_name) {
-+ size_t len;
-+ u8 *efuse;
-+
-+ cell = of_nvmem_cell_get(np, cell_name);
-+ if (IS_ERR(cell)) {
-+ dev_err(dev, "Failed to get cell '%s'\n", cell_name);
-+ return PTR_ERR(cell);
-+ }
-+
-+ efuse = nvmem_cell_read(cell, &len);
-+
-+ nvmem_cell_put(cell);
-+
-+ if (IS_ERR(efuse)) {
-+ dev_err(dev, "Failed to read cell '%s'\n", cell_name);
-+ return PTR_ERR(efuse);
-+ }
-+
-+ lvts_td->calib = devm_krealloc(dev, lvts_td->calib,
-+ lvts_td->calib_len + len, GFP_KERNEL);
-+ if (!lvts_td->calib)
-+ return -ENOMEM;
-+
-+ memcpy(lvts_td->calib + lvts_td->calib_len, efuse, len);
-+
-+ lvts_td->calib_len += len;
-+
-+ kfree(efuse);
-+ }
-+
-+ return 0;
-+}
-+
-+static int lvts_golden_temp_init(struct device *dev, u32 *value)
-+{
-+ u32 gt;
-+
-+ gt = (*value) >> 24;
-+
-+ if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
-+ golden_temp = gt;
-+
-+ coeff_b = golden_temp * 500 + LVTS_COEFF_B;
-+
-+ return 0;
-+}
-+
-+static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
-+ const struct lvts_data *lvts_data)
-+{
-+ size_t size = sizeof(*lvts_td->lvts_ctrl) * lvts_data->num_lvts_ctrl;
-+ struct lvts_ctrl *lvts_ctrl;
-+ int i, ret;
-+
-+ /*
-+ * Create the calibration bytes stream from efuse data
-+ */
-+ ret = lvts_calibration_read(dev, lvts_td, lvts_data);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * The golden temp information is contained in the first chunk
-+ * of efuse data.
-+ */
-+ ret = lvts_golden_temp_init(dev, (u32 *)lvts_td->calib);
-+ if (ret)
-+ return ret;
-+
-+ lvts_ctrl = devm_kzalloc(dev, size, GFP_KERNEL);
-+ if (!lvts_ctrl)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < lvts_data->num_lvts_ctrl; i++) {
-+
-+ lvts_ctrl[i].base = lvts_td->base + lvts_data->lvts_ctrl[i].offset;
-+
-+ ret = lvts_sensor_init(dev, &lvts_ctrl[i],
-+ &lvts_data->lvts_ctrl[i]);
-+ if (ret)
-+ return ret;
-+
-+ ret = lvts_calibration_init(dev, &lvts_ctrl[i],
-+ &lvts_data->lvts_ctrl[i],
-+ lvts_td->calib);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * The mode the ctrl will use to read the temperature
-+ * (filtered or immediate)
-+ */
-+ lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode;
-+
-+ /*
-+ * The temperature to raw temperature must be done
-+ * after initializing the calibration.
-+ */
-+ lvts_ctrl[i].hw_tshut_raw_temp =
-+ lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
-+ }
-+
-+ /*
-+ * We no longer need the efuse bytes stream, let's free it
-+ */
-+ devm_kfree(dev, lvts_td->calib);
-+
-+ lvts_td->lvts_ctrl = lvts_ctrl;
-+ lvts_td->num_lvts_ctrl = lvts_data->num_lvts_ctrl;
-+
-+ return 0;
-+}
-+
-+/*
-+ * At this point the configuration register is the only place in the
-+ * driver where we write multiple values. Per hardware constraint,
-+ * each write in the configuration register must be separated by a
-+ * delay of 2 us.
-+ */
-+static void lvts_write_config(struct lvts_ctrl *lvts_ctrl, u32 *cmds, int nr_cmds)
-+{
-+ int i;
-+
-+ /*
-+ * Configuration register
-+ */
-+ for (i = 0; i < nr_cmds; i++) {
-+ writel(cmds[i], LVTS_CONFIG(lvts_ctrl->base));
-+ usleep_range(2, 4);
-+ }
-+}
-+
-+static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
-+{
-+ /*
-+ * LVTS_PROTCTL : Thermal Protection Sensor Selection
-+ *
-+ * Bits:
-+ *
-+ * 19-18 : Sensor to base the protection on
-+ * 17-16 : Strategy:
-+ * 00 : Average of 4 sensors
-+ * 01 : Max of 4 sensors
-+ * 10 : Selected sensor with bits 19-18
-+ * 11 : Reserved
-+ */
-+ writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));
-+
-+ /*
-+ * LVTS_PROTTA : Stage 1 temperature threshold
-+ * LVTS_PROTTB : Stage 2 temperature threshold
-+ * LVTS_PROTTC : Stage 3 temperature threshold
-+ *
-+ * Bits:
-+ *
-+ * 14-0: Raw temperature threshold
-+ *
-+ * writel(0x0, LVTS_PROTTA(lvts_ctrl->base));
-+ * writel(0x0, LVTS_PROTTB(lvts_ctrl->base));
-+ */
-+ writel(lvts_ctrl->hw_tshut_raw_temp, LVTS_PROTTC(lvts_ctrl->base));
-+
-+ /*
-+ * LVTS_MONINT : Interrupt configuration register
-+ *
-+ * The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS
-+ * register, except we set the bits to enable the interrupt.
-+ */
-+ writel(LVTS_MONINT_CONF, LVTS_MONINT(lvts_ctrl->base));
-+
-+ return 0;
-+}
-+
-+static int lvts_domain_reset(struct device *dev, struct reset_control *reset)
-+{
-+ int ret;
-+
-+ ret = reset_control_assert(reset);
-+ if (ret)
-+ return ret;
-+
-+ return reset_control_deassert(reset);
-+}
-+
-+/*
-+ * Enable or disable the clocks of a specified thermal controller
-+ */
-+static int lvts_ctrl_set_enable(struct lvts_ctrl *lvts_ctrl, int enable)
-+{
-+ /*
-+ * LVTS_CLKEN : Internal LVTS clock
-+ *
-+ * Bits:
-+ *
-+ * 0 : enable / disable clock
-+ */
-+ writel(enable, LVTS_CLKEN(lvts_ctrl->base));
-+
-+ return 0;
-+}
-+
-+static int lvts_ctrl_connect(struct device *dev, struct lvts_ctrl *lvts_ctrl)
-+{
-+ u32 id, cmds[] = { 0xC103FFFF, 0xC502FF55 };
-+
-+ lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
-+
-+ /*
-+ * LVTS_ID : Get ID and status of the thermal controller
-+ *
-+ * Bits:
-+ *
-+ * 0-5 : thermal controller id
-+ * 7 : thermal controller connection is valid
-+ */
-+ id = readl(LVTS_ID(lvts_ctrl->base));
-+ if (!(id & BIT(7)))
-+ return -EIO;
-+
-+ return 0;
-+}
-+
-+static int lvts_ctrl_initialize(struct device *dev, struct lvts_ctrl *lvts_ctrl)
-+{
-+ /*
-+ * Write device mask: 0xC1030000
-+ */
-+ u32 cmds[] = {
-+ 0xC1030E01, 0xC1030CFC, 0xC1030A8C, 0xC103098D, 0xC10308F1,
-+ 0xC10307A6, 0xC10306B8, 0xC1030500, 0xC1030420, 0xC1030300,
-+ 0xC1030030, 0xC10300F6, 0xC1030050, 0xC1030060, 0xC10300AC,
-+ 0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
-+ };
-+
-+ lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
-+
-+ return 0;
-+}
-+
-+static int lvts_ctrl_calibrate(struct device *dev, struct lvts_ctrl *lvts_ctrl)
-+{
-+ int i;
-+ void __iomem *lvts_edata[] = {
-+ LVTS_EDATA00(lvts_ctrl->base),
-+ LVTS_EDATA01(lvts_ctrl->base),
-+ LVTS_EDATA02(lvts_ctrl->base),
-+ LVTS_EDATA03(lvts_ctrl->base)
-+ };
-+
-+ /*
-+ * LVTS_EDATA0X : Efuse calibration reference value for sensor X
-+ *
-+ * Bits:
-+ *
-+ * 20-0 : Efuse value for normalization data
-+ */
-+ for (i = 0; i < LVTS_SENSOR_MAX; i++)
-+ writel(lvts_ctrl->calibration[i], lvts_edata[i]);
-+
-+ return 0;
-+}
-+
-+static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)
-+{
-+ u32 value;
-+
-+ /*
-+ * LVTS_TSSEL : Sensing point index numbering
-+ *
-+ * Bits:
-+ *
-+ * 31-24: ADC Sense 3
-+ * 23-16: ADC Sense 2
-+ * 15-8 : ADC Sense 1
-+ * 7-0 : ADC Sense 0
-+ */
-+ value = LVTS_TSSEL_CONF;
-+ writel(value, LVTS_TSSEL(lvts_ctrl->base));
-+
-+ /*
-+ * LVTS_CALSCALE : ADC voltage round
-+ */
-+ value = 0x300;
-+ value = LVTS_CALSCALE_CONF;
-+
-+ /*
-+ * LVTS_MSRCTL0 : Sensor filtering strategy
-+ *
-+ * Filters:
-+ *
-+ * 000 : One sample
-+ * 001 : Avg 2 samples
-+ * 010 : 4 samples, drop min and max, avg 2 samples
-+ * 011 : 6 samples, drop min and max, avg 4 samples
-+ * 100 : 10 samples, drop min and max, avg 8 samples
-+ * 101 : 18 samples, drop min and max, avg 16 samples
-+ *
-+ * Bits:
-+ *
-+ * 0-2 : Sensor0 filter
-+ * 3-5 : Sensor1 filter
-+ * 6-8 : Sensor2 filter
-+ * 9-11 : Sensor3 filter
-+ */
-+ value = LVTS_HW_FILTER << 9 | LVTS_HW_FILTER << 6 |
-+ LVTS_HW_FILTER << 3 | LVTS_HW_FILTER;
-+ writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
-+
-+ /*
-+ * LVTS_MSRCTL1 : Measurement control
-+ *
-+ * Bits:
-+ *
-+ * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
-+ * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
-+ * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
-+ * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
-+ *
-+ * That configuration will ignore the filtering and the delays
-+ * introduced below in MONCTL1 and MONCTL2
-+ */
-+ if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
-+ value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
-+ writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
-+ }
-+
-+ /*
-+ * LVTS_MONCTL1 : Period unit and group interval configuration
-+ *
-+ * The clock source of LVTS thermal controller is 26MHz.
-+ *
-+ * The period unit is a time base for all the interval delays
-+ * specified in the registers. By default we use 12. The time
-+ * conversion is done by multiplying by 256 and 1/26.10^6
-+ *
-+ * An interval delay multiplied by the period unit gives the
-+ * duration in seconds.
-+ *
-+ * - Filter interval delay is a delay between two samples of
-+ * the same sensor.
-+ *
-+ * - Sensor interval delay is a delay between two samples of
-+ * different sensors.
-+ *
-+ * - Group interval delay is a delay between different rounds.
-+ *
-+ * For example:
-+ * If Period unit = C, filter delay = 1, sensor delay = 2, group delay = 1,
-+ * and two sensors, TS1 and TS2, are in a LVTS thermal controller
-+ * and then
-+ * Period unit time = C * 1/26M * 256 = 12 * 38.46ns * 256 = 118.149us
-+ * Filter interval delay = 1 * Period unit = 118.149us
-+ * Sensor interval delay = 2 * Period unit = 236.298us
-+ * Group interval delay = 1 * Period unit = 118.149us
-+ *
-+ * TS1 TS1 ... TS1 TS2 TS2 ... TS2 TS1...
-+ * <--> Filter interval delay
-+ * <--> Sensor interval delay
-+ * <--> Group interval delay
-+ * Bits:
-+ * 29 - 20 : Group interval
-+ * 16 - 13 : Send a single interrupt when crossing the hot threshold (1)
-+ * or an interrupt everytime the hot threshold is crossed (0)
-+ * 9 - 0 : Period unit
-+ *
-+ */
-+ value = LVTS_GROUP_INTERVAL << 20 | LVTS_PERIOD_UNIT;
-+ writel(value, LVTS_MONCTL1(lvts_ctrl->base));
-+
-+ /*
-+ * LVTS_MONCTL2 : Filtering and sensor interval
-+ *
-+ * Bits:
-+ *
-+ * 25-16 : Interval unit in PERIOD_UNIT between sample on
-+ * the same sensor, filter interval
-+ * 9-0 : Interval unit in PERIOD_UNIT between each sensor
-+ *
-+ */
-+ value = LVTS_FILTER_INTERVAL << 16 | LVTS_SENSOR_INTERVAL;
-+ writel(value, LVTS_MONCTL2(lvts_ctrl->base));
-+
-+ return lvts_irq_init(lvts_ctrl);
-+}
-+
-+static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
-+{
-+ struct lvts_sensor *lvts_sensors = lvts_ctrl->sensors;
-+ struct thermal_zone_device *tz;
-+ u32 sensor_map = 0;
-+ int i;
-+
-+ for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
-+
-+ int dt_id = lvts_sensors[i].dt_id;
-+
-+ tz = devm_thermal_of_zone_register(dev, dt_id, &lvts_sensors[i],
-+ &lvts_ops);
-+ if (IS_ERR(tz)) {
-+ /*
-+ * This thermal zone is not described in the
-+ * device tree. It is not an error from the
-+ * thermal OF code POV, we just continue.
-+ */
-+ if (PTR_ERR(tz) == -ENODEV)
-+ continue;
-+
-+ return PTR_ERR(tz);
-+ }
-+
-+ /*
-+ * The thermal zone pointer will be needed in the
-+ * interrupt handler, we store it in the sensor
-+ * structure. The thermal domain structure will be
-+ * passed to the interrupt handler private data as the
-+ * interrupt is shared for all the controller
-+ * belonging to the thermal domain.
-+ */
-+ lvts_sensors[i].tz = tz;
-+
-+ /*
-+ * This sensor was correctly associated with a thermal
-+ * zone, let's set the corresponding bit in the sensor
-+ * map, so we can enable the temperature monitoring in
-+ * the hardware thermal controller.
-+ */
-+ sensor_map |= BIT(i);
-+ }
-+
-+ /*
-+ * Bits:
-+ * 9: Single point access flow
-+ * 0-3: Enable sensing point 0-3
-+ *
-+ * The initialization of the thermal zones give us
-+ * which sensor point to enable. If any thermal zone
-+ * was not described in the device tree, it won't be
-+ * enabled here in the sensor map.
-+ */
-+ writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
-+
-+ return 0;
-+}
-+
-+static int lvts_domain_init(struct device *dev, struct lvts_domain *lvts_td,
-+ const struct lvts_data *lvts_data)
-+{
-+ struct lvts_ctrl *lvts_ctrl;
-+ int i, ret;
-+
-+ ret = lvts_ctrl_init(dev, lvts_td, lvts_data);
-+ if (ret)
-+ return ret;
-+
-+ ret = lvts_domain_reset(dev, lvts_td->reset);
-+ if (ret) {
-+ dev_dbg(dev, "Failed to reset domain");
-+ return ret;
-+ }
-+
-+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
-+
-+ lvts_ctrl = &lvts_td->lvts_ctrl[i];
-+
-+ /*
-+ * Initialization steps:
-+ *
-+ * - Enable the clock
-+ * - Connect to the LVTS
-+ * - Initialize the LVTS
-+ * - Prepare the calibration data
-+ * - Select monitored sensors
-+ * [ Configure sampling ]
-+ * [ Configure the interrupt ]
-+ * - Start measurement
-+ */
-+ ret = lvts_ctrl_set_enable(lvts_ctrl, true);
-+ if (ret) {
-+ dev_dbg(dev, "Failed to enable LVTS clock");
-+ return ret;
-+ }
-+
-+ ret = lvts_ctrl_connect(dev, lvts_ctrl);
-+ if (ret) {
-+ dev_dbg(dev, "Failed to connect to LVTS controller");
-+ return ret;
-+ }
-+
-+ ret = lvts_ctrl_initialize(dev, lvts_ctrl);
-+ if (ret) {
-+ dev_dbg(dev, "Failed to initialize controller");
-+ return ret;
-+ }
-+
-+ ret = lvts_ctrl_calibrate(dev, lvts_ctrl);
-+ if (ret) {
-+ dev_dbg(dev, "Failed to calibrate controller");
-+ return ret;
-+ }
-+
-+ ret = lvts_ctrl_configure(dev, lvts_ctrl);
-+ if (ret) {
-+ dev_dbg(dev, "Failed to configure controller");
-+ return ret;
-+ }
-+
-+ ret = lvts_ctrl_start(dev, lvts_ctrl);
-+ if (ret) {
-+ dev_dbg(dev, "Failed to start controller");
-+ return ret;
-+ }
-+ }
-+
-+ return lvts_debugfs_init(dev, lvts_td);
-+}
-+
-+static int lvts_probe(struct platform_device *pdev)
-+{
-+ const struct lvts_data *lvts_data;
-+ struct lvts_domain *lvts_td;
-+ struct device *dev = &pdev->dev;
-+ struct resource *res;
-+ int irq, ret;
-+
-+ lvts_td = devm_kzalloc(dev, sizeof(*lvts_td), GFP_KERNEL);
-+ if (!lvts_td)
-+ return -ENOMEM;
-+
-+ lvts_data = of_device_get_match_data(dev);
-+
-+ lvts_td->clk = devm_clk_get_enabled(dev, NULL);
-+ if (IS_ERR(lvts_td->clk))
-+ return dev_err_probe(dev, PTR_ERR(lvts_td->clk), "Failed to retrieve clock\n");
-+
-+ res = platform_get_mem_or_io(pdev, 0);
-+ if (!res)
-+ return dev_err_probe(dev, (-ENXIO), "No IO resource\n");
-+
-+ lvts_td->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-+ if (IS_ERR(lvts_td->base))
-+ return dev_err_probe(dev, PTR_ERR(lvts_td->base), "Failed to map io resource\n");
-+
-+ lvts_td->reset = devm_reset_control_get_by_index(dev, 0);
-+ if (IS_ERR(lvts_td->reset))
-+ return dev_err_probe(dev, PTR_ERR(lvts_td->reset), "Failed to get reset control\n");
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0)
-+ return dev_err_probe(dev, irq, "No irq resource\n");
-+
-+ ret = lvts_domain_init(dev, lvts_td, lvts_data);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Failed to initialize the lvts domain\n");
-+
-+ /*
-+ * At this point the LVTS is initialized and enabled. We can
-+ * safely enable the interrupt.
-+ */
-+ ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
-+ IRQF_ONESHOT, dev_name(dev), lvts_td);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Failed to request interrupt\n");
-+
-+ platform_set_drvdata(pdev, lvts_td);
-+
-+ return 0;
-+}
-+
-+static int lvts_remove(struct platform_device *pdev)
-+{
-+ struct lvts_domain *lvts_td;
-+ int i;
-+
-+ lvts_td = platform_get_drvdata(pdev);
-+
-+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
-+ lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
-+
-+ lvts_debugfs_exit(lvts_td);
-+
-+ return 0;
-+}
-+
-+static const struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {
-+ {
-+ .cal_offset = { 0x04, 0x07 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8195_MCU_BIG_CPU0 },
-+ { .dt_id = MT8195_MCU_BIG_CPU1 }
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x0,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
-+ },
-+ {
-+ .cal_offset = { 0x0d, 0x10 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8195_MCU_BIG_CPU2 },
-+ { .dt_id = MT8195_MCU_BIG_CPU3 }
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x100,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
-+ },
-+ {
-+ .cal_offset = { 0x16, 0x19, 0x1c, 0x1f },
-+ .lvts_sensor = {
-+ { .dt_id = MT8195_MCU_LITTLE_CPU0 },
-+ { .dt_id = MT8195_MCU_LITTLE_CPU1 },
-+ { .dt_id = MT8195_MCU_LITTLE_CPU2 },
-+ { .dt_id = MT8195_MCU_LITTLE_CPU3 }
-+ },
-+ .num_lvts_sensor = 4,
-+ .offset = 0x200,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
-+ }
-+};
-+
-+static const struct lvts_data mt8195_lvts_mcu_data = {
-+ .lvts_ctrl = mt8195_lvts_data_ctrl,
-+ .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_data_ctrl),
-+};
-+
-+static const struct of_device_id lvts_of_match[] = {
-+ { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, lvts_of_match);
-+
-+static struct platform_driver lvts_driver = {
-+ .probe = lvts_probe,
-+ .remove = lvts_remove,
-+ .driver = {
-+ .name = "mtk-lvts-thermal",
-+ .of_match_table = lvts_of_match,
-+ },
-+};
-+module_platform_driver(lvts_driver);
-+
-+MODULE_AUTHOR("Balsam CHIHI <bchihi@baylibre.com>");
-+MODULE_DESCRIPTION("MediaTek LVTS Thermal Driver");
-+MODULE_LICENSE("GPL");
+++ /dev/null
-From 498e2f7a6e69dcbca24715de2b4b97569fdfeff4 Mon Sep 17 00:00:00 2001
-From: Balsam CHIHI <bchihi@baylibre.com>
-Date: Thu, 9 Feb 2023 11:56:24 +0100
-Subject: [PATCH] dt-bindings: thermal: mediatek: Add LVTS thermal controllers
-
-Add LVTS thermal controllers dt-binding definition for mt8192 and mt8195.
-
-Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20230209105628.50294-3-bchihi@baylibre.com
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- .../thermal/mediatek,lvts-thermal.yaml | 142 ++++++++++++++++++
- .../thermal/mediatek,lvts-thermal.h | 19 +++
- 2 files changed, 161 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
- create mode 100644 include/dt-bindings/thermal/mediatek,lvts-thermal.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
-@@ -0,0 +1,142 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
-+
-+maintainers:
-+ - Balsam CHIHI <bchihi@baylibre.com>
-+
-+description: |
-+ LVTS is a thermal management architecture composed of three subsystems,
-+ a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
-+ a Converter - Low Voltage Thermal Sensor converter (LVTS), and
-+ a Digital controller (LVTS_CTRL).
-+
-+properties:
-+ compatible:
-+ enum:
-+ - mediatek,mt8192-lvts-ap
-+ - mediatek,mt8192-lvts-mcu
-+ - mediatek,mt8195-lvts-ap
-+ - mediatek,mt8195-lvts-mcu
-+
-+ reg:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ clocks:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+ description: LVTS reset for clearing temporary data on AP/MCU.
-+
-+ nvmem-cells:
-+ minItems: 1
-+ items:
-+ - description: Calibration eFuse data 1 for LVTS
-+ - description: Calibration eFuse data 2 for LVTS
-+
-+ nvmem-cell-names:
-+ minItems: 1
-+ items:
-+ - const: lvts-calib-data-1
-+ - const: lvts-calib-data-2
-+
-+ "#thermal-sensor-cells":
-+ const: 1
-+
-+allOf:
-+ - $ref: thermal-sensor.yaml#
-+
-+ - if:
-+ properties:
-+ compatible:
-+ contains:
-+ enum:
-+ - mediatek,mt8192-lvts-ap
-+ - mediatek,mt8192-lvts-mcu
-+ then:
-+ properties:
-+ nvmem-cells:
-+ maxItems: 1
-+
-+ nvmem-cell-names:
-+ maxItems: 1
-+
-+ - if:
-+ properties:
-+ compatible:
-+ contains:
-+ enum:
-+ - mediatek,mt8195-lvts-ap
-+ - mediatek,mt8195-lvts-mcu
-+ then:
-+ properties:
-+ nvmem-cells:
-+ minItems: 2
-+
-+ nvmem-cell-names:
-+ minItems: 2
-+
-+required:
-+ - compatible
-+ - reg
-+ - interrupts
-+ - clocks
-+ - resets
-+ - nvmem-cells
-+ - nvmem-cell-names
-+ - "#thermal-sensor-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/interrupt-controller/arm-gic.h>
-+ #include <dt-bindings/clock/mt8195-clk.h>
-+ #include <dt-bindings/reset/mt8195-resets.h>
-+ #include <dt-bindings/thermal/mediatek,lvts-thermal.h>
-+
-+ soc {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+
-+ lvts_mcu: thermal-sensor@11278000 {
-+ compatible = "mediatek,mt8195-lvts-mcu";
-+ reg = <0 0x11278000 0 0x1000>;
-+ interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
-+ clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
-+ resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
-+ nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
-+ nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
-+ #thermal-sensor-cells = <1>;
-+ };
-+ };
-+
-+ thermal_zones: thermal-zones {
-+ cpu0-thermal {
-+ polling-delay = <1000>;
-+ polling-delay-passive = <250>;
-+ thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
-+
-+ trips {
-+ cpu0_alert: trip-alert {
-+ temperature = <85000>;
-+ hysteresis = <2000>;
-+ type = "passive";
-+ };
-+
-+ cpu0_crit: trip-crit {
-+ temperature = <100000>;
-+ hysteresis = <2000>;
-+ type = "critical";
-+ };
-+ };
-+ };
-+ };
---- /dev/null
-+++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
-@@ -0,0 +1,19 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Author: Balsam CHIHI <bchihi@baylibre.com>
-+ */
-+
-+#ifndef __MEDIATEK_LVTS_DT_H
-+#define __MEDIATEK_LVTS_DT_H
-+
-+#define MT8195_MCU_BIG_CPU0 0
-+#define MT8195_MCU_BIG_CPU1 1
-+#define MT8195_MCU_BIG_CPU2 2
-+#define MT8195_MCU_BIG_CPU3 3
-+#define MT8195_MCU_LITTLE_CPU0 4
-+#define MT8195_MCU_LITTLE_CPU1 5
-+#define MT8195_MCU_LITTLE_CPU2 6
-+#define MT8195_MCU_LITTLE_CPU3 7
-+
-+#endif /* __MEDIATEK_LVTS_DT_H */
+++ /dev/null
-From 05aaa7fdb0736262e224369b9b9f1410320fc71b Mon Sep 17 00:00:00 2001
-From: Balsam CHIHI <bchihi@baylibre.com>
-Date: Tue, 7 Mar 2023 16:45:21 +0100
-Subject: [PATCH] dt-bindings: thermal: mediatek: Add AP domain to LVTS thermal
- controllers for mt8195
-
-Add AP Domain to LVTS thermal controllers dt-binding definition for mt8195.
-
-Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
-Acked-by: Rob Herring <robh@kernel.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Tested-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230307154524.118541-2-bchihi@baylibre.com
----
- include/dt-bindings/thermal/mediatek,lvts-thermal.h | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h
-+++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
-@@ -16,4 +16,14 @@
- #define MT8195_MCU_LITTLE_CPU2 6
- #define MT8195_MCU_LITTLE_CPU3 7
-
-+#define MT8195_AP_VPU0 8
-+#define MT8195_AP_VPU1 9
-+#define MT8195_AP_GPU0 10
-+#define MT8195_AP_GPU1 11
-+#define MT8195_AP_VDEC 12
-+#define MT8195_AP_IMG 13
-+#define MT8195_AP_INFRA 14
-+#define MT8195_AP_CAM0 15
-+#define MT8195_AP_CAM1 16
-+
- #endif /* __MEDIATEK_LVTS_DT_H */
+++ /dev/null
-From a6ff3c0021468721b96e84892a8cae24bde8d65f Mon Sep 17 00:00:00 2001
-From: Daniel Lezcano <daniel.lezcano@linaro.org>
-Date: Wed, 1 Mar 2023 21:14:29 +0100
-Subject: [PATCH] thermal/core: Add a thermal zone 'devdata' accessor
-
-The thermal zone device structure is exposed to the different drivers
-and obviously they access the internals while that should be
-restricted to the core thermal code.
-
-In order to self-encapsulate the thermal core code, we need to prevent
-the drivers accessing directly the thermal zone structure and provide
-accessor functions to deal with.
-
-Provide an accessor to the 'devdata' structure and make use of it in
-the different drivers.
-
-No functional changes intended.
-
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Acked-by: Mark Brown <broonie@kernel.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/thermal/thermal_core.c | 6 ++++++
- include/linux/thermal.h | 7 +++++++
- 2 files changed, 13 insertions(+)
-
---- a/drivers/thermal/thermal_core.c
-+++ b/drivers/thermal/thermal_core.c
-@@ -1346,6 +1346,12 @@ struct thermal_zone_device *thermal_zone
- }
- EXPORT_SYMBOL_GPL(thermal_zone_device_register);
-
-+void *thermal_zone_device_priv(struct thermal_zone_device *tzd)
-+{
-+ return tzd->devdata;
-+}
-+EXPORT_SYMBOL_GPL(thermal_zone_device_priv);
-+
- /**
- * thermal_zone_device_unregister - removes the registered thermal zone device
- * @tz: the thermal zone device to remove
---- a/include/linux/thermal.h
-+++ b/include/linux/thermal.h
-@@ -346,6 +346,8 @@ thermal_zone_device_register_with_trips(
- void *, struct thermal_zone_device_ops *,
- struct thermal_zone_params *, int, int);
-
-+void *thermal_zone_device_priv(struct thermal_zone_device *tzd);
-+
- int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
- struct thermal_cooling_device *,
- unsigned long, unsigned long,
-@@ -417,6 +419,11 @@ static inline int thermal_zone_get_offse
- struct thermal_zone_device *tz)
- { return -ENODEV; }
-
-+static inline void *thermal_zone_device_priv(struct thermal_zone_device *tz)
-+{
-+ return NULL;
-+}
-+
- static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
- { return -ENODEV; }
-
+++ /dev/null
-From 072e35c98806100182c0a7263cf4cba09ce43463 Mon Sep 17 00:00:00 2001
-From: Daniel Lezcano <daniel.lezcano@linaro.org>
-Date: Wed, 1 Mar 2023 21:14:38 +0100
-Subject: [PATCH] thermal/core: Add thermal_zone_device structure 'type'
- accessor
-
-The thermal zone device structure is exposed via the exported
-thermal.h header. This structure should stay private the thermal core
-code. In order to encapsulate the structure, let's add an accessor to
-get the 'type' of the thermal zone.
-
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/thermal/thermal_core.c | 6 ++++++
- include/linux/thermal.h | 6 ++++++
- 2 files changed, 12 insertions(+)
-
---- a/drivers/thermal/thermal_core.c
-+++ b/drivers/thermal/thermal_core.c
-@@ -1352,6 +1352,12 @@ void *thermal_zone_device_priv(struct th
- }
- EXPORT_SYMBOL_GPL(thermal_zone_device_priv);
-
-+const char *thermal_zone_device_type(struct thermal_zone_device *tzd)
-+{
-+ return tzd->type;
-+}
-+EXPORT_SYMBOL_GPL(thermal_zone_device_type);
-+
- /**
- * thermal_zone_device_unregister - removes the registered thermal zone device
- * @tz: the thermal zone device to remove
---- a/include/linux/thermal.h
-+++ b/include/linux/thermal.h
-@@ -347,6 +347,7 @@ thermal_zone_device_register_with_trips(
- struct thermal_zone_params *, int, int);
-
- void *thermal_zone_device_priv(struct thermal_zone_device *tzd);
-+const char *thermal_zone_device_type(struct thermal_zone_device *tzd);
-
- int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
- struct thermal_cooling_device *,
-@@ -423,6 +424,11 @@ static inline void *thermal_zone_device_
- {
- return NULL;
- }
-+
-+static inline const char *thermal_zone_device_type(struct thermal_zone_device *tzd)
-+{
-+ return NULL;
-+}
-
- static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
- { return -ENODEV; }
+++ /dev/null
-From 7d78bab533eb9aa0e5240e25a204e8f416723ed6 Mon Sep 17 00:00:00 2001
-From: Daniel Lezcano <daniel.lezcano@linaro.org>
-Date: Wed, 1 Mar 2023 21:14:30 +0100
-Subject: [PATCH 07/42] thermal/core: Use the thermal zone 'devdata' accessor
- in thermal located drivers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The thermal zone device structure is exposed to the different drivers
-and obviously they access the internals while that should be
-restricted to the core thermal code.
-
-In order to self-encapsulate the thermal core code, we need to prevent
-the drivers accessing directly the thermal zone structure and provide
-accessor functions to deal with.
-
-Use the devdata accessor introduced in the previous patch.
-
-No functional changes intended.
-
-[skipped drivers not relevant for mediatek target]
-
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> #R-Car
-Acked-by: Mark Brown <broonie@kernel.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> #MediaTek auxadc and lvts
-Reviewed-by: Balsam CHIHI <bchihi@baylibre.com> #Mediatek lvts
-Reviewed-by: Adam Ward <DLG-Adam.Ward.opensource@dm.renesas.com> #da9062
-Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> #spread
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com> #sun8i_thermal
-Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Acked-by: Florian Fainelli <f.fainelli@gmail.com> #Broadcom
-Reviewed-by: Dhruva Gole <d-gole@ti.com> # K3 bandgap
-Acked-by: Linus Walleij <linus.walleij@linaro.org>
-Acked-by: Heiko Stuebner <heiko@sntech.de> #rockchip
-Reviewed-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com> #uniphier
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/thermal/mediatek/auxadc_thermal.c | 2 +-
- drivers/thermal/mediatek/lvts_thermal.c | 4 ++--
- 43 files changed, 71 insertions(+), 73 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -763,7 +763,7 @@ static int mtk_thermal_bank_temperature(
-
- static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature)
- {
-- struct mtk_thermal *mt = tz->devdata;
-+ struct mtk_thermal *mt = thermal_zone_device_priv(tz);
- int i;
- int tempmax = INT_MIN;
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -252,7 +252,7 @@ static u32 lvts_temp_to_raw(int temperat
-
- static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
- {
-- struct lvts_sensor *lvts_sensor = tz->devdata;
-+ struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
- void __iomem *msr = lvts_sensor->msr;
- u32 value;
-
-@@ -290,7 +290,7 @@ static int lvts_get_temp(struct thermal_
-
- static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
- {
-- struct lvts_sensor *lvts_sensor = tz->devdata;
-+ struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
- void __iomem *base = lvts_sensor->base;
- u32 raw_low = lvts_temp_to_raw(low);
- u32 raw_high = lvts_temp_to_raw(high);
+++ /dev/null
-From cc9c60e9cfeeac45d63361fa8c085c43c4bdfe3a Mon Sep 17 00:00:00 2001
-From: Daniel Lezcano <daniel.lezcano@linaro.org>
-Date: Wed, 1 Mar 2023 21:14:36 +0100
-Subject: [PATCH 08/42] thermal/hwmon: Use the right device for
- devm_thermal_add_hwmon_sysfs()
-
-The devres variant of thermal_add_hwmon_sysfs() only takes the thermal
-zone structure pointer as parameter.
-
-Actually, it uses the tz->device to add it in the devres list.
-
-It is preferable to use the device registering the thermal zone
-instead of the thermal zone device itself. That prevents the driver
-accessing the thermal zone structure internals and it is from my POV
-more correct regarding how devm_ is used.
-
-[skipped imx thermal which did not apply cleanly and irrelevant on
-mediatek target]
-
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> #amlogic_thermal
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com> #sun8i_thermal
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> #MediaTek auxadc
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/thermal/amlogic_thermal.c | 2 +-
- drivers/thermal/imx_sc_thermal.c | 2 +-
- drivers/thermal/k3_bandgap.c | 2 +-
- drivers/thermal/mediatek/auxadc_thermal.c | 2 +-
- drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 2 +-
- drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 2 +-
- drivers/thermal/qcom/tsens.c | 2 +-
- drivers/thermal/qoriq_thermal.c | 2 +-
- drivers/thermal/sun8i_thermal.c | 2 +-
- drivers/thermal/tegra/tegra30-tsensor.c | 2 +-
- drivers/thermal/thermal_hwmon.c | 4 ++--
- drivers/thermal/thermal_hwmon.h | 4 ++--
- drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +-
- 13 files changed, 15 insertions(+), 15 deletions(-)
-
---- a/drivers/thermal/amlogic_thermal.c
-+++ b/drivers/thermal/amlogic_thermal.c
-@@ -286,7 +286,7 @@ static int amlogic_thermal_probe(struct
- return ret;
- }
-
-- if (devm_thermal_add_hwmon_sysfs(pdata->tzd))
-+ if (devm_thermal_add_hwmon_sysfs(&pdev->dev, pdata->tzd))
- dev_warn(&pdev->dev, "Failed to add hwmon sysfs attributes\n");
-
- ret = amlogic_thermal_initialize(pdata);
---- a/drivers/thermal/imx_sc_thermal.c
-+++ b/drivers/thermal/imx_sc_thermal.c
-@@ -120,7 +120,7 @@ static int imx_sc_thermal_probe(struct p
- return ret;
- }
-
-- if (devm_thermal_add_hwmon_sysfs(sensor->tzd))
-+ if (devm_thermal_add_hwmon_sysfs(&pdev->dev, sensor->tzd))
- dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
- }
-
---- a/drivers/thermal/k3_bandgap.c
-+++ b/drivers/thermal/k3_bandgap.c
-@@ -222,7 +222,7 @@ static int k3_bandgap_probe(struct platf
- goto err_alloc;
- }
-
-- if (devm_thermal_add_hwmon_sysfs(data[id].tzd))
-+ if (devm_thermal_add_hwmon_sysfs(dev, data[id].tzd))
- dev_warn(dev, "Failed to add hwmon sysfs attributes\n");
- }
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -1210,7 +1210,7 @@ static int mtk_thermal_probe(struct plat
- goto err_disable_clk_peri_therm;
- }
-
-- ret = devm_thermal_add_hwmon_sysfs(tzdev);
-+ ret = devm_thermal_add_hwmon_sysfs(&pdev->dev, tzdev);
- if (ret)
- dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
-
---- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
-+++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
-@@ -688,7 +688,7 @@ static int adc_tm5_register_tzd(struct a
- return PTR_ERR(tzd);
- }
- adc_tm->channels[i].tzd = tzd;
-- if (devm_thermal_add_hwmon_sysfs(tzd))
-+ if (devm_thermal_add_hwmon_sysfs(adc_tm->dev, tzd))
- dev_warn(adc_tm->dev,
- "Failed to add hwmon sysfs attributes\n");
- }
---- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
-+++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
-@@ -460,7 +460,7 @@ static int qpnp_tm_probe(struct platform
- return ret;
- }
-
-- if (devm_thermal_add_hwmon_sysfs(chip->tz_dev))
-+ if (devm_thermal_add_hwmon_sysfs(&pdev->dev, chip->tz_dev))
- dev_warn(&pdev->dev,
- "Failed to add hwmon sysfs attributes\n");
-
---- a/drivers/thermal/qcom/tsens.c
-+++ b/drivers/thermal/qcom/tsens.c
-@@ -1056,7 +1056,7 @@ static int tsens_register(struct tsens_p
- if (priv->ops->enable)
- priv->ops->enable(priv, i);
-
-- if (devm_thermal_add_hwmon_sysfs(tzd))
-+ if (devm_thermal_add_hwmon_sysfs(priv->dev, tzd))
- dev_warn(priv->dev,
- "Failed to add hwmon sysfs attributes\n");
- }
---- a/drivers/thermal/qoriq_thermal.c
-+++ b/drivers/thermal/qoriq_thermal.c
-@@ -158,7 +158,7 @@ static int qoriq_tmu_register_tmu_zone(s
- return ret;
- }
-
-- if (devm_thermal_add_hwmon_sysfs(tzd))
-+ if (devm_thermal_add_hwmon_sysfs(dev, tzd))
- dev_warn(dev,
- "Failed to add hwmon sysfs attributes\n");
-
---- a/drivers/thermal/sun8i_thermal.c
-+++ b/drivers/thermal/sun8i_thermal.c
-@@ -468,7 +468,7 @@ static int sun8i_ths_register(struct ths
- if (IS_ERR(tmdev->sensor[i].tzd))
- return PTR_ERR(tmdev->sensor[i].tzd);
-
-- if (devm_thermal_add_hwmon_sysfs(tmdev->sensor[i].tzd))
-+ if (devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd))
- dev_warn(tmdev->dev,
- "Failed to add hwmon sysfs attributes\n");
- }
---- a/drivers/thermal/tegra/tegra30-tsensor.c
-+++ b/drivers/thermal/tegra/tegra30-tsensor.c
-@@ -530,7 +530,7 @@ static int tegra_tsensor_register_channe
- return 0;
- }
-
-- if (devm_thermal_add_hwmon_sysfs(tsc->tzd))
-+ if (devm_thermal_add_hwmon_sysfs(ts->dev, tsc->tzd))
- dev_warn(ts->dev, "failed to add hwmon sysfs attributes\n");
-
- return 0;
---- a/drivers/thermal/thermal_hwmon.c
-+++ b/drivers/thermal/thermal_hwmon.c
-@@ -255,7 +255,7 @@ static void devm_thermal_hwmon_release(s
- thermal_remove_hwmon_sysfs(*(struct thermal_zone_device **)res);
- }
-
--int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
-+int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz)
- {
- struct thermal_zone_device **ptr;
- int ret;
-@@ -272,7 +272,7 @@ int devm_thermal_add_hwmon_sysfs(struct
- }
-
- *ptr = tz;
-- devres_add(&tz->device, ptr);
-+ devres_add(dev, ptr);
-
- return ret;
- }
---- a/drivers/thermal/thermal_hwmon.h
-+++ b/drivers/thermal/thermal_hwmon.h
-@@ -17,7 +17,7 @@
-
- #ifdef CONFIG_THERMAL_HWMON
- int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
--int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
-+int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz);
- void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz);
- #else
- static inline int
-@@ -27,7 +27,7 @@ thermal_add_hwmon_sysfs(struct thermal_z
- }
-
- static inline int
--devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
-+devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz)
- {
- return 0;
- }
---- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
-+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
-@@ -182,7 +182,7 @@ int ti_thermal_expose_sensor(struct ti_b
- ti_bandgap_set_sensor_data(bgp, id, data);
- ti_bandgap_write_update_interval(bgp, data->sensor_id, interval);
-
-- if (devm_thermal_add_hwmon_sysfs(data->ti_thermal))
-+ if (devm_thermal_add_hwmon_sysfs(bgp->dev, data->ti_thermal))
- dev_warn(bgp->dev, "failed to add hwmon sysfs attributes\n");
-
- return 0;
+++ /dev/null
-From 5a72b8e4bac753e4dc74dc0a1335d120f63df97a Mon Sep 17 00:00:00 2001
-From: Daniel Lezcano <daniel.lezcano@linaro.org>
-Date: Wed, 1 Mar 2023 21:14:37 +0100
-Subject: [PATCH 09/42] thermal: Don't use 'device' internal thermal zone
- structure field
-
-Some drivers are directly using the thermal zone's 'device' structure
-field.
-
-Use the driver device pointer instead of the thermal zone device when
-it is available.
-
-Remove the traces when they are duplicate with the traces in the core
-code.
-
-[again skipped imx_thermal.c]
-
-Cc: Jean Delvare <jdelvare@suse.com>
-Cc: Guenter Roeck <linux@roeck-us.net>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Reviewed-by: Balsam CHIHI <bchihi@baylibre.com> #Mediatek LVTS
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> #MediaTek LVTS
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/thermal/mediatek/lvts_thermal.c | 4 ++--
- drivers/thermal/thermal_hwmon.c | 4 ++--
- drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +-
- 3 files changed, 5 insertions(+), 5 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -305,7 +305,7 @@ static int lvts_set_trips(struct thermal
- * 14-0 : Raw temperature for threshold
- */
- if (low != -INT_MAX) {
-- dev_dbg(&tz->device, "Setting low limit temperature interrupt: %d\n", low);
-+ pr_debug("%s: Setting low limit temperature interrupt: %d\n", tz->type, low);
- writel(raw_low, LVTS_H2NTHRE(base));
- }
-
-@@ -318,7 +318,7 @@ static int lvts_set_trips(struct thermal
- *
- * 14-0 : Raw temperature for threshold
- */
-- dev_dbg(&tz->device, "Setting high limit temperature interrupt: %d\n", high);
-+ pr_debug("%s: Setting high limit temperature interrupt: %d\n", tz->type, high);
- writel(raw_high, LVTS_HTHRE(base));
-
- return 0;
---- a/drivers/thermal/thermal_hwmon.c
-+++ b/drivers/thermal/thermal_hwmon.c
-@@ -220,14 +220,14 @@ void thermal_remove_hwmon_sysfs(struct t
- hwmon = thermal_hwmon_lookup_by_type(tz);
- if (unlikely(!hwmon)) {
- /* Should never happen... */
-- dev_dbg(&tz->device, "hwmon device lookup failed!\n");
-+ dev_dbg(hwmon->device, "hwmon device lookup failed!\n");
- return;
- }
-
- temp = thermal_hwmon_lookup_temp(hwmon, tz);
- if (unlikely(!temp)) {
- /* Should never happen... */
-- dev_dbg(&tz->device, "temperature input lookup failed!\n");
-+ dev_dbg(hwmon->device, "temperature input lookup failed!\n");
- return;
- }
-
---- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
-+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
-@@ -43,7 +43,7 @@ static void ti_thermal_work(struct work_
-
- thermal_zone_device_update(data->ti_thermal, THERMAL_EVENT_UNSPECIFIED);
-
-- dev_dbg(&data->ti_thermal->device, "updated thermal zone %s\n",
-+ dev_dbg(data->bgp->dev, "updated thermal zone %s\n",
- data->ti_thermal->type);
- }
-
+++ /dev/null
-From 66b3a292d3fc749e8ec7ac5278a17e8a5757ecbc Mon Sep 17 00:00:00 2001
-From: Daniel Lezcano <daniel.lezcano@linaro.org>
-Date: Wed, 1 Mar 2023 21:14:41 +0100
-Subject: [PATCH 10/42] thermal: Use thermal_zone_device_type() accessor
-
-Replace the accesses to 'tz->type' by its accessor version in order to
-self-encapsulate the thermal_zone_device structure.
-
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Reviewed-by: Ido Schimmel <idosch@nvidia.com> #mlxsw
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> #MediaTek LVTS
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 2 +-
- drivers/thermal/mediatek/lvts_thermal.c | 6 ++++--
- drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +-
- 3 files changed, 6 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
-+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
-@@ -168,7 +168,7 @@ mlxsw_thermal_module_trips_update(struct
-
- if (crit_temp > emerg_temp) {
- dev_warn(dev, "%s : Critical threshold %d is above emergency threshold %d\n",
-- tz->tzdev->type, crit_temp, emerg_temp);
-+ thermal_zone_device_type(tz->tzdev), crit_temp, emerg_temp);
- return 0;
- }
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -305,7 +305,8 @@ static int lvts_set_trips(struct thermal
- * 14-0 : Raw temperature for threshold
- */
- if (low != -INT_MAX) {
-- pr_debug("%s: Setting low limit temperature interrupt: %d\n", tz->type, low);
-+ pr_debug("%s: Setting low limit temperature interrupt: %d\n",
-+ thermal_zone_device_type(tz), low);
- writel(raw_low, LVTS_H2NTHRE(base));
- }
-
-@@ -318,7 +319,8 @@ static int lvts_set_trips(struct thermal
- *
- * 14-0 : Raw temperature for threshold
- */
-- pr_debug("%s: Setting high limit temperature interrupt: %d\n", tz->type, high);
-+ pr_debug("%s: Setting high limit temperature interrupt: %d\n",
-+ thermal_zone_device_type(tz), high);
- writel(raw_high, LVTS_HTHRE(base));
-
- return 0;
---- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
-+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
-@@ -44,7 +44,7 @@ static void ti_thermal_work(struct work_
- thermal_zone_device_update(data->ti_thermal, THERMAL_EVENT_UNSPECIFIED);
-
- dev_dbg(data->bgp->dev, "updated thermal zone %s\n",
-- data->ti_thermal->type);
-+ thermal_zone_device_type(data->ti_thermal));
- }
-
- /**
+++ /dev/null
-From f6658c1c4ae98477d6be00495226c0617354fe76 Mon Sep 17 00:00:00 2001
-From: Markus Schneider-Pargmann <msp@baylibre.com>
-Date: Fri, 27 Jan 2023 16:44:43 +0100
-Subject: [PATCH 11/42] thermal/drivers/mediatek: Control buffer enablement
- tweaks
-
-Add logic in order to be able to turn on the control buffer on MT8365.
-This change now allows to have control buffer support for MTK_THERMAL_V1,
-and it allows to define the register offset, and mask used to enable it.
-
-Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
-Signed-off-by: Fabien Parent <fparent@baylibre.com>
-Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221018-up-i350-thermal-bringup-v9-2-55a1ae14af74@baylibre.com
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
----
- drivers/thermal/mediatek/auxadc_thermal.c | 28 +++++++++++++++--------
- 1 file changed, 19 insertions(+), 9 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -307,6 +307,9 @@ struct mtk_thermal_data {
- bool need_switch_bank;
- struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
- enum mtk_thermal_version version;
-+ u32 apmixed_buffer_ctl_reg;
-+ u32 apmixed_buffer_ctl_mask;
-+ u32 apmixed_buffer_ctl_set;
- };
-
- struct mtk_thermal {
-@@ -560,6 +563,9 @@ static const struct mtk_thermal_data mt7
- .adcpnp = mt7622_adcpnp,
- .sensor_mux_values = mt7622_mux_values,
- .version = MTK_THERMAL_V2,
-+ .apmixed_buffer_ctl_reg = APMIXED_SYS_TS_CON1,
-+ .apmixed_buffer_ctl_mask = GENMASK(31, 6) | BIT(3),
-+ .apmixed_buffer_ctl_set = BIT(0),
- };
-
- /*
-@@ -1079,14 +1085,18 @@ static const struct of_device_id mtk_the
- };
- MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
-
--static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base)
-+static void mtk_thermal_turn_on_buffer(struct mtk_thermal *mt,
-+ void __iomem *apmixed_base)
- {
-- int tmp;
-+ u32 tmp;
-+
-+ if (!mt->conf->apmixed_buffer_ctl_reg)
-+ return;
-
-- tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1);
-- tmp &= ~(0x37);
-- tmp |= 0x1;
-- writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1);
-+ tmp = readl(apmixed_base + mt->conf->apmixed_buffer_ctl_reg);
-+ tmp &= mt->conf->apmixed_buffer_ctl_mask;
-+ tmp |= mt->conf->apmixed_buffer_ctl_set;
-+ writel(tmp, apmixed_base + mt->conf->apmixed_buffer_ctl_reg);
- udelay(200);
- }
-
-@@ -1184,10 +1194,10 @@ static int mtk_thermal_probe(struct plat
- goto err_disable_clk_auxadc;
- }
-
-- if (mt->conf->version != MTK_THERMAL_V1) {
-- mtk_thermal_turn_on_buffer(apmixed_base);
-+ mtk_thermal_turn_on_buffer(mt, apmixed_base);
-+
-+ if (mt->conf->version != MTK_THERMAL_V2)
- mtk_thermal_release_periodic_ts(mt, auxadc_base);
-- }
-
- if (mt->conf->version == MTK_THERMAL_V1)
- mt->raw_to_mcelsius = raw_to_mcelsius_v1;
+++ /dev/null
-From c4eff784465f88218dc5eb51320320464db83d3f Mon Sep 17 00:00:00 2001
-From: Fabien Parent <fparent@baylibre.com>
-Date: Fri, 27 Jan 2023 16:44:44 +0100
-Subject: [PATCH 12/42] thermal/drivers/mediatek: Add support for MT8365 SoC
-
-MT8365 is similar to the other SoCs supported by the driver. It has only
-one bank and 3 actual sensors that can be multiplexed. There is another
-one sensor that does not have usable data.
-
-Signed-off-by: Fabien Parent <fparent@baylibre.com>
-Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221018-up-i350-thermal-bringup-v9-3-55a1ae14af74@baylibre.com
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
----
- drivers/thermal/mediatek/auxadc_thermal.c | 68 +++++++++++++++++++++++
- 1 file changed, 68 insertions(+)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -31,6 +31,7 @@
- #define AUXADC_CON2_V 0x010
- #define AUXADC_DATA(channel) (0x14 + (channel) * 4)
-
-+#define APMIXED_SYS_TS_CON0 0x600
- #define APMIXED_SYS_TS_CON1 0x604
-
- /* Thermal Controller Registers */
-@@ -281,6 +282,17 @@ enum mtk_thermal_version {
- /* The calibration coefficient of sensor */
- #define MT7986_CALIBRATION 165
-
-+/* MT8365 */
-+#define MT8365_TEMP_AUXADC_CHANNEL 11
-+#define MT8365_CALIBRATION 164
-+#define MT8365_NUM_CONTROLLER 1
-+#define MT8365_NUM_BANKS 1
-+#define MT8365_NUM_SENSORS 3
-+#define MT8365_NUM_SENSORS_PER_ZONE 3
-+#define MT8365_TS1 0
-+#define MT8365_TS2 1
-+#define MT8365_TS3 2
-+
- struct mtk_thermal;
-
- struct thermal_bank_cfg {
-@@ -435,6 +447,24 @@ static const int mt7986_mux_values[MT798
- static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
- static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
-
-+/* MT8365 thermal sensor data */
-+static const int mt8365_bank_data[MT8365_NUM_SENSORS] = {
-+ MT8365_TS1, MT8365_TS2, MT8365_TS3
-+};
-+
-+static const int mt8365_msr[MT8365_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
-+};
-+
-+static const int mt8365_adcpnp[MT8365_NUM_SENSORS_PER_ZONE] = {
-+ TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
-+};
-+
-+static const int mt8365_mux_values[MT8365_NUM_SENSORS] = { 0, 1, 2 };
-+static const int mt8365_tc_offset[MT8365_NUM_CONTROLLER] = { 0 };
-+
-+static const int mt8365_vts_index[MT8365_NUM_SENSORS] = { VTS1, VTS2, VTS3 };
-+
- /*
- * The MT8173 thermal controller has four banks. Each bank can read up to
- * four temperature sensors simultaneously. The MT8173 has a total of 5
-@@ -510,6 +540,40 @@ static const struct mtk_thermal_data mt2
- };
-
- /*
-+ * The MT8365 thermal controller has one bank, which can read up to
-+ * four temperature sensors simultaneously. The MT8365 has a total of 3
-+ * temperature sensors.
-+ *
-+ * The thermal core only gets the maximum temperature of this one bank,
-+ * so the bank concept wouldn't be necessary here. However, the SVS (Smart
-+ * Voltage Scaling) unit makes its decisions based on the same bank
-+ * data.
-+ */
-+static const struct mtk_thermal_data mt8365_thermal_data = {
-+ .auxadc_channel = MT8365_TEMP_AUXADC_CHANNEL,
-+ .num_banks = MT8365_NUM_BANKS,
-+ .num_sensors = MT8365_NUM_SENSORS,
-+ .vts_index = mt8365_vts_index,
-+ .cali_val = MT8365_CALIBRATION,
-+ .num_controller = MT8365_NUM_CONTROLLER,
-+ .controller_offset = mt8365_tc_offset,
-+ .need_switch_bank = false,
-+ .bank_data = {
-+ {
-+ .num_sensors = MT8365_NUM_SENSORS,
-+ .sensors = mt8365_bank_data
-+ },
-+ },
-+ .msr = mt8365_msr,
-+ .adcpnp = mt8365_adcpnp,
-+ .sensor_mux_values = mt8365_mux_values,
-+ .version = MTK_THERMAL_V1,
-+ .apmixed_buffer_ctl_reg = APMIXED_SYS_TS_CON0,
-+ .apmixed_buffer_ctl_mask = (u32) ~GENMASK(29, 28),
-+ .apmixed_buffer_ctl_set = 0,
-+};
-+
-+/*
- * The MT2712 thermal controller has one bank, which can read up to
- * four temperature sensors simultaneously. The MT2712 has a total of 4
- * temperature sensors.
-@@ -1080,6 +1144,10 @@ static const struct of_device_id mtk_the
- {
- .compatible = "mediatek,mt8183-thermal",
- .data = (void *)&mt8183_thermal_data,
-+ },
-+ {
-+ .compatible = "mediatek,mt8365-thermal",
-+ .data = (void *)&mt8365_thermal_data,
- }, {
- },
- };
+++ /dev/null
-From 4eead70db74922bc61e9d0b4591524369a335751 Mon Sep 17 00:00:00 2001
-From: Amjad Ouled-Ameur <aouledameur@baylibre.com>
-Date: Fri, 27 Jan 2023 16:44:46 +0100
-Subject: [PATCH 13/42] thermal/drivers/mediatek: Add delay after thermal banks
- initialization
-
-Thermal sensor reads performed immediately after thermal bank
-initialization returns bogus values. This is currently tackled by returning
-0 if the temperature is bogus (exceeding 200000).
-
-Instead, add a delay between the bank init and the thermal zone device
-register to properly fix this.
-
-Signed-off-by: Michael Kao <michael.kao@mediatek.com>
-Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
-Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20221018-up-i350-thermal-bringup-v9-5-55a1ae14af74@baylibre.com
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
----
- drivers/thermal/mediatek/auxadc_thermal.c | 11 +++--------
- 1 file changed, 3 insertions(+), 8 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -816,14 +816,6 @@ static int mtk_thermal_bank_temperature(
- mt, conf->bank_data[bank->id].sensors[i], raw);
-
-
-- /*
-- * The first read of a sensor often contains very high bogus
-- * temperature value. Filter these out so that the system does
-- * not immediately shut down.
-- */
-- if (temp > 200000)
-- temp = 0;
--
- if (temp > max)
- max = temp;
- }
-@@ -1281,6 +1273,9 @@ static int mtk_thermal_probe(struct plat
-
- platform_set_drvdata(pdev, mt);
-
-+ /* Delay for thermal banks to be ready */
-+ msleep(30);
-+
- tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
- &mtk_thermal_ops);
- if (IS_ERR(tzdev)) {
+++ /dev/null
-From ad9dc9e92367803a4f9576aea0dab110d03fc510 Mon Sep 17 00:00:00 2001
-From: Chen-Yu Tsai <wenst@chromium.org>
-Date: Tue, 28 Mar 2023 11:10:17 +0800
-Subject: [PATCH 14/42] thermal/drivers/mediatek/lvts_thermal: Fix sensor 1
- interrupt status bitmask
-
-The binary representation for sensor 1 interrupt status was incorrectly
-assembled, when compared to the full table given in the same comment
-section. The conversion into hex was also incorrect, leading to
-incorrect interrupt status bitmask for sensor 1. This would cause the
-driver to incorrectly identify changes for sensor 1, when in fact it
-was sensor 0, or a sensor access time out.
-
-Fix the binary and hex representations in the comments, and the actual
-bitmask macro.
-
-Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
-Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230328031017.1360976-1-wenst@chromium.org
----
- drivers/thermal/mediatek/lvts_thermal.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -66,7 +66,7 @@
- #define LVTS_MONINT_CONF 0x9FBF7BDE
-
- #define LVTS_INT_SENSOR0 0x0009001F
--#define LVTS_INT_SENSOR1 0X000881F0
-+#define LVTS_INT_SENSOR1 0x001203E0
- #define LVTS_INT_SENSOR2 0x00247C00
- #define LVTS_INT_SENSOR3 0x1FC00000
-
-@@ -395,8 +395,8 @@ static irqreturn_t lvts_ctrl_irq_handler
- * => 0x1FC00000
- * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000
- * => 0x00247C00
-- * sensor 1 interrupt: 0000 0000 0001 0001 0000 0011 1110 0000
-- * => 0X000881F0
-+ * sensor 1 interrupt: 0000 0000 0001 0010 0000 0011 1110 0000
-+ * => 0X001203E0
- * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111
- * => 0x0009001F
- */
+++ /dev/null
-From 9aad43ad3285fc21158fb416830a6156a9a31fa5 Mon Sep 17 00:00:00 2001
-From: Balsam CHIHI <bchihi@baylibre.com>
-Date: Tue, 7 Mar 2023 16:45:22 +0100
-Subject: [PATCH 15/42] thermal/drivers/mediatek/lvts_thermal: Add AP domain
- for mt8195
-
-Add MT8195 AP Domain support to LVTS Driver.
-
-Take the opportunity to update the comments to show calibration data
-information related to the new domain.
-
-[dlezcano]: Massaged a bit the changelog
-
-Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
-Tested-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230307154524.118541-3-bchihi@baylibre.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 94 +++++++++++++++++++------
- 1 file changed, 74 insertions(+), 20 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -530,29 +530,33 @@ static int lvts_sensor_init(struct devic
- * The efuse blob values follows the sensor enumeration per thermal
- * controller. The decoding of the stream is as follow:
- *
-- * <--?-> <----big0 ???---> <-sensor0-> <-0->
-- * ------------------------------------------
-- * index in the stream: : | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 |
-- * ------------------------------------------
-+ * stream index map for MCU Domain :
- *
-- * <--sensor1--><-0-> <----big1 ???---> <-sen
-- * ------------------------------------------
-- * | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
-- * ------------------------------------------
-+ * <-----mcu-tc#0-----> <-----sensor#0-----> <-----sensor#1----->
-+ * 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09
- *
-- * sor0-> <-0-> <-sensor1-> <-0-> ..........
-- * ------------------------------------------
-- * | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
-- * ------------------------------------------
-+ * <-----mcu-tc#1-----> <-----sensor#2-----> <-----sensor#3----->
-+ * 0x0A | 0x0B | 0x0C | 0x0D | 0x0E | 0x0F | 0x10 | 0x11 | 0x12
- *
-- * And so on ...
-+ * <-----mcu-tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6-----> <-----sensor#7----->
-+ * 0x13 | 0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21
-+ *
-+ * stream index map for AP Domain :
-+ *
-+ * <-----ap--tc#0-----> <-----sensor#0-----> <-----sensor#1----->
-+ * 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A
-+ *
-+ * <-----ap--tc#1-----> <-----sensor#2-----> <-----sensor#3----->
-+ * 0x2B | 0x2C | 0x2D | 0x2E | 0x2F | 0x30 | 0x31 | 0x32 | 0x33
-+ *
-+ * <-----ap--tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6----->
-+ * 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 | 0x3A | 0x3B | 0x3C | 0x3D | 0x3E | 0x3F
-+ *
-+ * <-----ap--tc#3-----> <-----sensor#7-----> <-----sensor#8----->
-+ * 0x40 | 0x41 | 0x42 | 0x43 | 0x44 | 0x45 | 0x46 | 0x47 | 0x48
- *
- * The data description gives the offset of the calibration data in
- * this bytes stream for each sensor.
-- *
-- * Each thermal controller can handle up to 4 sensors max, we don't
-- * care if there are less as the array of calibration is sized to 4
-- * anyway. The unused sensor slot will be zeroed.
- */
- static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
- const struct lvts_ctrl_data *lvts_ctrl_data,
-@@ -1165,7 +1169,7 @@ static int lvts_remove(struct platform_d
- return 0;
- }
-
--static const struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {
-+static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
- {
- .cal_offset = { 0x04, 0x07 },
- .lvts_sensor = {
-@@ -1200,13 +1204,63 @@ static const struct lvts_ctrl_data mt819
- }
- };
-
-+static const struct lvts_ctrl_data mt8195_lvts_ap_data_ctrl[] = {
-+ {
-+ .cal_offset = { 0x25, 0x28 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8195_AP_VPU0 },
-+ { .dt_id = MT8195_AP_VPU1 }
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x0,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
-+ },
-+ {
-+ .cal_offset = { 0x2e, 0x31 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8195_AP_GPU0 },
-+ { .dt_id = MT8195_AP_GPU1 }
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x100,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
-+ },
-+ {
-+ .cal_offset = { 0x37, 0x3a, 0x3d },
-+ .lvts_sensor = {
-+ { .dt_id = MT8195_AP_VDEC },
-+ { .dt_id = MT8195_AP_IMG },
-+ { .dt_id = MT8195_AP_INFRA },
-+ },
-+ .num_lvts_sensor = 3,
-+ .offset = 0x200,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
-+ },
-+ {
-+ .cal_offset = { 0x43, 0x46 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8195_AP_CAM0 },
-+ { .dt_id = MT8195_AP_CAM1 }
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x300,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
-+ }
-+};
-+
- static const struct lvts_data mt8195_lvts_mcu_data = {
-- .lvts_ctrl = mt8195_lvts_data_ctrl,
-- .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_data_ctrl),
-+ .lvts_ctrl = mt8195_lvts_mcu_data_ctrl,
-+ .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
-+};
-+
-+static const struct lvts_data mt8195_lvts_ap_data = {
-+ .lvts_ctrl = mt8195_lvts_ap_data_ctrl,
-+ .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_ap_data_ctrl),
- };
-
- static const struct of_device_id lvts_of_match[] = {
- { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
-+ { .compatible = "mediatek,mt8195-lvts-ap", .data = &mt8195_lvts_ap_data },
- {},
- };
- MODULE_DEVICE_TABLE(of, lvts_of_match);
+++ /dev/null
-From 7105a86760bd9e4d107075cefc75016b693a5542 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Wed, 19 Apr 2023 08:11:45 +0200
-Subject: [PATCH 16/42] Revert "thermal/drivers/mediatek: Add delay after
- thermal banks initialization"
-
-Some more testing revealed that this commit introduces a regression on some
-MT8173 Chromebooks and at least on one MT6795 Sony Xperia M5 smartphone due
-to the delay being apparently variable and machine specific.
-
-Another solution would be to delay for a bit more (~70ms) but this is not
-feasible for two reasons: first of all, we're adding an even bigger delay
-in a probe function; second, some machines need less, some may need even
-more, making the msleep at probe solution highly suboptimal.
-
-This reverts commit 10debf8c2da8011c8009dd4b3f6d0ab85891c81b.
-
-Fixes: 10debf8c2da8 ("thermal/drivers/mediatek: Add delay after thermal banks initialization")
-Reported-by: "kernelci.org bot" <bot@kernelci.org>
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230419061146.22246-2-angelogioacchino.delregno@collabora.com
----
- drivers/thermal/mediatek/auxadc_thermal.c | 11 ++++++++---
- 1 file changed, 8 insertions(+), 3 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -816,6 +816,14 @@ static int mtk_thermal_bank_temperature(
- mt, conf->bank_data[bank->id].sensors[i], raw);
-
-
-+ /*
-+ * The first read of a sensor often contains very high bogus
-+ * temperature value. Filter these out so that the system does
-+ * not immediately shut down.
-+ */
-+ if (temp > 200000)
-+ temp = 0;
-+
- if (temp > max)
- max = temp;
- }
-@@ -1273,9 +1281,6 @@ static int mtk_thermal_probe(struct plat
-
- platform_set_drvdata(pdev, mt);
-
-- /* Delay for thermal banks to be ready */
-- msleep(30);
--
- tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
- &mtk_thermal_ops);
- if (IS_ERR(tzdev)) {
+++ /dev/null
-From 681b652c9dfc4037d4a55b2733e091a4e1a5de18 Mon Sep 17 00:00:00 2001
-From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Date: Wed, 19 Apr 2023 08:11:46 +0200
-Subject: [PATCH 17/42] thermal/drivers/mediatek: Add temperature constraints
- to validate read
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The AUXADC thermal v1 allows reading temperature range between -20°C to
-150°C and any value out of this range is invalid.
-
-Add new definitions for MT8173_TEMP_{MIN_MAX} and a new small helper
-mtk_thermal_temp_is_valid() to check if new readings are in range: if
-not, we tell to the API that the reading is invalid by returning
-THERMAL_TEMP_INVALID.
-
-It was chosen to introduce the helper function because, even though this
-temperature range is realistically ok for all, it comes from a downstream
-kernel driver for version 1, but here we also support v2 and v3 which may
-may have wider constraints.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230419061146.22246-3-angelogioacchino.delregno@collabora.com
----
- drivers/thermal/mediatek/auxadc_thermal.c | 24 +++++++++++++++++------
- 1 file changed, 18 insertions(+), 6 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -116,6 +116,10 @@
- /* The calibration coefficient of sensor */
- #define MT8173_CALIBRATION 165
-
-+/* Valid temperatures range */
-+#define MT8173_TEMP_MIN -20000
-+#define MT8173_TEMP_MAX 150000
-+
- /*
- * Layout of the fuses providing the calibration data
- * These macros could be used for MT8183, MT8173, MT2701, and MT2712.
-@@ -689,6 +693,11 @@ static const struct mtk_thermal_data mt7
- .version = MTK_THERMAL_V3,
- };
-
-+static bool mtk_thermal_temp_is_valid(int temp)
-+{
-+ return (temp >= MT8173_TEMP_MIN) && (temp <= MT8173_TEMP_MAX);
-+}
-+
- /**
- * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
- * @mt: The thermal controller
-@@ -815,14 +824,17 @@ static int mtk_thermal_bank_temperature(
- temp = mt->raw_to_mcelsius(
- mt, conf->bank_data[bank->id].sensors[i], raw);
-
--
- /*
-- * The first read of a sensor often contains very high bogus
-- * temperature value. Filter these out so that the system does
-- * not immediately shut down.
-+ * Depending on the filt/sen intervals and ADC polling time,
-+ * we may need up to 60 milliseconds after initialization: this
-+ * will result in the first reading containing an out of range
-+ * temperature value.
-+ * Validate the reading to both address the aforementioned issue
-+ * and to eventually avoid bogus readings during runtime in the
-+ * event that the AUXADC gets unstable due to high EMI, etc.
- */
-- if (temp > 200000)
-- temp = 0;
-+ if (!mtk_thermal_temp_is_valid(temp))
-+ temp = THERMAL_TEMP_INVALID;
-
- if (temp > max)
- max = temp;
+++ /dev/null
-From 458fa1d508de3f17e49d974a0158d9aeff273a58 Mon Sep 17 00:00:00 2001
-From: Kang Chen <void0red@hust.edu.cn>
-Date: Wed, 19 Apr 2023 10:07:48 +0800
-Subject: [PATCH 18/42] thermal/drivers/mediatek: Use devm_of_iomap to avoid
- resource leak in mtk_thermal_probe
-
-Smatch reports:
-1. mtk_thermal_probe() warn: 'apmixed_base' from of_iomap() not released.
-2. mtk_thermal_probe() warn: 'auxadc_base' from of_iomap() not released.
-
-The original code forgets to release iomap resource when handling errors,
-fix it by switch to devm_of_iomap.
-
-Fixes: 89945047b166 ("thermal: mediatek: Add tsensor support for V2 thermal system")
-Signed-off-by: Kang Chen <void0red@hust.edu.cn>
-Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230419020749.621257-1-void0red@hust.edu.cn
----
- drivers/thermal/mediatek/auxadc_thermal.c | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -1232,7 +1232,12 @@ static int mtk_thermal_probe(struct plat
- return -ENODEV;
- }
-
-- auxadc_base = of_iomap(auxadc, 0);
-+ auxadc_base = devm_of_iomap(&pdev->dev, auxadc, 0, NULL);
-+ if (IS_ERR(auxadc_base)) {
-+ of_node_put(auxadc);
-+ return PTR_ERR(auxadc_base);
-+ }
-+
- auxadc_phys_base = of_get_phys_base(auxadc);
-
- of_node_put(auxadc);
-@@ -1248,7 +1253,12 @@ static int mtk_thermal_probe(struct plat
- return -ENODEV;
- }
-
-- apmixed_base = of_iomap(apmixedsys, 0);
-+ apmixed_base = devm_of_iomap(&pdev->dev, apmixedsys, 0, NULL);
-+ if (IS_ERR(apmixed_base)) {
-+ of_node_put(apmixedsys);
-+ return PTR_ERR(apmixed_base);
-+ }
-+
- apmixed_phys_base = of_get_phys_base(apmixedsys);
-
- of_node_put(apmixedsys);
+++ /dev/null
-From 227d1856924ec00a4f5bdf5afcf77bc7f3f04e86 Mon Sep 17 00:00:00 2001
-From: Kang Chen <void0red@hust.edu.cn>
-Date: Wed, 19 Apr 2023 10:07:49 +0800
-Subject: [PATCH 19/42] thermal/drivers/mediatek: Change clk_prepare_enable to
- devm_clk_get_enabled in mtk_thermal_probe
-
-Use devm_clk_get_enabled to do automatic resource management.
-Meanwhile, remove error handling labels in the probe function and
-the whole remove function.
-
-Signed-off-by: Kang Chen <void0red@hust.edu.cn>
-Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230419020749.621257-2-void0red@hust.edu.cn
----
- drivers/thermal/mediatek/auxadc_thermal.c | 44 +++++------------------
- 1 file changed, 9 insertions(+), 35 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -1206,14 +1206,6 @@ static int mtk_thermal_probe(struct plat
-
- mt->conf = of_device_get_match_data(&pdev->dev);
-
-- mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
-- if (IS_ERR(mt->clk_peri_therm))
-- return PTR_ERR(mt->clk_peri_therm);
--
-- mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
-- if (IS_ERR(mt->clk_auxadc))
-- return PTR_ERR(mt->clk_auxadc);
--
- mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
- if (IS_ERR(mt->thermal_base))
- return PTR_ERR(mt->thermal_base);
-@@ -1272,16 +1264,18 @@ static int mtk_thermal_probe(struct plat
- if (ret)
- return ret;
-
-- ret = clk_prepare_enable(mt->clk_auxadc);
-- if (ret) {
-+ mt->clk_auxadc = devm_clk_get_enabled(&pdev->dev, "auxadc");
-+ if (IS_ERR(mt->clk_auxadc)) {
-+ ret = PTR_ERR(mt->clk_auxadc);
- dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
- return ret;
- }
-
-- ret = clk_prepare_enable(mt->clk_peri_therm);
-- if (ret) {
-+ mt->clk_peri_therm = devm_clk_get_enabled(&pdev->dev, "therm");
-+ if (IS_ERR(mt->clk_peri_therm)) {
-+ ret = PTR_ERR(mt->clk_peri_therm);
- dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
-- goto err_disable_clk_auxadc;
-+ return ret;
- }
-
- mtk_thermal_turn_on_buffer(mt, apmixed_base);
-@@ -1305,38 +1299,18 @@ static int mtk_thermal_probe(struct plat
-
- tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
- &mtk_thermal_ops);
-- if (IS_ERR(tzdev)) {
-- ret = PTR_ERR(tzdev);
-- goto err_disable_clk_peri_therm;
-- }
-+ if (IS_ERR(tzdev))
-+ return PTR_ERR(tzdev);
-
- ret = devm_thermal_add_hwmon_sysfs(&pdev->dev, tzdev);
- if (ret)
- dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
-
- return 0;
--
--err_disable_clk_peri_therm:
-- clk_disable_unprepare(mt->clk_peri_therm);
--err_disable_clk_auxadc:
-- clk_disable_unprepare(mt->clk_auxadc);
--
-- return ret;
--}
--
--static int mtk_thermal_remove(struct platform_device *pdev)
--{
-- struct mtk_thermal *mt = platform_get_drvdata(pdev);
--
-- clk_disable_unprepare(mt->clk_peri_therm);
-- clk_disable_unprepare(mt->clk_auxadc);
--
-- return 0;
- }
-
- static struct platform_driver mtk_thermal_driver = {
- .probe = mtk_thermal_probe,
-- .remove = mtk_thermal_remove,
- .driver = {
- .name = "mtk-thermal",
- .of_match_table = mtk_thermal_of_match,
+++ /dev/null
-From 655fe2533ac05323a07c19ba079bf2064e7741af Mon Sep 17 00:00:00 2001
-From: Rob Herring <robh@kernel.org>
-Date: Sun, 19 Mar 2023 11:32:31 -0500
-Subject: [PATCH 20/42] thermal/drivers/mediatek: Use of_address_to_resource()
-
-Replace of_get_address() and of_translate_address() calls with single
-call to of_address_to_resource().
-
-Signed-off-by: Rob Herring <robh@kernel.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230319163231.226738-1-robh@kernel.org
----
- drivers/thermal/mediatek/auxadc_thermal.c | 8 +++-----
- 1 file changed, 3 insertions(+), 5 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -979,14 +979,12 @@ static void mtk_thermal_init_bank(struct
-
- static u64 of_get_phys_base(struct device_node *np)
- {
-- u64 size64;
-- const __be32 *regaddr_p;
-+ struct resource res;
-
-- regaddr_p = of_get_address(np, 0, &size64, NULL);
-- if (!regaddr_p)
-+ if (of_address_to_resource(np, 0, &res))
- return OF_BAD_ADDR;
-
-- return of_translate_address(np, regaddr_p);
-+ return res.start;
- }
-
- static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf)
+++ /dev/null
-From 2c380d07215e6fce3ac66cc5af059bc2c2a69f7a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ricardo=20Ca=C3=B1uelo?= <ricardo.canuelo@collabora.com>
-Date: Thu, 25 May 2023 14:18:11 +0200
-Subject: [PATCH 21/42] Revert "thermal/drivers/mediatek: Use devm_of_iomap to
- avoid resource leak in mtk_thermal_probe"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This reverts commit f05c7b7d9ea9477fcc388476c6f4ade8c66d2d26.
-
-That change was causing a regression in the generic-adc-thermal-probed
-bootrr test as reported in the kernelci-results list [1].
-A proper rework will take longer, so revert it for now.
-
-[1] https://groups.io/g/kernelci-results/message/42660
-
-Fixes: f05c7b7d9ea9 ("thermal/drivers/mediatek: Use devm_of_iomap to avoid resource leak in mtk_thermal_probe")
-Signed-off-by: Ricardo Cañuelo <ricardo.canuelo@collabora.com>
-Suggested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230525121811.3360268-1-ricardo.canuelo@collabora.com
----
- drivers/thermal/mediatek/auxadc_thermal.c | 14 ++------------
- 1 file changed, 2 insertions(+), 12 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -1222,12 +1222,7 @@ static int mtk_thermal_probe(struct plat
- return -ENODEV;
- }
-
-- auxadc_base = devm_of_iomap(&pdev->dev, auxadc, 0, NULL);
-- if (IS_ERR(auxadc_base)) {
-- of_node_put(auxadc);
-- return PTR_ERR(auxadc_base);
-- }
--
-+ auxadc_base = of_iomap(auxadc, 0);
- auxadc_phys_base = of_get_phys_base(auxadc);
-
- of_node_put(auxadc);
-@@ -1243,12 +1238,7 @@ static int mtk_thermal_probe(struct plat
- return -ENODEV;
- }
-
-- apmixed_base = devm_of_iomap(&pdev->dev, apmixedsys, 0, NULL);
-- if (IS_ERR(apmixed_base)) {
-- of_node_put(apmixedsys);
-- return PTR_ERR(apmixed_base);
-- }
--
-+ apmixed_base = of_iomap(apmixedsys, 0);
- apmixed_phys_base = of_get_phys_base(apmixedsys);
-
- of_node_put(apmixedsys);
+++ /dev/null
-From 496f4b08981d8a788ad5a2073fa1c65a2af1862b Mon Sep 17 00:00:00 2001
-From: Chen-Yu Tsai <wenst@chromium.org>
-Date: Tue, 13 Jun 2023 17:13:16 +0800
-Subject: [PATCH 22/42] thermal/drivers/mediatek/lvts_thermal: Register thermal
- zones as hwmon sensors
-
-Register thermal zones as hwmon sensors to let userspace read
-temperatures using standard hwmon interface.
-
-Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230613091317.1691247-1-wenst@chromium.org
----
- drivers/thermal/mediatek/lvts_thermal.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -19,6 +19,8 @@
- #include <linux/thermal.h>
- #include <dt-bindings/thermal/mediatek,lvts-thermal.h>
-
-+#include "../thermal_hwmon.h"
-+
- #define LVTS_MONCTL0(__base) (__base + 0x0000)
- #define LVTS_MONCTL1(__base) (__base + 0x0004)
- #define LVTS_MONCTL2(__base) (__base + 0x0008)
-@@ -996,6 +998,9 @@ static int lvts_ctrl_start(struct device
- return PTR_ERR(tz);
- }
-
-+ if (devm_thermal_add_hwmon_sysfs(dev, tz))
-+ dev_warn(dev, "zone %d: Failed to add hwmon sysfs attributes\n", dt_id);
-+
- /*
- * The thermal zone pointer will be needed in the
- * interrupt handler, we store it in the sensor
+++ /dev/null
-From 885b9768ce2a66ed5d250822aed53d5114c895da Mon Sep 17 00:00:00 2001
-From: Yangtao Li <frank.li@vivo.com>
-Date: Tue, 20 Jun 2023 17:07:31 +0800
-Subject: [PATCH 23/42] thermal/drivers/mediatek/lvts_thermal: Remove redundant
- msg in lvts_ctrl_start()
-
-The upper-layer devm_thermal_add_hwmon_sysfs() function can directly
-print error information.
-
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230620090732.50025-10-frank.li@vivo.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -998,8 +998,7 @@ static int lvts_ctrl_start(struct device
- return PTR_ERR(tz);
- }
-
-- if (devm_thermal_add_hwmon_sysfs(dev, tz))
-- dev_warn(dev, "zone %d: Failed to add hwmon sysfs attributes\n", dt_id);
-+ devm_thermal_add_hwmon_sysfs(dev, tz);
-
- /*
- * The thermal zone pointer will be needed in the
+++ /dev/null
-From 27b389d9f62c2174f95fe4002b11e77d4cb3ce80 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
- <nfraprado@collabora.com>
-Date: Thu, 6 Jul 2023 11:37:32 -0400
-Subject: [PATCH 25/42] thermal/drivers/mediatek/lvts_thermal: Handle IRQ on
- all controllers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There is a single IRQ handler for each LVTS thermal domain, and it is
-supposed to check each of its underlying controllers for the origin of
-the interrupt and clear its status. However due to a typo, only the
-first controller was ever being handled, which resulted in the interrupt
-never being cleared when it happened on the other controllers. Add the
-missing index so interrupts are handled for all controllers.
-
-Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
-Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Tested-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230706153823.201943-2-nfraprado@collabora.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -451,7 +451,7 @@ static irqreturn_t lvts_irq_handler(int
-
- for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
-
-- aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl);
-+ aux = lvts_ctrl_irq_handler(&lvts_td->lvts_ctrl[i]);
- if (aux != IRQ_HANDLED)
- continue;
-
+++ /dev/null
-From 6d827142643ee10c13ff9a1d90f38fb399aa9fff Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
- <nfraprado@collabora.com>
-Date: Thu, 6 Jul 2023 11:37:33 -0400
-Subject: [PATCH 26/42] thermal/drivers/mediatek/lvts_thermal: Honor sensors in
- immediate mode
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Each controller can be configured to operate on immediate or filtered
-mode. On filtered mode, the sensors are enabled by setting the
-corresponding bits in MONCTL0, while on immediate mode, by setting
-MSRCTL1.
-
-Previously, the code would set MSRCTL1 for all four sensors when
-configured to immediate mode, but given that the controller might not
-have all four sensors connected, this would cause interrupts to trigger
-for non-existent sensors. Fix this by handling the MSRCTL1 register
-analogously to the MONCTL0: only enable the sensors that were declared.
-
-Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Tested-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230706153823.201943-3-nfraprado@collabora.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 57 ++++++++++++++-----------
- 1 file changed, 33 insertions(+), 24 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -897,24 +897,6 @@ static int lvts_ctrl_configure(struct de
- writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
-
- /*
-- * LVTS_MSRCTL1 : Measurement control
-- *
-- * Bits:
-- *
-- * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
-- * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
-- * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
-- * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
-- *
-- * That configuration will ignore the filtering and the delays
-- * introduced below in MONCTL1 and MONCTL2
-- */
-- if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
-- value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
-- writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
-- }
--
-- /*
- * LVTS_MONCTL1 : Period unit and group interval configuration
- *
- * The clock source of LVTS thermal controller is 26MHz.
-@@ -979,6 +961,15 @@ static int lvts_ctrl_start(struct device
- struct thermal_zone_device *tz;
- u32 sensor_map = 0;
- int i;
-+ /*
-+ * Bitmaps to enable each sensor on immediate and filtered modes, as
-+ * described in MSRCTL1 and MONCTL0 registers below, respectively.
-+ */
-+ u32 sensor_imm_bitmap[] = { BIT(4), BIT(5), BIT(6), BIT(9) };
-+ u32 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) };
-+
-+ u32 *sensor_bitmap = lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE ?
-+ sensor_imm_bitmap : sensor_filt_bitmap;
-
- for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
-
-@@ -1016,20 +1007,38 @@ static int lvts_ctrl_start(struct device
- * map, so we can enable the temperature monitoring in
- * the hardware thermal controller.
- */
-- sensor_map |= BIT(i);
-+ sensor_map |= sensor_bitmap[i];
- }
-
- /*
-- * Bits:
-- * 9: Single point access flow
-- * 0-3: Enable sensing point 0-3
-- *
- * The initialization of the thermal zones give us
- * which sensor point to enable. If any thermal zone
- * was not described in the device tree, it won't be
- * enabled here in the sensor map.
- */
-- writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
-+ if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
-+ /*
-+ * LVTS_MSRCTL1 : Measurement control
-+ *
-+ * Bits:
-+ *
-+ * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
-+ * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
-+ * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
-+ * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
-+ *
-+ * That configuration will ignore the filtering and the delays
-+ * introduced in MONCTL1 and MONCTL2
-+ */
-+ writel(sensor_map, LVTS_MSRCTL1(lvts_ctrl->base));
-+ } else {
-+ /*
-+ * Bits:
-+ * 9: Single point access flow
-+ * 0-3: Enable sensing point 0-3
-+ */
-+ writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
-+ }
-
- return 0;
- }
+++ /dev/null
-From 93bb11dd19bdcc1fc97c7ceababd0db9fde128ad Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
- <nfraprado@collabora.com>
-Date: Thu, 6 Jul 2023 11:37:34 -0400
-Subject: [PATCH 27/42] thermal/drivers/mediatek/lvts_thermal: Use offset
- threshold for IRQ
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There are two kinds of temperature monitoring interrupts available:
-* High Offset, Low Offset
-* Hot, Hot to normal, Cold
-
-The code currently uses the hot/h2n/cold interrupts, however in a way
-that doesn't work: the cold threshold is left uninitialized, which
-prevents the other thresholds from ever triggering, and the h2n
-interrupt is used as the lower threshold, which prevents the hot
-interrupt from triggering again after the thresholds are updated by the
-thermal framework, since a hot interrupt can only trigger again after
-the hot to normal interrupt has been triggered.
-
-But better yet than addressing those issues, is to use the high/low
-offset interrupts instead. This way only two thresholds need to be
-managed, which have a simpler state machine, making them a better match
-to the thermal framework's high and low thresholds.
-
-Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
-Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230706153823.201943-4-nfraprado@collabora.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -298,9 +298,9 @@ static int lvts_set_trips(struct thermal
- u32 raw_high = lvts_temp_to_raw(high);
-
- /*
-- * Hot to normal temperature threshold
-+ * Low offset temperature threshold
- *
-- * LVTS_H2NTHRE
-+ * LVTS_OFFSETL
- *
- * Bits:
- *
-@@ -309,13 +309,13 @@ static int lvts_set_trips(struct thermal
- if (low != -INT_MAX) {
- pr_debug("%s: Setting low limit temperature interrupt: %d\n",
- thermal_zone_device_type(tz), low);
-- writel(raw_low, LVTS_H2NTHRE(base));
-+ writel(raw_low, LVTS_OFFSETL(base));
- }
-
- /*
-- * Hot temperature threshold
-+ * High offset temperature threshold
- *
-- * LVTS_HTHRE
-+ * LVTS_OFFSETH
- *
- * Bits:
- *
-@@ -323,7 +323,7 @@ static int lvts_set_trips(struct thermal
- */
- pr_debug("%s: Setting high limit temperature interrupt: %d\n",
- thermal_zone_device_type(tz), high);
-- writel(raw_high, LVTS_HTHRE(base));
-+ writel(raw_high, LVTS_OFFSETH(base));
-
- return 0;
- }
+++ /dev/null
-From 8f8cab9d3e90acf1db278ef44ad05f10aefb973f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
- <nfraprado@collabora.com>
-Date: Thu, 6 Jul 2023 11:37:35 -0400
-Subject: [PATCH 28/42] thermal/drivers/mediatek/lvts_thermal: Disable
- undesired interrupts
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Out of the many interrupts supported by the hardware, the only ones of
-interest to the driver currently are:
-* The temperature went over the high offset threshold, for any of the
- sensors
-* The temperature went below the low offset threshold, for any of the
- sensors
-* The temperature went over the stage3 threshold
-
-These are the only thresholds configured by the driver through the
-OFFSETH, OFFSETL, and PROTTC registers, respectively.
-
-The current interrupt mask in LVTS_MONINT_CONF, enables many more
-interrupts, including data ready on sensors for both filtered and
-immediate mode. These are not only not handled by the driver, but they
-are also triggered too often, causing unneeded overhead. Disable these
-unnecessary interrupts.
-
-The meaning of each bit can be seen in the comment describing
-LVTS_MONINTST in the IRQ handler.
-
-Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
-Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230706153823.201943-5-nfraprado@collabora.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -65,7 +65,7 @@
- #define LVTS_HW_FILTER 0x2
- #define LVTS_TSSEL_CONF 0x13121110
- #define LVTS_CALSCALE_CONF 0x300
--#define LVTS_MONINT_CONF 0x9FBF7BDE
-+#define LVTS_MONINT_CONF 0x8300318C
-
- #define LVTS_INT_SENSOR0 0x0009001F
- #define LVTS_INT_SENSOR1 0x001203E0
+++ /dev/null
-From bd1ccf9408e6155564530af5e09b53ae497fe332 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
- <nfraprado@collabora.com>
-Date: Thu, 6 Jul 2023 11:37:36 -0400
-Subject: [PATCH 29/42] thermal/drivers/mediatek/lvts_thermal: Don't leave
- threshold zeroed
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The thermal framework might leave the low threshold unset if there
-aren't any lower trip points. This leaves the register zeroed, which
-translates to a very high temperature for the low threshold. The
-interrupt for this threshold is then immediately triggered, and the
-state machine gets stuck, preventing any other temperature monitoring
-interrupts to ever trigger.
-
-(The same happens by not setting the Cold or Hot to Normal thresholds
-when using those)
-
-Set the unused threshold to a valid low value. This value was chosen so
-that for any valid golden temperature read from the efuse, when the
-value is converted to raw and back again to milliCelsius, the result
-doesn't underflow.
-
-Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
-Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230706153823.201943-6-nfraprado@collabora.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -83,6 +83,8 @@
-
- #define LVTS_HW_SHUTDOWN_MT8195 105000
-
-+#define LVTS_MINIMUM_THRESHOLD 20000
-+
- static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
- static int coeff_b = LVTS_COEFF_B;
-
-@@ -294,7 +296,7 @@ static int lvts_set_trips(struct thermal
- {
- struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
- void __iomem *base = lvts_sensor->base;
-- u32 raw_low = lvts_temp_to_raw(low);
-+ u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD);
- u32 raw_high = lvts_temp_to_raw(high);
-
- /*
-@@ -306,11 +308,9 @@ static int lvts_set_trips(struct thermal
- *
- * 14-0 : Raw temperature for threshold
- */
-- if (low != -INT_MAX) {
-- pr_debug("%s: Setting low limit temperature interrupt: %d\n",
-- thermal_zone_device_type(tz), low);
-- writel(raw_low, LVTS_OFFSETL(base));
-- }
-+ pr_debug("%s: Setting low limit temperature interrupt: %d\n",
-+ thermal_zone_device_type(tz), low);
-+ writel(raw_low, LVTS_OFFSETL(base));
-
- /*
- * High offset temperature threshold
+++ /dev/null
-From d4dd09968cab3249e6148e1c3fccb51824edb411 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
- <nfraprado@collabora.com>
-Date: Thu, 6 Jul 2023 11:37:37 -0400
-Subject: [PATCH 30/42] thermal/drivers/mediatek/lvts_thermal: Manage threshold
- between sensors
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Each LVTS thermal controller can have up to four sensors, each capable
-of triggering its own interrupt when its measured temperature crosses
-the configured threshold. The threshold for each sensor is handled
-separately by the thermal framework, since each one is registered with
-its own thermal zone and trips. However, the temperature thresholds are
-configured on the controller, and therefore are shared between all
-sensors on that controller.
-
-When the temperature measured by the sensors is different enough to
-cause the thermal framework to configure different thresholds for each
-one, interrupts start triggering on sensors outside the last threshold
-configured.
-
-To address the issue, track the thresholds required by each sensor and
-only actually set the highest one in the hardware, and disable
-interrupts for all sensors outside the current configured range.
-
-Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
-Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230706153823.201943-7-nfraprado@collabora.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 69 +++++++++++++++++++++++++
- 1 file changed, 69 insertions(+)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -67,6 +67,11 @@
- #define LVTS_CALSCALE_CONF 0x300
- #define LVTS_MONINT_CONF 0x8300318C
-
-+#define LVTS_MONINT_OFFSET_SENSOR0 0xC
-+#define LVTS_MONINT_OFFSET_SENSOR1 0x180
-+#define LVTS_MONINT_OFFSET_SENSOR2 0x3000
-+#define LVTS_MONINT_OFFSET_SENSOR3 0x3000000
-+
- #define LVTS_INT_SENSOR0 0x0009001F
- #define LVTS_INT_SENSOR1 0x001203E0
- #define LVTS_INT_SENSOR2 0x00247C00
-@@ -112,6 +117,8 @@ struct lvts_sensor {
- void __iomem *base;
- int id;
- int dt_id;
-+ int low_thresh;
-+ int high_thresh;
- };
-
- struct lvts_ctrl {
-@@ -121,6 +128,8 @@ struct lvts_ctrl {
- int num_lvts_sensor;
- int mode;
- void __iomem *base;
-+ int low_thresh;
-+ int high_thresh;
- };
-
- struct lvts_domain {
-@@ -292,12 +301,66 @@ static int lvts_get_temp(struct thermal_
- return 0;
- }
-
-+static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
-+{
-+ u32 masks[] = {
-+ LVTS_MONINT_OFFSET_SENSOR0,
-+ LVTS_MONINT_OFFSET_SENSOR1,
-+ LVTS_MONINT_OFFSET_SENSOR2,
-+ LVTS_MONINT_OFFSET_SENSOR3,
-+ };
-+ u32 value = 0;
-+ int i;
-+
-+ value = readl(LVTS_MONINT(lvts_ctrl->base));
-+
-+ for (i = 0; i < ARRAY_SIZE(masks); i++) {
-+ if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
-+ && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
-+ value |= masks[i];
-+ else
-+ value &= ~masks[i];
-+ }
-+
-+ writel(value, LVTS_MONINT(lvts_ctrl->base));
-+}
-+
-+static bool lvts_should_update_thresh(struct lvts_ctrl *lvts_ctrl, int high)
-+{
-+ int i;
-+
-+ if (high > lvts_ctrl->high_thresh)
-+ return true;
-+
-+ for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++)
-+ if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
-+ && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
-+ return false;
-+
-+ return true;
-+}
-+
- static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
- {
- struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
-+ struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl, sensors[lvts_sensor->id]);
- void __iomem *base = lvts_sensor->base;
- u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD);
- u32 raw_high = lvts_temp_to_raw(high);
-+ bool should_update_thresh;
-+
-+ lvts_sensor->low_thresh = low;
-+ lvts_sensor->high_thresh = high;
-+
-+ should_update_thresh = lvts_should_update_thresh(lvts_ctrl, high);
-+ if (should_update_thresh) {
-+ lvts_ctrl->high_thresh = high;
-+ lvts_ctrl->low_thresh = low;
-+ }
-+ lvts_update_irq_mask(lvts_ctrl);
-+
-+ if (!should_update_thresh)
-+ return 0;
-
- /*
- * Low offset temperature threshold
-@@ -521,6 +584,9 @@ static int lvts_sensor_init(struct devic
- */
- lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
- imm_regs[i] : msr_regs[i];
-+
-+ lvts_sensor[i].low_thresh = INT_MIN;
-+ lvts_sensor[i].high_thresh = INT_MIN;
- };
-
- lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
-@@ -688,6 +754,9 @@ static int lvts_ctrl_init(struct device
- */
- lvts_ctrl[i].hw_tshut_raw_temp =
- lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
-+
-+ lvts_ctrl[i].low_thresh = INT_MIN;
-+ lvts_ctrl[i].high_thresh = INT_MIN;
- }
-
- /*
+++ /dev/null
-From 5af4904adc8b840987000724977c13c706d3b7d8 Mon Sep 17 00:00:00 2001
-From: Minjie Du <duminjie@vivo.com>
-Date: Thu, 13 Jul 2023 12:24:12 +0800
-Subject: [PATCH 31/42] thermal/drivers/mediatek/lvts: Fix parameter check in
- lvts_debugfs_init()
-
-The documentation says "If an error occurs, ERR_PTR(-ERROR) will be
-returned" but the current code checks against a NULL pointer returned.
-
-Fix this by checking if IS_ERR().
-
-Signed-off-by: Minjie Du <duminjie@vivo.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230713042413.2519-1-duminjie@vivo.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -201,7 +201,7 @@ static int lvts_debugfs_init(struct devi
- int i;
-
- lvts_td->dom_dentry = debugfs_create_dir(dev_name(dev), NULL);
-- if (!lvts_td->dom_dentry)
-+ if (IS_ERR(lvts_td->dom_dentry))
- return 0;
-
- for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+++ /dev/null
-From 6186be80317d1dbda34d35c06c084a083938f2d3 Mon Sep 17 00:00:00 2001
-From: Chen Jiahao <chenjiahao16@huawei.com>
-Date: Wed, 2 Aug 2023 17:45:27 +0800
-Subject: [PATCH 32/42] thermal/drivers/mediatek: Clean up redundant
- dev_err_probe()
-
-Referring to platform_get_irq()'s definition, the return value has
-already been checked if ret < 0, and printed via dev_err_probe().
-Calling dev_err_probe() one more time outside platform_get_irq()
-is obviously redundant.
-
-Removing dev_err_probe() outside platform_get_irq() to clean up
-above problem.
-
-Signed-off-by: Chen Jiahao <chenjiahao16@huawei.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230802094527.988842-1-chenjiahao16@huawei.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -1216,7 +1216,7 @@ static int lvts_probe(struct platform_de
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
-- return dev_err_probe(dev, irq, "No irq resource\n");
-+ return irq;
-
- ret = lvts_domain_init(dev, lvts_td, lvts_data);
- if (ret)
+++ /dev/null
-From c2ab54ab0425388e65901a7af2fbf69ead968708 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
- <nfraprado@collabora.com>
-Date: Thu, 13 Jul 2023 11:42:37 -0400
-Subject: [PATCH 33/42] thermal/drivers/mediatek/lvts_thermal: Make readings
- valid in filtered mode
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Currently, when a controller is configured to use filtered mode, thermal
-readings are valid only about 30% of the time.
-
-Upon testing, it was noticed that lowering any of the interval settings
-resulted in an improved rate of valid data. The same was observed when
-decreasing the number of samples for each sensor (which also results in
-quicker measurements).
-
-Retrying the read with a timeout longer than the time it takes to
-resample (about 344us with these settings and 4 sensors) also improves
-the rate.
-
-Lower all timing settings to the minimum, configure the filtering to
-single sample, and poll the measurement register for at least one period
-to improve the data validity on filtered mode. With these changes in
-place, out of 100000 reads, a single one failed, ie 99.999% of the data
-was valid.
-
-Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
-Tested-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230713154743.611870-1-nfraprado@collabora.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 19 ++++++++++++-------
- 1 file changed, 12 insertions(+), 7 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -58,11 +58,11 @@
- #define LVTS_PROTTC(__base) (__base + 0x00CC)
- #define LVTS_CLKEN(__base) (__base + 0x00E4)
-
--#define LVTS_PERIOD_UNIT ((118 * 1000) / (256 * 38))
--#define LVTS_GROUP_INTERVAL 1
--#define LVTS_FILTER_INTERVAL 1
--#define LVTS_SENSOR_INTERVAL 1
--#define LVTS_HW_FILTER 0x2
-+#define LVTS_PERIOD_UNIT 0
-+#define LVTS_GROUP_INTERVAL 0
-+#define LVTS_FILTER_INTERVAL 0
-+#define LVTS_SENSOR_INTERVAL 0
-+#define LVTS_HW_FILTER 0x0
- #define LVTS_TSSEL_CONF 0x13121110
- #define LVTS_CALSCALE_CONF 0x300
- #define LVTS_MONINT_CONF 0x8300318C
-@@ -86,6 +86,9 @@
- #define LVTS_MSR_IMMEDIATE_MODE 0
- #define LVTS_MSR_FILTERED_MODE 1
-
-+#define LVTS_MSR_READ_TIMEOUT_US 400
-+#define LVTS_MSR_READ_WAIT_US (LVTS_MSR_READ_TIMEOUT_US / 2)
-+
- #define LVTS_HW_SHUTDOWN_MT8195 105000
-
- #define LVTS_MINIMUM_THRESHOLD 20000
-@@ -268,6 +271,7 @@ static int lvts_get_temp(struct thermal_
- struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
- void __iomem *msr = lvts_sensor->msr;
- u32 value;
-+ int rc;
-
- /*
- * Measurement registers:
-@@ -280,7 +284,8 @@ static int lvts_get_temp(struct thermal_
- * 16 : Valid temperature
- * 15-0 : Raw temperature
- */
-- value = readl(msr);
-+ rc = readl_poll_timeout(msr, value, value & BIT(16),
-+ LVTS_MSR_READ_WAIT_US, LVTS_MSR_READ_TIMEOUT_US);
-
- /*
- * As the thermal zone temperature will read before the
-@@ -293,7 +298,7 @@ static int lvts_get_temp(struct thermal_
- * functionning temperature and directly jump to a system
- * shutdown.
- */
-- if (!(value & BIT(16)))
-+ if (rc)
- return -EAGAIN;
-
- *temp = lvts_raw_to_temp(value & 0xFFFF);
+++ /dev/null
-From c864ff9de3b225b43bb8e08dedb223632323e059 Mon Sep 17 00:00:00 2001
-From: Andrei Coardos <aboutphysycs@gmail.com>
-Date: Fri, 11 Aug 2023 22:28:47 +0300
-Subject: [PATCH 34/42] thermal/drivers/mediatek/auxadc_thermal: Removed call
- to platform_set_drvdata()
-
-This function call was found to be unnecessary as there is no equivalent
-platform_get_drvdata() call to access the private data of the driver. Also,
-the private data is defined in this driver, so there is no risk of it being
-accessed outside of this driver file.
-
-Signed-off-by: Andrei Coardos <aboutphysycs@gmail.com>
-Reviewed-by: Alexandru Ardelean <alex@shruggie.ro>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230811192847.3838-1-aboutphysycs@gmail.com
----
- drivers/thermal/mediatek/auxadc_thermal.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -1283,8 +1283,6 @@ static int mtk_thermal_probe(struct plat
- mtk_thermal_init_bank(mt, i, apmixed_phys_base,
- auxadc_phys_base, ctrl_id);
-
-- platform_set_drvdata(pdev, mt);
--
- tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
- &mtk_thermal_ops);
- if (IS_ERR(tzdev))
+++ /dev/null
-From 6cf96078969ec00b873db99bae4e47001290685e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
-Date: Wed, 27 Sep 2023 21:37:23 +0200
-Subject: [PATCH 35/42] thermal: lvts: 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: Daniel Lezcano <daniel.lezcano@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
----
- drivers/thermal/mediatek/lvts_thermal.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -1241,7 +1241,7 @@ static int lvts_probe(struct platform_de
- return 0;
- }
-
--static int lvts_remove(struct platform_device *pdev)
-+static void lvts_remove(struct platform_device *pdev)
- {
- struct lvts_domain *lvts_td;
- int i;
-@@ -1252,8 +1252,6 @@ static int lvts_remove(struct platform_d
- lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
-
- lvts_debugfs_exit(lvts_td);
--
-- return 0;
- }
-
- static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
-@@ -1354,7 +1352,7 @@ MODULE_DEVICE_TABLE(of, lvts_of_match);
-
- static struct platform_driver lvts_driver = {
- .probe = lvts_probe,
-- .remove = lvts_remove,
-+ .remove_new = lvts_remove,
- .driver = {
- .name = "mtk-lvts-thermal",
- .of_match_table = lvts_of_match,
+++ /dev/null
-From 26cc18a3d6d9eac21c4f4b4bb96147b2c6617c86 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Fri, 22 Sep 2023 07:50:19 +0200
-Subject: [PATCH 36/42] thermal/drivers/mediatek/lvts_thermal: Make coeff
- configurable
-
-The upcoming mt7988 has different temperature coefficients so we
-cannot use constants in the functions lvts_golden_temp_init,
-lvts_golden_temp_init and lvts_raw_to_temp anymore.
-
-Add a field in the lvts_ctrl pointing to the lvts_data which now
-contains the soc-specific temperature coefficents.
-
-To make the code better readable, rename static int coeff_b to
-golden_temp_offset, COEFF_A to temp_factor and COEFF_B to temp_offset.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230922055020.6436-4-linux@fw-web.de
----
- drivers/thermal/mediatek/lvts_thermal.c | 51 ++++++++++++++++---------
- 1 file changed, 34 insertions(+), 17 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -80,8 +80,8 @@
- #define LVTS_SENSOR_MAX 4
- #define LVTS_GOLDEN_TEMP_MAX 62
- #define LVTS_GOLDEN_TEMP_DEFAULT 50
--#define LVTS_COEFF_A -250460
--#define LVTS_COEFF_B 250460
-+#define LVTS_COEFF_A_MT8195 -250460
-+#define LVTS_COEFF_B_MT8195 250460
-
- #define LVTS_MSR_IMMEDIATE_MODE 0
- #define LVTS_MSR_FILTERED_MODE 1
-@@ -94,7 +94,7 @@
- #define LVTS_MINIMUM_THRESHOLD 20000
-
- static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
--static int coeff_b = LVTS_COEFF_B;
-+static int golden_temp_offset;
-
- struct lvts_sensor_data {
- int dt_id;
-@@ -112,6 +112,8 @@ struct lvts_ctrl_data {
- struct lvts_data {
- const struct lvts_ctrl_data *lvts_ctrl;
- int num_lvts_ctrl;
-+ int temp_factor;
-+ int temp_offset;
- };
-
- struct lvts_sensor {
-@@ -126,6 +128,7 @@ struct lvts_sensor {
-
- struct lvts_ctrl {
- struct lvts_sensor sensors[LVTS_SENSOR_MAX];
-+ const struct lvts_data *lvts_data;
- u32 calibration[LVTS_SENSOR_MAX];
- u32 hw_tshut_raw_temp;
- int num_lvts_sensor;
-@@ -247,21 +250,21 @@ static void lvts_debugfs_exit(struct lvt
-
- #endif
-
--static int lvts_raw_to_temp(u32 raw_temp)
-+static int lvts_raw_to_temp(u32 raw_temp, int temp_factor)
- {
- int temperature;
-
-- temperature = ((s64)(raw_temp & 0xFFFF) * LVTS_COEFF_A) >> 14;
-- temperature += coeff_b;
-+ temperature = ((s64)(raw_temp & 0xFFFF) * temp_factor) >> 14;
-+ temperature += golden_temp_offset;
-
- return temperature;
- }
-
--static u32 lvts_temp_to_raw(int temperature)
-+static u32 lvts_temp_to_raw(int temperature, int temp_factor)
- {
-- u32 raw_temp = ((s64)(coeff_b - temperature)) << 14;
-+ u32 raw_temp = ((s64)(golden_temp_offset - temperature)) << 14;
-
-- raw_temp = div_s64(raw_temp, -LVTS_COEFF_A);
-+ raw_temp = div_s64(raw_temp, -temp_factor);
-
- return raw_temp;
- }
-@@ -269,6 +272,9 @@ static u32 lvts_temp_to_raw(int temperat
- static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
- {
- struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
-+ struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
-+ sensors[lvts_sensor->id]);
-+ const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
- void __iomem *msr = lvts_sensor->msr;
- u32 value;
- int rc;
-@@ -301,7 +307,7 @@ static int lvts_get_temp(struct thermal_
- if (rc)
- return -EAGAIN;
-
-- *temp = lvts_raw_to_temp(value & 0xFFFF);
-+ *temp = lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);
-
- return 0;
- }
-@@ -348,10 +354,13 @@ static bool lvts_should_update_thresh(st
- static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
- {
- struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
-- struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl, sensors[lvts_sensor->id]);
-+ struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
-+ sensors[lvts_sensor->id]);
-+ const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
- void __iomem *base = lvts_sensor->base;
-- u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD);
-- u32 raw_high = lvts_temp_to_raw(high);
-+ u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD,
-+ lvts_data->temp_factor);
-+ u32 raw_high = lvts_temp_to_raw(high, lvts_data->temp_factor);
- bool should_update_thresh;
-
- lvts_sensor->low_thresh = low;
-@@ -692,7 +701,7 @@ static int lvts_calibration_read(struct
- return 0;
- }
-
--static int lvts_golden_temp_init(struct device *dev, u32 *value)
-+static int lvts_golden_temp_init(struct device *dev, u32 *value, int temp_offset)
- {
- u32 gt;
-
-@@ -701,7 +710,7 @@ static int lvts_golden_temp_init(struct
- if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
- golden_temp = gt;
-
-- coeff_b = golden_temp * 500 + LVTS_COEFF_B;
-+ golden_temp_offset = golden_temp * 500 + temp_offset;
-
- return 0;
- }
-@@ -724,7 +733,7 @@ static int lvts_ctrl_init(struct device
- * The golden temp information is contained in the first chunk
- * of efuse data.
- */
-- ret = lvts_golden_temp_init(dev, (u32 *)lvts_td->calib);
-+ ret = lvts_golden_temp_init(dev, (u32 *)lvts_td->calib, lvts_data->temp_offset);
- if (ret)
- return ret;
-
-@@ -735,6 +744,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;
-+ lvts_ctrl[i].lvts_data = lvts_data;
-
- ret = lvts_sensor_init(dev, &lvts_ctrl[i],
- &lvts_data->lvts_ctrl[i]);
-@@ -758,7 +768,8 @@ static int lvts_ctrl_init(struct device
- * after initializing the calibration.
- */
- lvts_ctrl[i].hw_tshut_raw_temp =
-- lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
-+ lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp,
-+ lvts_data->temp_factor);
-
- lvts_ctrl[i].low_thresh = INT_MIN;
- lvts_ctrl[i].high_thresh = INT_MIN;
-@@ -1223,6 +1234,8 @@ static int lvts_probe(struct platform_de
- if (irq < 0)
- return irq;
-
-+ golden_temp_offset = lvts_data->temp_offset;
-+
- ret = lvts_domain_init(dev, lvts_td, lvts_data);
- if (ret)
- return dev_err_probe(dev, ret, "Failed to initialize the lvts domain\n");
-@@ -1336,11 +1349,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),
-+ .temp_factor = LVTS_COEFF_A_MT8195,
-+ .temp_offset = LVTS_COEFF_B_MT8195,
- };
-
- static const struct lvts_data mt8195_lvts_ap_data = {
- .lvts_ctrl = mt8195_lvts_ap_data_ctrl,
- .num_lvts_ctrl = ARRAY_SIZE(mt8195_lvts_ap_data_ctrl),
-+ .temp_factor = LVTS_COEFF_A_MT8195,
-+ .temp_offset = LVTS_COEFF_B_MT8195,
- };
-
- static const struct of_device_id lvts_of_match[] = {
+++ /dev/null
-From be2cc09bd5b46f13629d4fcdeac7ad1b18bb1a0b Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Fri, 22 Sep 2023 07:50:18 +0200
-Subject: [PATCH] dt-bindings: thermal: mediatek: Add LVTS thermal sensors for
- mt7988
-
-Add sensor constants for MT7988.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Acked-by: Conor Dooley <conor.dooley@microchip.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230922055020.6436-3-linux@fw-web.de
----
- include/dt-bindings/thermal/mediatek,lvts-thermal.h | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h
-+++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
-@@ -7,6 +7,15 @@
- #ifndef __MEDIATEK_LVTS_DT_H
- #define __MEDIATEK_LVTS_DT_H
-
-+#define MT7988_CPU_0 0
-+#define MT7988_CPU_1 1
-+#define MT7988_ETH2P5G_0 2
-+#define MT7988_ETH2P5G_1 3
-+#define MT7988_TOPS_0 4
-+#define MT7988_TOPS_1 5
-+#define MT7988_ETHWARP_0 6
-+#define MT7988_ETHWARP_1 7
-+
- #define MT8195_MCU_BIG_CPU0 0
- #define MT8195_MCU_BIG_CPU1 1
- #define MT8195_MCU_BIG_CPU2 2
+++ /dev/null
-From 9924e9b91b43aaa1610a1d59c4caa43785948cf6 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Fri, 22 Sep 2023 07:50:20 +0200
-Subject: [PATCH 37/42] thermal/drivers/mediatek/lvts_thermal: Add mt7988
- support
-
-Add Support for Mediatek Filogic 880/MT7988 LVTS.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Tested-by: Daniel Golle <daniel@makrotopia.org>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230922055020.6436-5-linux@fw-web.de
----
- drivers/thermal/mediatek/lvts_thermal.c | 38 +++++++++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -82,6 +82,8 @@
- #define LVTS_GOLDEN_TEMP_DEFAULT 50
- #define LVTS_COEFF_A_MT8195 -250460
- #define LVTS_COEFF_B_MT8195 250460
-+#define LVTS_COEFF_A_MT7988 -204650
-+#define LVTS_COEFF_B_MT7988 204650
-
- #define LVTS_MSR_IMMEDIATE_MODE 0
- #define LVTS_MSR_FILTERED_MODE 1
-@@ -89,6 +91,7 @@
- #define LVTS_MSR_READ_TIMEOUT_US 400
- #define LVTS_MSR_READ_WAIT_US (LVTS_MSR_READ_TIMEOUT_US / 2)
-
-+#define LVTS_HW_SHUTDOWN_MT7988 105000
- #define LVTS_HW_SHUTDOWN_MT8195 105000
-
- #define LVTS_MINIMUM_THRESHOLD 20000
-@@ -1267,6 +1270,33 @@ static void lvts_remove(struct platform_
- lvts_debugfs_exit(lvts_td);
- }
-
-+static const struct lvts_ctrl_data mt7988_lvts_ap_data_ctrl[] = {
-+ {
-+ .cal_offset = { 0x00, 0x04, 0x08, 0x0c },
-+ .lvts_sensor = {
-+ { .dt_id = MT7988_CPU_0 },
-+ { .dt_id = MT7988_CPU_1 },
-+ { .dt_id = MT7988_ETH2P5G_0 },
-+ { .dt_id = MT7988_ETH2P5G_1 }
-+ },
-+ .num_lvts_sensor = 4,
-+ .offset = 0x0,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT7988,
-+ },
-+ {
-+ .cal_offset = { 0x14, 0x18, 0x1c, 0x20 },
-+ .lvts_sensor = {
-+ { .dt_id = MT7988_TOPS_0},
-+ { .dt_id = MT7988_TOPS_1},
-+ { .dt_id = MT7988_ETHWARP_0},
-+ { .dt_id = MT7988_ETHWARP_1}
-+ },
-+ .num_lvts_sensor = 4,
-+ .offset = 0x100,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT7988,
-+ }
-+};
-+
- static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
- {
- .cal_offset = { 0x04, 0x07 },
-@@ -1346,6 +1376,13 @@ static const struct lvts_ctrl_data mt819
- }
- };
-
-+static const struct lvts_data mt7988_lvts_ap_data = {
-+ .lvts_ctrl = mt7988_lvts_ap_data_ctrl,
-+ .num_lvts_ctrl = ARRAY_SIZE(mt7988_lvts_ap_data_ctrl),
-+ .temp_factor = LVTS_COEFF_A_MT7988,
-+ .temp_offset = LVTS_COEFF_B_MT7988,
-+};
-+
- 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),
-@@ -1361,6 +1398,7 @@ 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 },
- { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
- { .compatible = "mediatek,mt8195-lvts-ap", .data = &mt8195_lvts_ap_data },
- {},
+++ /dev/null
-From fb1bbb5b63e4e3c788a978724749ced57d208054 Mon Sep 17 00:00:00 2001
-From: Minjie Du <duminjie@vivo.com>
-Date: Thu, 21 Sep 2023 17:10:50 +0800
-Subject: [PATCH 38/42] thermal/drivers/mediatek/lvts_thermal: Fix error check
- in lvts_debugfs_init()
-
-debugfs_create_dir() function returns an error value embedded in
-the pointer (PTR_ERR). Evaluate the return value using IS_ERR
-rather than checking for NULL.
-
-Signed-off-by: Minjie Du <duminjie@vivo.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230921091057.3812-1-duminjie@vivo.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -219,7 +219,7 @@ static int lvts_debugfs_init(struct devi
-
- sprintf(name, "controller%d", i);
- dentry = debugfs_create_dir(name, lvts_td->dom_dentry);
-- if (!dentry)
-+ if (IS_ERR(dentry))
- continue;
-
- regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
+++ /dev/null
-From e6f43063f2fe9f08b34797bc6d223f7d63b01910 Mon Sep 17 00:00:00 2001
-From: Markus Schneider-Pargmann <msp@baylibre.com>
-Date: Mon, 18 Sep 2023 12:07:06 +0200
-Subject: [PATCH 39/42] thermal/drivers/mediatek: Fix probe for THERMAL_V2
-
-Fix the probe function to call mtk_thermal_release_periodic_ts for
-everything != MTK_THERMAL_V1. This was accidentally changed from V1
-to V2 in the original patch.
-
-Reported-by: Frank Wunderlich <frank-w@public-files.de>
-Closes: https://lore.kernel.org/lkml/B0B3775B-B8D1-4284-814F-4F41EC22F532@public-files.de/
-Reported-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Closes: https://lore.kernel.org/lkml/07a569b9-e691-64ea-dd65-3b49842af33d@linaro.org/
-Fixes: 33140e668b10 ("thermal/drivers/mediatek: Control buffer enablement tweaks")
-Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20230918100706.1229239-1-msp@baylibre.com
----
- drivers/thermal/mediatek/auxadc_thermal.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -1268,7 +1268,7 @@ static int mtk_thermal_probe(struct plat
-
- mtk_thermal_turn_on_buffer(mt, apmixed_base);
-
-- if (mt->conf->version != MTK_THERMAL_V2)
-+ if (mt->conf->version != MTK_THERMAL_V1)
- mtk_thermal_release_periodic_ts(mt, auxadc_base);
-
- if (mt->conf->version == MTK_THERMAL_V1)
+++ /dev/null
-From a1d874ef3376295ee8ed89b3b5315f4c840ff00b Mon Sep 17 00:00:00 2001
-From: Balsam CHIHI <bchihi@baylibre.com>
-Date: Tue, 17 Oct 2023 21:05:42 +0200
-Subject: [PATCH 40/42] thermal/drivers/mediatek/lvts_thermal: Add suspend and
- resume
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add suspend and resume support to LVTS driver.
-
-Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
-[bero@baylibre.com: suspend/resume in noirq phase]
-Co-developed-by: Bernhard Rosenkränzer <bero@baylibre.com>
-Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
-Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20231017190545.157282-3-bero@baylibre.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 37 +++++++++++++++++++++++++
- 1 file changed, 37 insertions(+)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -1297,6 +1297,38 @@ static const struct lvts_ctrl_data mt798
- }
- };
-
-+static int lvts_suspend(struct device *dev)
-+{
-+ struct lvts_domain *lvts_td;
-+ int i;
-+
-+ lvts_td = dev_get_drvdata(dev);
-+
-+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
-+ lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
-+
-+ clk_disable_unprepare(lvts_td->clk);
-+
-+ return 0;
-+}
-+
-+static int lvts_resume(struct device *dev)
-+{
-+ struct lvts_domain *lvts_td;
-+ int i, ret;
-+
-+ lvts_td = dev_get_drvdata(dev);
-+
-+ ret = clk_prepare_enable(lvts_td->clk);
-+ if (ret)
-+ return ret;
-+
-+ for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
-+ lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], true);
-+
-+ return 0;
-+}
-+
- static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
- {
- .cal_offset = { 0x04, 0x07 },
-@@ -1405,12 +1437,17 @@ static const struct of_device_id lvts_of
- };
- MODULE_DEVICE_TABLE(of, lvts_of_match);
-
-+static const struct dev_pm_ops lvts_pm_ops = {
-+ NOIRQ_SYSTEM_SLEEP_PM_OPS(lvts_suspend, lvts_resume)
-+};
-+
- static struct platform_driver lvts_driver = {
- .probe = lvts_probe,
- .remove_new = lvts_remove,
- .driver = {
- .name = "mtk-lvts-thermal",
- .of_match_table = lvts_of_match,
-+ .pm = &lvts_pm_ops,
- },
- };
- module_platform_driver(lvts_driver);
+++ /dev/null
-From 0bb4937b58ab712f158588376dbac97f8e9df68e Mon Sep 17 00:00:00 2001
-From: Balsam CHIHI <bchihi@baylibre.com>
-Date: Tue, 17 Oct 2023 21:05:41 +0200
-Subject: [PATCH] dt-bindings: thermal: mediatek: Add LVTS thermal controller
- definition for mt8192
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add LVTS thermal controller definition for MT8192.
-
-Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
-Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20231017190545.157282-2-bero@baylibre.com
----
- .../thermal/mediatek,lvts-thermal.h | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
-
---- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h
-+++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
-@@ -35,4 +35,23 @@
- #define MT8195_AP_CAM0 15
- #define MT8195_AP_CAM1 16
-
-+#define MT8192_MCU_BIG_CPU0 0
-+#define MT8192_MCU_BIG_CPU1 1
-+#define MT8192_MCU_BIG_CPU2 2
-+#define MT8192_MCU_BIG_CPU3 3
-+#define MT8192_MCU_LITTLE_CPU0 4
-+#define MT8192_MCU_LITTLE_CPU1 5
-+#define MT8192_MCU_LITTLE_CPU2 6
-+#define MT8192_MCU_LITTLE_CPU3 7
-+
-+#define MT8192_AP_VPU0 8
-+#define MT8192_AP_VPU1 9
-+#define MT8192_AP_GPU0 10
-+#define MT8192_AP_GPU1 11
-+#define MT8192_AP_INFRA 12
-+#define MT8192_AP_CAM 13
-+#define MT8192_AP_MD0 14
-+#define MT8192_AP_MD1 15
-+#define MT8192_AP_MD2 16
-+
- #endif /* __MEDIATEK_LVTS_DT_H */
+++ /dev/null
-From 7d8b3864b38d881cf105328ff8569f47446811ad Mon Sep 17 00:00:00 2001
-From: Balsam CHIHI <bchihi@baylibre.com>
-Date: Tue, 17 Oct 2023 21:05:43 +0200
-Subject: [PATCH 41/42] thermal/drivers/mediatek/lvts_thermal: Add mt8192
- support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add LVTS Driver support for MT8192.
-
-Co-developed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
-Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-[bero@baylibre.com: cosmetic changes, rebase]
-Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
-Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20231017190545.157282-4-bero@baylibre.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 95 +++++++++++++++++++++++++
- 1 file changed, 95 insertions(+)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -92,6 +92,7 @@
- #define LVTS_MSR_READ_WAIT_US (LVTS_MSR_READ_TIMEOUT_US / 2)
-
- #define LVTS_HW_SHUTDOWN_MT7988 105000
-+#define LVTS_HW_SHUTDOWN_MT8192 105000
- #define LVTS_HW_SHUTDOWN_MT8195 105000
-
- #define LVTS_MINIMUM_THRESHOLD 20000
-@@ -1329,6 +1330,88 @@ static int lvts_resume(struct device *de
- return 0;
- }
-
-+static const struct lvts_ctrl_data mt8192_lvts_mcu_data_ctrl[] = {
-+ {
-+ .cal_offset = { 0x04, 0x08 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8192_MCU_BIG_CPU0 },
-+ { .dt_id = MT8192_MCU_BIG_CPU1 }
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x0,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
-+ .mode = LVTS_MSR_FILTERED_MODE,
-+ },
-+ {
-+ .cal_offset = { 0x0c, 0x10 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8192_MCU_BIG_CPU2 },
-+ { .dt_id = MT8192_MCU_BIG_CPU3 }
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x100,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
-+ .mode = LVTS_MSR_FILTERED_MODE,
-+ },
-+ {
-+ .cal_offset = { 0x14, 0x18, 0x1c, 0x20 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8192_MCU_LITTLE_CPU0 },
-+ { .dt_id = MT8192_MCU_LITTLE_CPU1 },
-+ { .dt_id = MT8192_MCU_LITTLE_CPU2 },
-+ { .dt_id = MT8192_MCU_LITTLE_CPU3 }
-+ },
-+ .num_lvts_sensor = 4,
-+ .offset = 0x200,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
-+ .mode = LVTS_MSR_FILTERED_MODE,
-+ }
-+};
-+
-+static const struct lvts_ctrl_data mt8192_lvts_ap_data_ctrl[] = {
-+ {
-+ .cal_offset = { 0x24, 0x28 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8192_AP_VPU0 },
-+ { .dt_id = MT8192_AP_VPU1 }
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x0,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
-+ },
-+ {
-+ .cal_offset = { 0x2c, 0x30 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8192_AP_GPU0 },
-+ { .dt_id = MT8192_AP_GPU1 }
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x100,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
-+ },
-+ {
-+ .cal_offset = { 0x34, 0x38 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8192_AP_INFRA },
-+ { .dt_id = MT8192_AP_CAM },
-+ },
-+ .num_lvts_sensor = 2,
-+ .offset = 0x200,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
-+ },
-+ {
-+ .cal_offset = { 0x3c, 0x40, 0x44 },
-+ .lvts_sensor = {
-+ { .dt_id = MT8192_AP_MD0 },
-+ { .dt_id = MT8192_AP_MD1 },
-+ { .dt_id = MT8192_AP_MD2 }
-+ },
-+ .num_lvts_sensor = 3,
-+ .offset = 0x300,
-+ .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
-+ }
-+};
-+
- static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
- {
- .cal_offset = { 0x04, 0x07 },
-@@ -1415,6 +1498,16 @@ static const struct lvts_data mt7988_lvt
- .temp_offset = LVTS_COEFF_B_MT7988,
- };
-
-+static const struct lvts_data mt8192_lvts_mcu_data = {
-+ .lvts_ctrl = mt8192_lvts_mcu_data_ctrl,
-+ .num_lvts_ctrl = ARRAY_SIZE(mt8192_lvts_mcu_data_ctrl),
-+};
-+
-+static const struct lvts_data mt8192_lvts_ap_data = {
-+ .lvts_ctrl = mt8192_lvts_ap_data_ctrl,
-+ .num_lvts_ctrl = ARRAY_SIZE(mt8192_lvts_ap_data_ctrl),
-+};
-+
- 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),
-@@ -1431,6 +1524,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 },
-+ { .compatible = "mediatek,mt8192-lvts-mcu", .data = &mt8192_lvts_mcu_data },
-+ { .compatible = "mediatek,mt8192-lvts-ap", .data = &mt8192_lvts_ap_data },
- { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
- { .compatible = "mediatek,mt8195-lvts-ap", .data = &mt8195_lvts_ap_data },
- {},
+++ /dev/null
-From 5d126a3c87cf7964b28bacf3826eea4266265bce Mon Sep 17 00:00:00 2001
-From: Balsam CHIHI <bchihi@baylibre.com>
-Date: Tue, 17 Oct 2023 21:05:45 +0200
-Subject: [PATCH 42/42] thermal/drivers/mediatek/lvts_thermal: Update
- calibration data documentation
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Update LVTS calibration data documentation for mt8192 and mt8195.
-
-Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
-Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
-[bero@baylibre.com: Fix issues pointed out by Nícolas F. R. A. Prado <nfraprado@collabora.com>]
-Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20231017190545.157282-6-bero@baylibre.com
----
- drivers/thermal/mediatek/lvts_thermal.c | 31 +++++++++++++++++++++++--
- 1 file changed, 29 insertions(+), 2 deletions(-)
-
---- a/drivers/thermal/mediatek/lvts_thermal.c
-+++ b/drivers/thermal/mediatek/lvts_thermal.c
-@@ -616,7 +616,34 @@ static int lvts_sensor_init(struct devic
- * The efuse blob values follows the sensor enumeration per thermal
- * controller. The decoding of the stream is as follow:
- *
-- * stream index map for MCU Domain :
-+ * MT8192 :
-+ * Stream index map for MCU Domain mt8192 :
-+ *
-+ * <-----mcu-tc#0-----> <-----sensor#0-----> <-----sensor#1----->
-+ * 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09 | 0x0A | 0x0B
-+ *
-+ * <-----sensor#2-----> <-----sensor#3----->
-+ * 0x0C | 0x0D | 0x0E | 0x0F | 0x10 | 0x11 | 0x12 | 0x13
-+ *
-+ * <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6-----> <-----sensor#7----->
-+ * 0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21 | 0x22 | 0x23
-+ *
-+ * Stream index map for AP Domain mt8192 :
-+ *
-+ * <-----sensor#0-----> <-----sensor#1----->
-+ * 0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A | 0x2B
-+ *
-+ * <-----sensor#2-----> <-----sensor#3----->
-+ * 0x2C | 0x2D | 0x2E | 0x2F | 0x30 | 0x31 | 0x32 | 0x33
-+ *
-+ * <-----sensor#4-----> <-----sensor#5----->
-+ * 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 | 0x3A | 0x3B
-+ *
-+ * <-----sensor#6-----> <-----sensor#7-----> <-----sensor#8----->
-+ * 0x3C | 0x3D | 0x3E | 0x3F | 0x40 | 0x41 | 0x42 | 0x43 | 0x44 | 0x45 | 0x46 | 0x47
-+ *
-+ * MT8195 :
-+ * Stream index map for MCU Domain mt8195 :
- *
- * <-----mcu-tc#0-----> <-----sensor#0-----> <-----sensor#1----->
- * 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09
-@@ -627,7 +654,7 @@ static int lvts_sensor_init(struct devic
- * <-----mcu-tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6-----> <-----sensor#7----->
- * 0x13 | 0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21
- *
-- * stream index map for AP Domain :
-+ * Stream index map for AP Domain mt8195 :
- *
- * <-----ap--tc#0-----> <-----sensor#0-----> <-----sensor#1----->
- * 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A
+++ /dev/null
-From patchwork Thu Sep 7 11:20:18 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Frank Wunderlich <linux@fw-web.de>
-X-Patchwork-Id: 13376356
-From: Frank Wunderlich <linux@fw-web.de>
-To: linux-mediatek@lists.infradead.org
-Subject: [PATCH] thermal/drivers/mediatek: Fix control buffer enablement on
- MT7896
-Date: Thu, 7 Sep 2023 13:20:18 +0200
-Message-Id: <20230907112018.52811-1-linux@fw-web.de>
-X-Mailer: git-send-email 2.34.1
-MIME-Version: 1.0
-X-Mail-ID: e7eeb8e1-00de-41f6-a5df-ce2e9164136e
-X-BeenThere: linux-mediatek@lists.infradead.org
-X-Mailman-Version: 2.1.34
-Precedence: list
-List-Id: <linux-mediatek.lists.infradead.org>
-Cc: Daniel Lezcano <daniel.lezcano@linaro.org>,
- "Rafael J. Wysocki" <rafael@kernel.org>, linux-pm@vger.kernel.org,
- Amit Kucheria <amitk@kernel.org>, Daniel Golle <daniel@makrotopia.org>,
- stable@vger.kernel.org, linux-kernel@vger.kernel.org,
- Matthias Brugger <matthias.bgg@gmail.com>, Zhang Rui <rui.zhang@intel.com>,
- linux-arm-kernel@lists.infradead.org,
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
-
-From: Frank Wunderlich <frank-w@public-files.de>
-
-Reading thermal sensor on mt7986 devices returns invalid temperature:
-
-bpi-r3 ~ # cat /sys/class/thermal/thermal_zone0/temp
- -274000
-
-Fix this by adding missing members in mtk_thermal_data struct which were
-used in mtk_thermal_turn_on_buffer after commit 33140e668b10.
-
-Cc: stable@vger.kernel.org
-Fixes: 33140e668b10 ("thermal/drivers/mediatek: Control buffer enablement tweaks")
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
----
- drivers/thermal/mediatek/auxadc_thermal.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/thermal/mediatek/auxadc_thermal.c
-+++ b/drivers/thermal/mediatek/auxadc_thermal.c
-@@ -691,6 +691,9 @@ static const struct mtk_thermal_data mt7
- .adcpnp = mt7986_adcpnp,
- .sensor_mux_values = mt7986_mux_values,
- .version = MTK_THERMAL_V3,
-+ .apmixed_buffer_ctl_reg = APMIXED_SYS_TS_CON1,
-+ .apmixed_buffer_ctl_mask = GENMASK(31, 6) | BIT(3),
-+ .apmixed_buffer_ctl_set = BIT(0),
- };
-
- static bool mtk_thermal_temp_is_valid(int temp)
+++ /dev/null
-From 11f9a0f4e51887ad7b4a2898a368fcd0c2984e89 Mon Sep 17 00:00:00 2001
-From: Frank Wunderlich <frank-w@public-files.de>
-Date: Sun, 9 Oct 2022 12:16:31 +0200
-Subject: [PATCH 12/16] i2c: mediatek: add mt7986 support
-
-Add i2c support for MT7986 SoC.
-
-Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Wolfram Sang <wsa@kernel.org>
----
- drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/drivers/i2c/busses/i2c-mt65xx.c
-+++ b/drivers/i2c/busses/i2c-mt65xx.c
-@@ -431,6 +431,19 @@ static const struct mtk_i2c_compatible m
- .max_dma_support = 33,
- };
-
-+static const struct mtk_i2c_compatible mt7986_compat = {
-+ .quirks = &mt7622_i2c_quirks,
-+ .regs = mt_i2c_regs_v1,
-+ .pmic_i2c = 0,
-+ .dcm = 1,
-+ .auto_restart = 1,
-+ .aux_len_reg = 1,
-+ .timing_adjust = 0,
-+ .dma_sync = 1,
-+ .ltiming_adjust = 0,
-+ .max_dma_support = 32,
-+};
-+
- static const struct mtk_i2c_compatible mt8173_compat = {
- .regs = mt_i2c_regs_v1,
- .pmic_i2c = 0,
-@@ -503,6 +516,7 @@ static const struct of_device_id mtk_i2c
- { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
- { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
- { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
-+ { .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },
- { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },
- { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
- { .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
+++ /dev/null
-From 98204ccafd45a8a6109ff2d60e2c179b95d92578 Mon Sep 17 00:00:00 2001
-From: ye xingchen <ye.xingchen@zte.com.cn>
-Date: Thu, 19 Jan 2023 17:19:58 +0800
-Subject: [PATCH 13/16] i2c: mt65xx: 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: ye xingchen <ye.xingchen@zte.com.cn>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Wolfram Sang <wsa@kernel.org>
----
- drivers/i2c/busses/i2c-mt65xx.c | 7 ++-----
- 1 file changed, 2 insertions(+), 5 deletions(-)
-
---- a/drivers/i2c/busses/i2c-mt65xx.c
-+++ b/drivers/i2c/busses/i2c-mt65xx.c
-@@ -1366,20 +1366,17 @@ static int mtk_i2c_probe(struct platform
- {
- int ret = 0;
- struct mtk_i2c *i2c;
-- struct resource *res;
- int i, irq, speed_clk;
-
- i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
- if (!i2c)
- return -ENOMEM;
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- i2c->base = devm_ioremap_resource(&pdev->dev, res);
-+ i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
- if (IS_ERR(i2c->base))
- return PTR_ERR(i2c->base);
-
-- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-- i2c->pdmabase = devm_ioremap_resource(&pdev->dev, res);
-+ i2c->pdmabase = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
- if (IS_ERR(i2c->pdmabase))
- return PTR_ERR(i2c->pdmabase);
-
+++ /dev/null
-From 8106fa2e0ae6082833fe1df97829c46c0183eaea Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Sat, 11 Mar 2023 12:16:54 +0100
-Subject: [PATCH 14/16] i2c: mt65xx: drop of_match_ptr for ID table
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The driver can match only via the DT table so the table should be always
-used and the of_match_ptr does not have any sense (this also allows ACPI
-matching via PRP0001, even though it might not be relevant here).
-
- drivers/i2c/busses/i2c-mt65xx.c:514:34: error: ‘mtk_i2c_of_match’ defined but not used [-Werror=unused-const-variable=]
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Guenter Roeck <groeck@chromium.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Signed-off-by: Wolfram Sang <wsa@kernel.org>
----
- drivers/i2c/busses/i2c-mt65xx.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/i2c/busses/i2c-mt65xx.c
-+++ b/drivers/i2c/busses/i2c-mt65xx.c
-@@ -1546,7 +1546,7 @@ static struct platform_driver mtk_i2c_dr
- .driver = {
- .name = I2C_DRV_NAME,
- .pm = &mtk_i2c_pm,
-- .of_match_table = of_match_ptr(mtk_i2c_of_match),
-+ .of_match_table = mtk_i2c_of_match,
- },
- };
-
+++ /dev/null
-From f69f3d662ba3bf999c36d9ac1e684540c4487bc3 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 10 Apr 2023 17:19:38 +0100
-Subject: [PATCH 15/16] i2c: mediatek: add support for MT7981 SoC
-
-Add support for the I2C units found in the MediaTek MT7981 and MT7988
-SoCs. Just like other recent MediaTek I2C units that also uses v3
-register offsets (which differ from v2 only by OFFSET_SLAVE_ADDR being
-0x94 instead of 0x4).
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
-Signed-off-by: Wolfram Sang <wsa@kernel.org>
----
- drivers/i2c/busses/i2c-mt65xx.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/drivers/i2c/busses/i2c-mt65xx.c
-+++ b/drivers/i2c/busses/i2c-mt65xx.c
-@@ -431,6 +431,18 @@ static const struct mtk_i2c_compatible m
- .max_dma_support = 33,
- };
-
-+static const struct mtk_i2c_compatible mt7981_compat = {
-+ .regs = mt_i2c_regs_v3,
-+ .pmic_i2c = 0,
-+ .dcm = 0,
-+ .auto_restart = 1,
-+ .aux_len_reg = 1,
-+ .timing_adjust = 1,
-+ .dma_sync = 1,
-+ .ltiming_adjust = 1,
-+ .max_dma_support = 33
-+};
-+
- static const struct mtk_i2c_compatible mt7986_compat = {
- .quirks = &mt7622_i2c_quirks,
- .regs = mt_i2c_regs_v1,
-@@ -516,6 +528,7 @@ static const struct of_device_id mtk_i2c
- { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
- { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
- { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
-+ { .compatible = "mediatek,mt7981-i2c", .data = &mt7981_compat },
- { .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },
- { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },
- { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
+++ /dev/null
-From 3bf827929a44c17bfb1bf1000b143c02ce26a929 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 26 Aug 2023 21:56:51 +0100
-Subject: [PATCH] i2c: mt65xx: allow optional pmic clock
-
-Using the I2C host controller on the MT7981 SoC requires 4 clocks to
-be enabled. One of them, the pmic clk, is only enabled in case
-'mediatek,have-pmic' is also set which has other consequences which
-are not desired in this case.
-
-Allow defining a pmic clk even in case the 'mediatek,have-pmic' propterty
-is not present and the bus is not used to connect to a pmic, but may
-still require to enable the pmic clock.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/i2c/busses/i2c-mt65xx.c | 12 ++++++++----
- 1 file changed, 8 insertions(+), 4 deletions(-)
-
---- a/drivers/i2c/busses/i2c-mt65xx.c
-+++ b/drivers/i2c/busses/i2c-mt65xx.c
-@@ -1444,15 +1444,19 @@ static int mtk_i2c_probe(struct platform
- if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
- return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
-
-+ i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get_optional(&pdev->dev, "pmic");
-+ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
-+ dev_err(&pdev->dev, "cannot get pmic clock\n");
-+ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
-+ }
-+
- if (i2c->have_pmic) {
-- i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
-- if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
-+ if (!i2c->clocks[I2C_MT65XX_CLK_PMIC].clk) {
- dev_err(&pdev->dev, "cannot get pmic clock\n");
-- return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
-+ return -ENODEV;
- }
- speed_clk = I2C_MT65XX_CLK_PMIC;
- } else {
-- i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL;
- speed_clk = I2C_MT65XX_CLK_MAIN;
- }
-
+++ /dev/null
-From d35469096915f2551ed1d26da1ab12ff500fc963 Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Thu, 17 Aug 2023 18:13:33 +0800
-Subject: [PATCH 1/9] ASoC: mediatek: mt7986: add common header
-
-Add header files for register definition and structure.
-
-Signed-off-by: Maso Huang <maso.huang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230817101338.18782-2-maso.huang@mediatek.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- sound/soc/mediatek/mt7986/mt7986-afe-common.h | 49 +++++
- sound/soc/mediatek/mt7986/mt7986-reg.h | 196 ++++++++++++++++++
- 2 files changed, 245 insertions(+)
- create mode 100644 sound/soc/mediatek/mt7986/mt7986-afe-common.h
- create mode 100644 sound/soc/mediatek/mt7986/mt7986-reg.h
-
---- /dev/null
-+++ b/sound/soc/mediatek/mt7986/mt7986-afe-common.h
-@@ -0,0 +1,49 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * mt7986-afe-common.h -- MediaTek 7986 audio driver definitions
-+ *
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Authors: Vic Wu <vic.wu@mediatek.com>
-+ * Maso Huang <maso.huang@mediatek.com>
-+ */
-+
-+#ifndef _MT_7986_AFE_COMMON_H_
-+#define _MT_7986_AFE_COMMON_H_
-+
-+#include <sound/soc.h>
-+#include <linux/clk.h>
-+#include <linux/list.h>
-+#include <linux/regmap.h>
-+#include "../common/mtk-base-afe.h"
-+
-+enum {
-+ MT7986_MEMIF_DL1,
-+ MT7986_MEMIF_VUL12,
-+ MT7986_MEMIF_NUM,
-+ MT7986_DAI_ETDM = MT7986_MEMIF_NUM,
-+ MT7986_DAI_NUM,
-+};
-+
-+enum {
-+ MT7986_IRQ_0,
-+ MT7986_IRQ_1,
-+ MT7986_IRQ_2,
-+ MT7986_IRQ_NUM,
-+};
-+
-+struct mt7986_afe_private {
-+ struct clk_bulk_data *clks;
-+ int num_clks;
-+
-+ int pm_runtime_bypass_reg_ctl;
-+
-+ /* dai */
-+ void *dai_priv[MT7986_DAI_NUM];
-+};
-+
-+unsigned int mt7986_afe_rate_transform(struct device *dev,
-+ unsigned int rate);
-+
-+/* dai register */
-+int mt7986_dai_etdm_register(struct mtk_base_afe *afe);
-+#endif
---- /dev/null
-+++ b/sound/soc/mediatek/mt7986/mt7986-reg.h
-@@ -0,0 +1,196 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * mt7986-reg.h -- MediaTek 7986 audio driver reg definition
-+ *
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Authors: Vic Wu <vic.wu@mediatek.com>
-+ * Maso Huang <maso.huang@mediatek.com>
-+ */
-+
-+#ifndef _MT7986_REG_H_
-+#define _MT7986_REG_H_
-+
-+#define AUDIO_TOP_CON2 0x0008
-+#define AUDIO_TOP_CON4 0x0010
-+#define AUDIO_ENGEN_CON0 0x0014
-+#define AFE_IRQ_MCU_EN 0x0100
-+#define AFE_IRQ_MCU_STATUS 0x0120
-+#define AFE_IRQ_MCU_CLR 0x0128
-+#define AFE_IRQ0_MCU_CFG0 0x0140
-+#define AFE_IRQ0_MCU_CFG1 0x0144
-+#define AFE_IRQ1_MCU_CFG0 0x0148
-+#define AFE_IRQ1_MCU_CFG1 0x014c
-+#define AFE_IRQ2_MCU_CFG0 0x0150
-+#define AFE_IRQ2_MCU_CFG1 0x0154
-+#define ETDM_IN5_CON0 0x13f0
-+#define ETDM_IN5_CON1 0x13f4
-+#define ETDM_IN5_CON2 0x13f8
-+#define ETDM_IN5_CON3 0x13fc
-+#define ETDM_IN5_CON4 0x1400
-+#define ETDM_OUT5_CON0 0x1570
-+#define ETDM_OUT5_CON4 0x1580
-+#define ETDM_OUT5_CON5 0x1584
-+#define ETDM_4_7_COWORK_CON0 0x15e0
-+#define ETDM_4_7_COWORK_CON1 0x15e4
-+#define AFE_CONN018_1 0x1b44
-+#define AFE_CONN018_4 0x1b50
-+#define AFE_CONN019_1 0x1b64
-+#define AFE_CONN019_4 0x1b70
-+#define AFE_CONN124_1 0x2884
-+#define AFE_CONN124_4 0x2890
-+#define AFE_CONN125_1 0x28a4
-+#define AFE_CONN125_4 0x28b0
-+#define AFE_CONN_RS_0 0x3920
-+#define AFE_CONN_RS_3 0x392c
-+#define AFE_CONN_16BIT_0 0x3960
-+#define AFE_CONN_16BIT_3 0x396c
-+#define AFE_CONN_24BIT_0 0x3980
-+#define AFE_CONN_24BIT_3 0x398c
-+#define AFE_MEMIF_CON0 0x3d98
-+#define AFE_MEMIF_RD_MON 0x3da0
-+#define AFE_MEMIF_WR_MON 0x3da4
-+#define AFE_DL0_BASE_MSB 0x3e40
-+#define AFE_DL0_BASE 0x3e44
-+#define AFE_DL0_CUR_MSB 0x3e48
-+#define AFE_DL0_CUR 0x3e4c
-+#define AFE_DL0_END_MSB 0x3e50
-+#define AFE_DL0_END 0x3e54
-+#define AFE_DL0_RCH_MON 0x3e58
-+#define AFE_DL0_LCH_MON 0x3e5c
-+#define AFE_DL0_CON0 0x3e60
-+#define AFE_VUL0_BASE_MSB 0x4220
-+#define AFE_VUL0_BASE 0x4224
-+#define AFE_VUL0_CUR_MSB 0x4228
-+#define AFE_VUL0_CUR 0x422c
-+#define AFE_VUL0_END_MSB 0x4230
-+#define AFE_VUL0_END 0x4234
-+#define AFE_VUL0_CON0 0x4238
-+
-+#define AFE_MAX_REGISTER AFE_VUL0_CON0
-+#define AFE_IRQ_STATUS_BITS 0x7
-+#define AFE_IRQ_CNT_SHIFT 0
-+#define AFE_IRQ_CNT_MASK 0xffffff
-+
-+/* AUDIO_TOP_CON2 */
-+#define CLK_OUT5_PDN BIT(14)
-+#define CLK_OUT5_PDN_MASK BIT(14)
-+#define CLK_IN5_PDN BIT(7)
-+#define CLK_IN5_PDN_MASK BIT(7)
-+
-+/* AUDIO_TOP_CON4 */
-+#define PDN_APLL_TUNER2 BIT(12)
-+#define PDN_APLL_TUNER2_MASK BIT(12)
-+
-+/* AUDIO_ENGEN_CON0 */
-+#define AUD_APLL2_EN BIT(3)
-+#define AUD_APLL2_EN_MASK BIT(3)
-+#define AUD_26M_EN BIT(0)
-+#define AUD_26M_EN_MASK BIT(0)
-+
-+/* AFE_DL0_CON0 */
-+#define DL0_ON_SFT 28
-+#define DL0_ON_MASK 0x1
-+#define DL0_ON_MASK_SFT BIT(28)
-+#define DL0_MINLEN_SFT 20
-+#define DL0_MINLEN_MASK 0xf
-+#define DL0_MINLEN_MASK_SFT (0xf << 20)
-+#define DL0_MODE_SFT 8
-+#define DL0_MODE_MASK 0x1f
-+#define DL0_MODE_MASK_SFT (0x1f << 8)
-+#define DL0_PBUF_SIZE_SFT 5
-+#define DL0_PBUF_SIZE_MASK 0x3
-+#define DL0_PBUF_SIZE_MASK_SFT (0x3 << 5)
-+#define DL0_MONO_SFT 4
-+#define DL0_MONO_MASK 0x1
-+#define DL0_MONO_MASK_SFT BIT(4)
-+#define DL0_HALIGN_SFT 2
-+#define DL0_HALIGN_MASK 0x1
-+#define DL0_HALIGN_MASK_SFT BIT(2)
-+#define DL0_HD_MODE_SFT 0
-+#define DL0_HD_MODE_MASK 0x3
-+#define DL0_HD_MODE_MASK_SFT (0x3 << 0)
-+
-+/* AFE_VUL0_CON0 */
-+#define VUL0_ON_SFT 28
-+#define VUL0_ON_MASK 0x1
-+#define VUL0_ON_MASK_SFT BIT(28)
-+#define VUL0_MODE_SFT 8
-+#define VUL0_MODE_MASK 0x1f
-+#define VUL0_MODE_MASK_SFT (0x1f << 8)
-+#define VUL0_MONO_SFT 4
-+#define VUL0_MONO_MASK 0x1
-+#define VUL0_MONO_MASK_SFT BIT(4)
-+#define VUL0_HALIGN_SFT 2
-+#define VUL0_HALIGN_MASK 0x1
-+#define VUL0_HALIGN_MASK_SFT BIT(2)
-+#define VUL0_HD_MODE_SFT 0
-+#define VUL0_HD_MODE_MASK 0x3
-+#define VUL0_HD_MODE_MASK_SFT (0x3 << 0)
-+
-+/* AFE_IRQ_MCU_CON */
-+#define IRQ_MCU_MODE_SFT 4
-+#define IRQ_MCU_MODE_MASK 0x1f
-+#define IRQ_MCU_MODE_MASK_SFT (0x1f << 4)
-+#define IRQ_MCU_ON_SFT 0
-+#define IRQ_MCU_ON_MASK 0x1
-+#define IRQ_MCU_ON_MASK_SFT BIT(0)
-+#define IRQ0_MCU_CLR_SFT 0
-+#define IRQ0_MCU_CLR_MASK 0x1
-+#define IRQ0_MCU_CLR_MASK_SFT BIT(0)
-+#define IRQ1_MCU_CLR_SFT 1
-+#define IRQ1_MCU_CLR_MASK 0x1
-+#define IRQ1_MCU_CLR_MASK_SFT BIT(1)
-+#define IRQ2_MCU_CLR_SFT 2
-+#define IRQ2_MCU_CLR_MASK 0x1
-+#define IRQ2_MCU_CLR_MASK_SFT BIT(2)
-+
-+/* ETDM_IN5_CON2 */
-+#define IN_CLK_SRC(x) ((x) << 10)
-+#define IN_CLK_SRC_SFT 10
-+#define IN_CLK_SRC_MASK GENMASK(12, 10)
-+
-+/* ETDM_IN5_CON3 */
-+#define IN_SEL_FS(x) ((x) << 26)
-+#define IN_SEL_FS_SFT 26
-+#define IN_SEL_FS_MASK GENMASK(30, 26)
-+
-+/* ETDM_IN5_CON4 */
-+#define IN_RELATCH(x) ((x) << 20)
-+#define IN_RELATCH_SFT 20
-+#define IN_RELATCH_MASK GENMASK(24, 20)
-+#define IN_CLK_INV BIT(18)
-+#define IN_CLK_INV_MASK BIT(18)
-+
-+/* ETDM_IN5_CON0 & ETDM_OUT5_CON0 */
-+#define RELATCH_SRC_MASK GENMASK(30, 28)
-+#define ETDM_CH_NUM_MASK GENMASK(27, 23)
-+#define ETDM_WRD_LEN_MASK GENMASK(20, 16)
-+#define ETDM_BIT_LEN_MASK GENMASK(15, 11)
-+#define ETDM_FMT_MASK GENMASK(8, 6)
-+#define ETDM_SYNC BIT(1)
-+#define ETDM_SYNC_MASK BIT(1)
-+#define ETDM_EN BIT(0)
-+#define ETDM_EN_MASK BIT(0)
-+
-+/* ETDM_OUT5_CON4 */
-+#define OUT_RELATCH(x) ((x) << 24)
-+#define OUT_RELATCH_SFT 24
-+#define OUT_RELATCH_MASK GENMASK(28, 24)
-+#define OUT_CLK_SRC(x) ((x) << 6)
-+#define OUT_CLK_SRC_SFT 6
-+#define OUT_CLK_SRC_MASK GENMASK(8, 6)
-+#define OUT_SEL_FS(x) (x)
-+#define OUT_SEL_FS_SFT 0
-+#define OUT_SEL_FS_MASK GENMASK(4, 0)
-+
-+/* ETDM_OUT5_CON5 */
-+#define ETDM_CLK_DIV BIT(12)
-+#define ETDM_CLK_DIV_MASK BIT(12)
-+#define OUT_CLK_INV BIT(9)
-+#define OUT_CLK_INV_MASK BIT(9)
-+
-+/* ETDM_4_7_COWORK_CON0 */
-+#define OUT_SEL(x) ((x) << 12)
-+#define OUT_SEL_SFT 12
-+#define OUT_SEL_MASK GENMASK(15, 12)
-+#endif
+++ /dev/null
-From 948a288897015fb3ee63b3f720b396b590c17fd7 Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Thu, 17 Aug 2023 18:13:34 +0800
-Subject: [PATCH 2/9] ASoC: mediatek: mt7986: support etdm in platform driver
-
-Add mt7986 etdm dai driver support.
-
-Signed-off-by: Maso Huang <maso.huang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230817101338.18782-3-maso.huang@mediatek.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- sound/soc/mediatek/mt7986/mt7986-dai-etdm.c | 411 ++++++++++++++++++++
- 1 file changed, 411 insertions(+)
- create mode 100644 sound/soc/mediatek/mt7986/mt7986-dai-etdm.c
-
---- /dev/null
-+++ b/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c
-@@ -0,0 +1,411 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * MediaTek ALSA SoC Audio DAI eTDM Control
-+ *
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Authors: Vic Wu <vic.wu@mediatek.com>
-+ * Maso Huang <maso.huang@mediatek.com>
-+ */
-+
-+#include <linux/bitfield.h>
-+#include <linux/bitops.h>
-+#include <linux/regmap.h>
-+#include <sound/pcm_params.h>
-+#include "mt7986-afe-common.h"
-+#include "mt7986-reg.h"
-+
-+#define HOPPING_CLK 0
-+#define APLL_CLK 1
-+#define MTK_DAI_ETDM_FORMAT_I2S 0
-+#define MTK_DAI_ETDM_FORMAT_DSPA 4
-+#define MTK_DAI_ETDM_FORMAT_DSPB 5
-+
-+enum {
-+ MTK_ETDM_RATE_8K = 0,
-+ MTK_ETDM_RATE_12K = 1,
-+ MTK_ETDM_RATE_16K = 2,
-+ MTK_ETDM_RATE_24K = 3,
-+ MTK_ETDM_RATE_32K = 4,
-+ MTK_ETDM_RATE_48K = 5,
-+ MTK_ETDM_RATE_96K = 7,
-+ MTK_ETDM_RATE_192K = 9,
-+ MTK_ETDM_RATE_11K = 16,
-+ MTK_ETDM_RATE_22K = 17,
-+ MTK_ETDM_RATE_44K = 18,
-+ MTK_ETDM_RATE_88K = 19,
-+ MTK_ETDM_RATE_176K = 20,
-+};
-+
-+struct mtk_dai_etdm_priv {
-+ bool bck_inv;
-+ bool lrck_inv;
-+ bool slave_mode;
-+ unsigned int format;
-+};
-+
-+static unsigned int mt7986_etdm_rate_transform(struct device *dev, unsigned int rate)
-+{
-+ switch (rate) {
-+ case 8000:
-+ return MTK_ETDM_RATE_8K;
-+ case 11025:
-+ return MTK_ETDM_RATE_11K;
-+ case 12000:
-+ return MTK_ETDM_RATE_12K;
-+ case 16000:
-+ return MTK_ETDM_RATE_16K;
-+ case 22050:
-+ return MTK_ETDM_RATE_22K;
-+ case 24000:
-+ return MTK_ETDM_RATE_24K;
-+ case 32000:
-+ return MTK_ETDM_RATE_32K;
-+ case 44100:
-+ return MTK_ETDM_RATE_44K;
-+ case 48000:
-+ return MTK_ETDM_RATE_48K;
-+ case 88200:
-+ return MTK_ETDM_RATE_88K;
-+ case 96000:
-+ return MTK_ETDM_RATE_96K;
-+ case 176400:
-+ return MTK_ETDM_RATE_176K;
-+ case 192000:
-+ return MTK_ETDM_RATE_192K;
-+ default:
-+ dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n",
-+ __func__, rate, MTK_ETDM_RATE_48K);
-+ return MTK_ETDM_RATE_48K;
-+ }
-+}
-+
-+static int get_etdm_wlen(unsigned int bitwidth)
-+{
-+ return bitwidth <= 16 ? 16 : 32;
-+}
-+
-+/* dai component */
-+/* interconnection */
-+
-+static const struct snd_kcontrol_new o124_mix[] = {
-+ SOC_DAPM_SINGLE_AUTODISABLE("I032_Switch", AFE_CONN124_1, 0, 1, 0),
-+};
-+
-+static const struct snd_kcontrol_new o125_mix[] = {
-+ SOC_DAPM_SINGLE_AUTODISABLE("I033_Switch", AFE_CONN125_1, 1, 1, 0),
-+};
-+
-+static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
-+
-+ /* DL */
-+ SND_SOC_DAPM_MIXER("I150", SND_SOC_NOPM, 0, 0, NULL, 0),
-+ SND_SOC_DAPM_MIXER("I151", SND_SOC_NOPM, 0, 0, NULL, 0),
-+ /* UL */
-+ SND_SOC_DAPM_MIXER("O124", SND_SOC_NOPM, 0, 0, o124_mix, ARRAY_SIZE(o124_mix)),
-+ SND_SOC_DAPM_MIXER("O125", SND_SOC_NOPM, 0, 0, o125_mix, ARRAY_SIZE(o125_mix)),
-+};
-+
-+static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
-+ {"I150", NULL, "ETDM Capture"},
-+ {"I151", NULL, "ETDM Capture"},
-+ {"ETDM Playback", NULL, "O124"},
-+ {"ETDM Playback", NULL, "O125"},
-+ {"O124", "I032_Switch", "I032"},
-+ {"O125", "I033_Switch", "I033"},
-+};
-+
-+/* dai ops */
-+static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *dai)
-+{
-+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-+ struct mt7986_afe_private *afe_priv = afe->platform_priv;
-+ int ret;
-+
-+ ret = clk_bulk_prepare_enable(afe_priv->num_clks, afe_priv->clks);
-+ if (ret)
-+ return dev_err_probe(afe->dev, ret, "Failed to enable clocks\n");
-+
-+ regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_OUT5_PDN_MASK, 0);
-+ regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_IN5_PDN_MASK, 0);
-+
-+ return 0;
-+}
-+
-+static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *dai)
-+{
-+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-+ struct mt7986_afe_private *afe_priv = afe->platform_priv;
-+
-+ regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_OUT5_PDN_MASK,
-+ CLK_OUT5_PDN);
-+ regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_IN5_PDN_MASK,
-+ CLK_IN5_PDN);
-+
-+ clk_bulk_disable_unprepare(afe_priv->num_clks, afe_priv->clks);
-+}
-+
-+static unsigned int get_etdm_ch_fixup(unsigned int channels)
-+{
-+ if (channels > 16)
-+ return 24;
-+ else if (channels > 8)
-+ return 16;
-+ else if (channels > 4)
-+ return 8;
-+ else if (channels > 2)
-+ return 4;
-+ else
-+ return 2;
-+}
-+
-+static int mtk_dai_etdm_config(struct mtk_base_afe *afe,
-+ struct snd_pcm_hw_params *params,
-+ struct snd_soc_dai *dai,
-+ int stream)
-+{
-+ struct mt7986_afe_private *afe_priv = afe->platform_priv;
-+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
-+ unsigned int rate = params_rate(params);
-+ unsigned int etdm_rate = mt7986_etdm_rate_transform(afe->dev, rate);
-+ unsigned int afe_rate = mt7986_afe_rate_transform(afe->dev, rate);
-+ unsigned int channels = params_channels(params);
-+ unsigned int bit_width = params_width(params);
-+ unsigned int wlen = get_etdm_wlen(bit_width);
-+ unsigned int val = 0;
-+ unsigned int mask = 0;
-+
-+ dev_dbg(afe->dev, "%s(), stream %d, rate %u, bitwidth %u\n",
-+ __func__, stream, rate, bit_width);
-+
-+ /* CON0 */
-+ mask |= ETDM_BIT_LEN_MASK;
-+ val |= FIELD_PREP(ETDM_BIT_LEN_MASK, bit_width - 1);
-+ mask |= ETDM_WRD_LEN_MASK;
-+ val |= FIELD_PREP(ETDM_WRD_LEN_MASK, wlen - 1);
-+ mask |= ETDM_FMT_MASK;
-+ val |= FIELD_PREP(ETDM_FMT_MASK, etdm_data->format);
-+ mask |= ETDM_CH_NUM_MASK;
-+ val |= FIELD_PREP(ETDM_CH_NUM_MASK, get_etdm_ch_fixup(channels) - 1);
-+ mask |= RELATCH_SRC_MASK;
-+ val |= FIELD_PREP(RELATCH_SRC_MASK, APLL_CLK);
-+
-+ switch (stream) {
-+ case SNDRV_PCM_STREAM_PLAYBACK:
-+ /* set ETDM_OUT5_CON0 */
-+ regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, mask, val);
-+
-+ /* set ETDM_OUT5_CON4 */
-+ regmap_update_bits(afe->regmap, ETDM_OUT5_CON4,
-+ OUT_RELATCH_MASK, OUT_RELATCH(afe_rate));
-+ regmap_update_bits(afe->regmap, ETDM_OUT5_CON4,
-+ OUT_CLK_SRC_MASK, OUT_CLK_SRC(APLL_CLK));
-+ regmap_update_bits(afe->regmap, ETDM_OUT5_CON4,
-+ OUT_SEL_FS_MASK, OUT_SEL_FS(etdm_rate));
-+
-+ /* set ETDM_OUT5_CON5 */
-+ regmap_update_bits(afe->regmap, ETDM_OUT5_CON5,
-+ ETDM_CLK_DIV_MASK, ETDM_CLK_DIV);
-+ break;
-+ case SNDRV_PCM_STREAM_CAPTURE:
-+ /* set ETDM_IN5_CON0 */
-+ regmap_update_bits(afe->regmap, ETDM_IN5_CON0, mask, val);
-+ regmap_update_bits(afe->regmap, ETDM_IN5_CON0,
-+ ETDM_SYNC_MASK, ETDM_SYNC);
-+
-+ /* set ETDM_IN5_CON2 */
-+ regmap_update_bits(afe->regmap, ETDM_IN5_CON2,
-+ IN_CLK_SRC_MASK, IN_CLK_SRC(APLL_CLK));
-+
-+ /* set ETDM_IN5_CON3 */
-+ regmap_update_bits(afe->regmap, ETDM_IN5_CON3,
-+ IN_SEL_FS_MASK, IN_SEL_FS(etdm_rate));
-+
-+ /* set ETDM_IN5_CON4 */
-+ regmap_update_bits(afe->regmap, ETDM_IN5_CON4,
-+ IN_RELATCH_MASK, IN_RELATCH(afe_rate));
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params,
-+ struct snd_soc_dai *dai)
-+{
-+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-+
-+ mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_PLAYBACK);
-+ mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_CAPTURE);
-+
-+ return 0;
-+}
-+
-+static int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int cmd,
-+ struct snd_soc_dai *dai)
-+{
-+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-+
-+ dev_dbg(afe->dev, "%s(), cmd %d, dai id %d\n", __func__, cmd, dai->id);
-+ switch (cmd) {
-+ case SNDRV_PCM_TRIGGER_START:
-+ case SNDRV_PCM_TRIGGER_RESUME:
-+ regmap_update_bits(afe->regmap, ETDM_IN5_CON0, ETDM_EN_MASK,
-+ ETDM_EN);
-+ regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, ETDM_EN_MASK,
-+ ETDM_EN);
-+ break;
-+ case SNDRV_PCM_TRIGGER_STOP:
-+ case SNDRV_PCM_TRIGGER_SUSPEND:
-+ regmap_update_bits(afe->regmap, ETDM_IN5_CON0, ETDM_EN_MASK,
-+ 0);
-+ regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, ETDM_EN_MASK,
-+ 0);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-+{
-+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-+ struct mt7986_afe_private *afe_priv = afe->platform_priv;
-+ struct mtk_dai_etdm_priv *etdm_data;
-+ void *priv_data;
-+
-+ switch (dai->id) {
-+ case MT7986_DAI_ETDM:
-+ break;
-+ default:
-+ dev_warn(afe->dev, "%s(), id %d not support\n",
-+ __func__, dai->id);
-+ return -EINVAL;
-+ }
-+
-+ priv_data = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_etdm_priv),
-+ GFP_KERNEL);
-+ if (!priv_data)
-+ return -ENOMEM;
-+
-+ afe_priv->dai_priv[dai->id] = priv_data;
-+ etdm_data = afe_priv->dai_priv[dai->id];
-+
-+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-+ case SND_SOC_DAIFMT_I2S:
-+ etdm_data->format = MTK_DAI_ETDM_FORMAT_I2S;
-+ break;
-+ case SND_SOC_DAIFMT_DSP_A:
-+ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPA;
-+ break;
-+ case SND_SOC_DAIFMT_DSP_B:
-+ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPB;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
-+ case SND_SOC_DAIFMT_NB_NF:
-+ etdm_data->bck_inv = false;
-+ etdm_data->lrck_inv = false;
-+ break;
-+ case SND_SOC_DAIFMT_NB_IF:
-+ etdm_data->bck_inv = false;
-+ etdm_data->lrck_inv = true;
-+ break;
-+ case SND_SOC_DAIFMT_IB_NF:
-+ etdm_data->bck_inv = true;
-+ etdm_data->lrck_inv = false;
-+ break;
-+ case SND_SOC_DAIFMT_IB_IF:
-+ etdm_data->bck_inv = true;
-+ etdm_data->lrck_inv = true;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-+ case SND_SOC_DAIFMT_CBM_CFM:
-+ etdm_data->slave_mode = true;
-+ break;
-+ case SND_SOC_DAIFMT_CBS_CFS:
-+ etdm_data->slave_mode = false;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct snd_soc_dai_ops mtk_dai_etdm_ops = {
-+ .startup = mtk_dai_etdm_startup,
-+ .shutdown = mtk_dai_etdm_shutdown,
-+ .hw_params = mtk_dai_etdm_hw_params,
-+ .trigger = mtk_dai_etdm_trigger,
-+ .set_fmt = mtk_dai_etdm_set_fmt,
-+};
-+
-+/* dai driver */
-+#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_48000 |\
-+ SNDRV_PCM_RATE_88200 |\
-+ SNDRV_PCM_RATE_96000 |\
-+ SNDRV_PCM_RATE_176400 |\
-+ SNDRV_PCM_RATE_192000)
-+
-+#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
-+ SNDRV_PCM_FMTBIT_S24_LE |\
-+ SNDRV_PCM_FMTBIT_S32_LE)
-+
-+static struct snd_soc_dai_driver mtk_dai_etdm_driver[] = {
-+ {
-+ .name = "ETDM",
-+ .id = MT7986_DAI_ETDM,
-+ .capture = {
-+ .stream_name = "ETDM Capture",
-+ .channels_min = 1,
-+ .channels_max = 2,
-+ .rates = MTK_ETDM_RATES,
-+ .formats = MTK_ETDM_FORMATS,
-+ },
-+ .playback = {
-+ .stream_name = "ETDM Playback",
-+ .channels_min = 1,
-+ .channels_max = 2,
-+ .rates = MTK_ETDM_RATES,
-+ .formats = MTK_ETDM_FORMATS,
-+ },
-+ .ops = &mtk_dai_etdm_ops,
-+ .symmetric_rate = 1,
-+ .symmetric_sample_bits = 1,
-+ },
-+};
-+
-+int mt7986_dai_etdm_register(struct mtk_base_afe *afe)
-+{
-+ struct mtk_base_afe_dai *dai;
-+
-+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
-+ if (!dai)
-+ return -ENOMEM;
-+
-+ list_add(&dai->list, &afe->sub_dais);
-+
-+ dai->dai_drivers = mtk_dai_etdm_driver;
-+ dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_etdm_driver);
-+
-+ dai->dapm_widgets = mtk_dai_etdm_widgets;
-+ dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_etdm_widgets);
-+ dai->dapm_routes = mtk_dai_etdm_routes;
-+ dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_etdm_routes);
-+
-+ return 0;
-+}
+++ /dev/null
-From fc7776dee86bc07d22820a904760a95f49a2f12e Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Thu, 17 Aug 2023 18:13:35 +0800
-Subject: [PATCH 3/9] ASoC: mediatek: mt7986: add platform driver
-
-Add mt7986 platform driver.
-
-Signed-off-by: Maso Huang <maso.huang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230817101338.18782-4-maso.huang@mediatek.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- sound/soc/mediatek/Kconfig | 10 +
- sound/soc/mediatek/Makefile | 1 +
- sound/soc/mediatek/mt7986/Makefile | 8 +
- sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 622 +++++++++++++++++++++
- 4 files changed, 641 insertions(+)
- create mode 100644 sound/soc/mediatek/mt7986/Makefile
- create mode 100644 sound/soc/mediatek/mt7986/mt7986-afe-pcm.c
-
---- a/sound/soc/mediatek/Kconfig
-+++ b/sound/soc/mediatek/Kconfig
-@@ -54,6 +54,16 @@ config SND_SOC_MT6797_MT6351
- Select Y if you have such device.
- If unsure select "N".
-
-+config SND_SOC_MT7986
-+ tristate "ASoC support for Mediatek MT7986 chip"
-+ depends on ARCH_MEDIATEK
-+ select SND_SOC_MEDIATEK
-+ help
-+ This adds ASoC platform driver support for MediaTek MT7986 chip
-+ that can be used with other codecs.
-+ Select Y if you have such device.
-+ If unsure select "N".
-+
- config SND_SOC_MT8173
- tristate "ASoC support for Mediatek MT8173 chip"
- depends on ARCH_MEDIATEK
---- a/sound/soc/mediatek/Makefile
-+++ b/sound/soc/mediatek/Makefile
-@@ -2,6 +2,7 @@
- obj-$(CONFIG_SND_SOC_MEDIATEK) += common/
- obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
- obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
-+obj-$(CONFIG_SND_SOC_MT7986) += mt7986/
- obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
- obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
- obj-$(CONFIG_SND_SOC_MT8186) += mt8186/
---- /dev/null
-+++ b/sound/soc/mediatek/mt7986/Makefile
-@@ -0,0 +1,8 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+# platform driver
-+snd-soc-mt7986-afe-objs := \
-+ mt7986-afe-pcm.o \
-+ mt7986-dai-etdm.o
-+
-+obj-$(CONFIG_SND_SOC_MT7986) += snd-soc-mt7986-afe.o
---- /dev/null
-+++ b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c
-@@ -0,0 +1,622 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * MediaTek ALSA SoC AFE platform driver for MT7986
-+ *
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Authors: Vic Wu <vic.wu@mediatek.com>
-+ * Maso Huang <maso.huang@mediatek.com>
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_address.h>
-+#include <linux/pm_runtime.h>
-+
-+#include "mt7986-afe-common.h"
-+#include "mt7986-reg.h"
-+#include "../common/mtk-afe-platform-driver.h"
-+#include "../common/mtk-afe-fe-dai.h"
-+
-+enum {
-+ MTK_AFE_RATE_8K = 0,
-+ MTK_AFE_RATE_11K = 1,
-+ MTK_AFE_RATE_12K = 2,
-+ MTK_AFE_RATE_16K = 4,
-+ MTK_AFE_RATE_22K = 5,
-+ MTK_AFE_RATE_24K = 6,
-+ MTK_AFE_RATE_32K = 8,
-+ MTK_AFE_RATE_44K = 9,
-+ MTK_AFE_RATE_48K = 10,
-+ MTK_AFE_RATE_88K = 13,
-+ MTK_AFE_RATE_96K = 14,
-+ MTK_AFE_RATE_176K = 17,
-+ MTK_AFE_RATE_192K = 18,
-+};
-+
-+enum {
-+ CLK_INFRA_AUD_BUS_CK = 0,
-+ CLK_INFRA_AUD_26M_CK,
-+ CLK_INFRA_AUD_L_CK,
-+ CLK_INFRA_AUD_AUD_CK,
-+ CLK_INFRA_AUD_EG2_CK,
-+ CLK_NUM
-+};
-+
-+static const char *aud_clks[CLK_NUM] = {
-+ [CLK_INFRA_AUD_BUS_CK] = "aud_bus_ck",
-+ [CLK_INFRA_AUD_26M_CK] = "aud_26m_ck",
-+ [CLK_INFRA_AUD_L_CK] = "aud_l_ck",
-+ [CLK_INFRA_AUD_AUD_CK] = "aud_aud_ck",
-+ [CLK_INFRA_AUD_EG2_CK] = "aud_eg2_ck",
-+};
-+
-+unsigned int mt7986_afe_rate_transform(struct device *dev, unsigned int rate)
-+{
-+ switch (rate) {
-+ case 8000:
-+ return MTK_AFE_RATE_8K;
-+ case 11025:
-+ return MTK_AFE_RATE_11K;
-+ case 12000:
-+ return MTK_AFE_RATE_12K;
-+ case 16000:
-+ return MTK_AFE_RATE_16K;
-+ case 22050:
-+ return MTK_AFE_RATE_22K;
-+ case 24000:
-+ return MTK_AFE_RATE_24K;
-+ case 32000:
-+ return MTK_AFE_RATE_32K;
-+ case 44100:
-+ return MTK_AFE_RATE_44K;
-+ case 48000:
-+ return MTK_AFE_RATE_48K;
-+ case 88200:
-+ return MTK_AFE_RATE_88K;
-+ case 96000:
-+ return MTK_AFE_RATE_96K;
-+ case 176400:
-+ return MTK_AFE_RATE_176K;
-+ case 192000:
-+ return MTK_AFE_RATE_192K;
-+ default:
-+ dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n",
-+ __func__, rate, MTK_AFE_RATE_48K);
-+ return MTK_AFE_RATE_48K;
-+ }
-+}
-+
-+static const struct snd_pcm_hardware mt7986_afe_hardware = {
-+ .info = SNDRV_PCM_INFO_MMAP |
-+ SNDRV_PCM_INFO_INTERLEAVED |
-+ SNDRV_PCM_INFO_MMAP_VALID,
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
-+ SNDRV_PCM_FMTBIT_S24_LE |
-+ SNDRV_PCM_FMTBIT_S32_LE,
-+ .period_bytes_min = 256,
-+ .period_bytes_max = 4 * 48 * 1024,
-+ .periods_min = 2,
-+ .periods_max = 256,
-+ .buffer_bytes_max = 8 * 48 * 1024,
-+ .fifo_size = 0,
-+};
-+
-+static int mt7986_memif_fs(struct snd_pcm_substream *substream,
-+ unsigned int rate)
-+{
-+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
-+ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
-+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
-+
-+ return mt7986_afe_rate_transform(afe->dev, rate);
-+}
-+
-+static int mt7986_irq_fs(struct snd_pcm_substream *substream,
-+ unsigned int rate)
-+{
-+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
-+ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
-+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
-+
-+ return mt7986_afe_rate_transform(afe->dev, rate);
-+}
-+
-+#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000 |\
-+ SNDRV_PCM_RATE_88200 |\
-+ SNDRV_PCM_RATE_96000 |\
-+ SNDRV_PCM_RATE_176400 |\
-+ SNDRV_PCM_RATE_192000)
-+
-+#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
-+ SNDRV_PCM_FMTBIT_S24_LE |\
-+ SNDRV_PCM_FMTBIT_S32_LE)
-+
-+static struct snd_soc_dai_driver mt7986_memif_dai_driver[] = {
-+ /* FE DAIs: memory intefaces to CPU */
-+ {
-+ .name = "DL1",
-+ .id = MT7986_MEMIF_DL1,
-+ .playback = {
-+ .stream_name = "DL1",
-+ .channels_min = 1,
-+ .channels_max = 2,
-+ .rates = MTK_PCM_RATES,
-+ .formats = MTK_PCM_FORMATS,
-+ },
-+ .ops = &mtk_afe_fe_ops,
-+ },
-+ {
-+ .name = "UL1",
-+ .id = MT7986_MEMIF_VUL12,
-+ .capture = {
-+ .stream_name = "UL1",
-+ .channels_min = 1,
-+ .channels_max = 2,
-+ .rates = MTK_PCM_RATES,
-+ .formats = MTK_PCM_FORMATS,
-+ },
-+ .ops = &mtk_afe_fe_ops,
-+ },
-+};
-+
-+static const struct snd_kcontrol_new o018_mix[] = {
-+ SOC_DAPM_SINGLE_AUTODISABLE("I150_Switch", AFE_CONN018_4, 22, 1, 0),
-+};
-+
-+static const struct snd_kcontrol_new o019_mix[] = {
-+ SOC_DAPM_SINGLE_AUTODISABLE("I151_Switch", AFE_CONN019_4, 23, 1, 0),
-+};
-+
-+static const struct snd_soc_dapm_widget mt7986_memif_widgets[] = {
-+ /* DL */
-+ SND_SOC_DAPM_MIXER("I032", SND_SOC_NOPM, 0, 0, NULL, 0),
-+ SND_SOC_DAPM_MIXER("I033", SND_SOC_NOPM, 0, 0, NULL, 0),
-+
-+ /* UL */
-+ SND_SOC_DAPM_MIXER("O018", SND_SOC_NOPM, 0, 0,
-+ o018_mix, ARRAY_SIZE(o018_mix)),
-+ SND_SOC_DAPM_MIXER("O019", SND_SOC_NOPM, 0, 0,
-+ o019_mix, ARRAY_SIZE(o019_mix)),
-+};
-+
-+static const struct snd_soc_dapm_route mt7986_memif_routes[] = {
-+ {"I032", NULL, "DL1"},
-+ {"I033", NULL, "DL1"},
-+ {"UL1", NULL, "O018"},
-+ {"UL1", NULL, "O019"},
-+ {"O018", "I150_Switch", "I150"},
-+ {"O019", "I151_Switch", "I151"},
-+};
-+
-+static const struct snd_soc_component_driver mt7986_afe_pcm_dai_component = {
-+ .name = "mt7986-afe-pcm-dai",
-+};
-+
-+static const struct mtk_base_memif_data memif_data[MT7986_MEMIF_NUM] = {
-+ [MT7986_MEMIF_DL1] = {
-+ .name = "DL1",
-+ .id = MT7986_MEMIF_DL1,
-+ .reg_ofs_base = AFE_DL0_BASE,
-+ .reg_ofs_cur = AFE_DL0_CUR,
-+ .reg_ofs_end = AFE_DL0_END,
-+ .reg_ofs_base_msb = AFE_DL0_BASE_MSB,
-+ .reg_ofs_cur_msb = AFE_DL0_CUR_MSB,
-+ .reg_ofs_end_msb = AFE_DL0_END_MSB,
-+ .fs_reg = AFE_DL0_CON0,
-+ .fs_shift = DL0_MODE_SFT,
-+ .fs_maskbit = DL0_MODE_MASK,
-+ .mono_reg = AFE_DL0_CON0,
-+ .mono_shift = DL0_MONO_SFT,
-+ .enable_reg = AFE_DL0_CON0,
-+ .enable_shift = DL0_ON_SFT,
-+ .hd_reg = AFE_DL0_CON0,
-+ .hd_shift = DL0_HD_MODE_SFT,
-+ .hd_align_reg = AFE_DL0_CON0,
-+ .hd_align_mshift = DL0_HALIGN_SFT,
-+ .pbuf_reg = AFE_DL0_CON0,
-+ .pbuf_shift = DL0_PBUF_SIZE_SFT,
-+ .minlen_reg = AFE_DL0_CON0,
-+ .minlen_shift = DL0_MINLEN_SFT,
-+ },
-+ [MT7986_MEMIF_VUL12] = {
-+ .name = "VUL12",
-+ .id = MT7986_MEMIF_VUL12,
-+ .reg_ofs_base = AFE_VUL0_BASE,
-+ .reg_ofs_cur = AFE_VUL0_CUR,
-+ .reg_ofs_end = AFE_VUL0_END,
-+ .reg_ofs_base_msb = AFE_VUL0_BASE_MSB,
-+ .reg_ofs_cur_msb = AFE_VUL0_CUR_MSB,
-+ .reg_ofs_end_msb = AFE_VUL0_END_MSB,
-+ .fs_reg = AFE_VUL0_CON0,
-+ .fs_shift = VUL0_MODE_SFT,
-+ .fs_maskbit = VUL0_MODE_MASK,
-+ .mono_reg = AFE_VUL0_CON0,
-+ .mono_shift = VUL0_MONO_SFT,
-+ .enable_reg = AFE_VUL0_CON0,
-+ .enable_shift = VUL0_ON_SFT,
-+ .hd_reg = AFE_VUL0_CON0,
-+ .hd_shift = VUL0_HD_MODE_SFT,
-+ .hd_align_reg = AFE_VUL0_CON0,
-+ .hd_align_mshift = VUL0_HALIGN_SFT,
-+ },
-+};
-+
-+static const struct mtk_base_irq_data irq_data[MT7986_IRQ_NUM] = {
-+ [MT7986_IRQ_0] = {
-+ .id = MT7986_IRQ_0,
-+ .irq_cnt_reg = AFE_IRQ0_MCU_CFG1,
-+ .irq_cnt_shift = AFE_IRQ_CNT_SHIFT,
-+ .irq_cnt_maskbit = AFE_IRQ_CNT_MASK,
-+ .irq_fs_reg = AFE_IRQ0_MCU_CFG0,
-+ .irq_fs_shift = IRQ_MCU_MODE_SFT,
-+ .irq_fs_maskbit = IRQ_MCU_MODE_MASK,
-+ .irq_en_reg = AFE_IRQ0_MCU_CFG0,
-+ .irq_en_shift = IRQ_MCU_ON_SFT,
-+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
-+ .irq_clr_shift = IRQ0_MCU_CLR_SFT,
-+ },
-+ [MT7986_IRQ_1] = {
-+ .id = MT7986_IRQ_1,
-+ .irq_cnt_reg = AFE_IRQ1_MCU_CFG1,
-+ .irq_cnt_shift = AFE_IRQ_CNT_SHIFT,
-+ .irq_cnt_maskbit = AFE_IRQ_CNT_MASK,
-+ .irq_fs_reg = AFE_IRQ1_MCU_CFG0,
-+ .irq_fs_shift = IRQ_MCU_MODE_SFT,
-+ .irq_fs_maskbit = IRQ_MCU_MODE_MASK,
-+ .irq_en_reg = AFE_IRQ1_MCU_CFG0,
-+ .irq_en_shift = IRQ_MCU_ON_SFT,
-+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
-+ .irq_clr_shift = IRQ1_MCU_CLR_SFT,
-+ },
-+ [MT7986_IRQ_2] = {
-+ .id = MT7986_IRQ_2,
-+ .irq_cnt_reg = AFE_IRQ2_MCU_CFG1,
-+ .irq_cnt_shift = AFE_IRQ_CNT_SHIFT,
-+ .irq_cnt_maskbit = AFE_IRQ_CNT_MASK,
-+ .irq_fs_reg = AFE_IRQ2_MCU_CFG0,
-+ .irq_fs_shift = IRQ_MCU_MODE_SFT,
-+ .irq_fs_maskbit = IRQ_MCU_MODE_MASK,
-+ .irq_en_reg = AFE_IRQ2_MCU_CFG0,
-+ .irq_en_shift = IRQ_MCU_ON_SFT,
-+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
-+ .irq_clr_shift = IRQ2_MCU_CLR_SFT,
-+ },
-+};
-+
-+static bool mt7986_is_volatile_reg(struct device *dev, unsigned int reg)
-+{
-+ /*
-+ * Those auto-gen regs are read-only, so put it as volatile because
-+ * volatile registers cannot be cached, which means that they cannot
-+ * be set when power is off
-+ */
-+
-+ switch (reg) {
-+ case AFE_DL0_CUR_MSB:
-+ case AFE_DL0_CUR:
-+ case AFE_DL0_RCH_MON:
-+ case AFE_DL0_LCH_MON:
-+ case AFE_VUL0_CUR_MSB:
-+ case AFE_VUL0_CUR:
-+ case AFE_IRQ_MCU_STATUS:
-+ case AFE_MEMIF_RD_MON:
-+ case AFE_MEMIF_WR_MON:
-+ return true;
-+ default:
-+ return false;
-+ };
-+}
-+
-+static const struct regmap_config mt7986_afe_regmap_config = {
-+ .reg_bits = 32,
-+ .reg_stride = 4,
-+ .val_bits = 32,
-+ .volatile_reg = mt7986_is_volatile_reg,
-+ .max_register = AFE_MAX_REGISTER,
-+ .num_reg_defaults_raw = ((AFE_MAX_REGISTER / 4) + 1),
-+};
-+
-+static int mt7986_init_clock(struct mtk_base_afe *afe)
-+{
-+ struct mt7986_afe_private *afe_priv = afe->platform_priv;
-+ int ret, i;
-+
-+ afe_priv->clks = devm_kcalloc(afe->dev, CLK_NUM,
-+ sizeof(*afe_priv->clks), GFP_KERNEL);
-+ if (!afe_priv->clks)
-+ return -ENOMEM;
-+ afe_priv->num_clks = CLK_NUM;
-+
-+ for (i = 0; i < afe_priv->num_clks; i++)
-+ afe_priv->clks[i].id = aud_clks[i];
-+
-+ ret = devm_clk_bulk_get(afe->dev, afe_priv->num_clks, afe_priv->clks);
-+ if (ret)
-+ return dev_err_probe(afe->dev, ret, "Failed to get clocks\n");
-+
-+ return 0;
-+}
-+
-+static irqreturn_t mt7986_afe_irq_handler(int irq_id, void *dev)
-+{
-+ struct mtk_base_afe *afe = dev;
-+ struct mtk_base_afe_irq *irq;
-+ u32 mcu_en, status, status_mcu;
-+ int i, ret;
-+ irqreturn_t irq_ret = IRQ_HANDLED;
-+
-+ /* get irq that is sent to MCU */
-+ regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en);
-+
-+ ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status);
-+ /* only care IRQ which is sent to MCU */
-+ status_mcu = status & mcu_en & AFE_IRQ_STATUS_BITS;
-+
-+ if (ret || status_mcu == 0) {
-+ dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, mcu_en 0x%x\n",
-+ __func__, ret, status, mcu_en);
-+
-+ irq_ret = IRQ_NONE;
-+ goto err_irq;
-+ }
-+
-+ for (i = 0; i < MT7986_MEMIF_NUM; i++) {
-+ struct mtk_base_afe_memif *memif = &afe->memif[i];
-+
-+ if (!memif->substream)
-+ continue;
-+
-+ if (memif->irq_usage < 0)
-+ continue;
-+
-+ irq = &afe->irqs[memif->irq_usage];
-+
-+ if (status_mcu & (1 << irq->irq_data->irq_en_shift))
-+ snd_pcm_period_elapsed(memif->substream);
-+ }
-+
-+err_irq:
-+ /* clear irq */
-+ regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, status_mcu);
-+
-+ return irq_ret;
-+}
-+
-+static int mt7986_afe_runtime_suspend(struct device *dev)
-+{
-+ struct mtk_base_afe *afe = dev_get_drvdata(dev);
-+ struct mt7986_afe_private *afe_priv = afe->platform_priv;
-+
-+ if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
-+ goto skip_regmap;
-+
-+ /* disable clk*/
-+ regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0x3fff);
-+ regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK, 0);
-+ regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK, 0);
-+
-+ /* make sure all irq status are cleared, twice intended */
-+ regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CLR, 0xffff, 0xffff);
-+
-+skip_regmap:
-+ clk_bulk_disable_unprepare(afe_priv->num_clks, afe_priv->clks);
-+
-+ return 0;
-+}
-+
-+static int mt7986_afe_runtime_resume(struct device *dev)
-+{
-+ struct mtk_base_afe *afe = dev_get_drvdata(dev);
-+ struct mt7986_afe_private *afe_priv = afe->platform_priv;
-+ int ret;
-+
-+ ret = clk_bulk_prepare_enable(afe_priv->num_clks, afe_priv->clks);
-+ if (ret)
-+ return dev_err_probe(afe->dev, ret, "Failed to enable clocks\n");
-+
-+ if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
-+ return 0;
-+
-+ /* enable clk*/
-+ regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0);
-+ regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK,
-+ AUD_APLL2_EN);
-+ regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK,
-+ AUD_26M_EN);
-+
-+ return 0;
-+}
-+
-+static int mt7986_afe_component_probe(struct snd_soc_component *component)
-+{
-+ return mtk_afe_add_sub_dai_control(component);
-+}
-+
-+static const struct snd_soc_component_driver mt7986_afe_component = {
-+ .name = AFE_PCM_NAME,
-+ .probe = mt7986_afe_component_probe,
-+ .pointer = mtk_afe_pcm_pointer,
-+ .pcm_construct = mtk_afe_pcm_new,
-+};
-+
-+static int mt7986_dai_memif_register(struct mtk_base_afe *afe)
-+{
-+ struct mtk_base_afe_dai *dai;
-+
-+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
-+ if (!dai)
-+ return -ENOMEM;
-+
-+ list_add(&dai->list, &afe->sub_dais);
-+
-+ dai->dai_drivers = mt7986_memif_dai_driver;
-+ dai->num_dai_drivers = ARRAY_SIZE(mt7986_memif_dai_driver);
-+
-+ dai->dapm_widgets = mt7986_memif_widgets;
-+ dai->num_dapm_widgets = ARRAY_SIZE(mt7986_memif_widgets);
-+ dai->dapm_routes = mt7986_memif_routes;
-+ dai->num_dapm_routes = ARRAY_SIZE(mt7986_memif_routes);
-+
-+ return 0;
-+}
-+
-+typedef int (*dai_register_cb)(struct mtk_base_afe *);
-+static const dai_register_cb dai_register_cbs[] = {
-+ mt7986_dai_etdm_register,
-+ mt7986_dai_memif_register,
-+};
-+
-+static int mt7986_afe_pcm_dev_probe(struct platform_device *pdev)
-+{
-+ struct mtk_base_afe *afe;
-+ struct mt7986_afe_private *afe_priv;
-+ struct device *dev;
-+ int i, irq_id, ret;
-+
-+ afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
-+ if (!afe)
-+ return -ENOMEM;
-+ platform_set_drvdata(pdev, afe);
-+
-+ afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
-+ GFP_KERNEL);
-+ if (!afe->platform_priv)
-+ return -ENOMEM;
-+
-+ afe_priv = afe->platform_priv;
-+ afe->dev = &pdev->dev;
-+ dev = afe->dev;
-+
-+ afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(afe->base_addr))
-+ return PTR_ERR(afe->base_addr);
-+
-+ /* initial audio related clock */
-+ ret = mt7986_init_clock(afe);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Cannot initialize clocks\n");
-+
-+ ret = devm_pm_runtime_enable(dev);
-+ if (ret)
-+ return ret;
-+
-+ /* enable clock for regcache get default value from hw */
-+ afe_priv->pm_runtime_bypass_reg_ctl = true;
-+ pm_runtime_get_sync(&pdev->dev);
-+
-+ afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
-+ &mt7986_afe_regmap_config);
-+
-+ pm_runtime_put_sync(&pdev->dev);
-+ if (IS_ERR(afe->regmap))
-+ return PTR_ERR(afe->regmap);
-+
-+ afe_priv->pm_runtime_bypass_reg_ctl = false;
-+
-+ /* init memif */
-+ afe->memif_size = MT7986_MEMIF_NUM;
-+ afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
-+ GFP_KERNEL);
-+ if (!afe->memif)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < afe->memif_size; i++) {
-+ afe->memif[i].data = &memif_data[i];
-+ afe->memif[i].irq_usage = -1;
-+ }
-+
-+ mutex_init(&afe->irq_alloc_lock);
-+
-+ /* irq initialize */
-+ afe->irqs_size = MT7986_IRQ_NUM;
-+ afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
-+ GFP_KERNEL);
-+ if (!afe->irqs)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < afe->irqs_size; i++)
-+ afe->irqs[i].irq_data = &irq_data[i];
-+
-+ /* request irq */
-+ irq_id = platform_get_irq(pdev, 0);
-+ if (irq_id < 0) {
-+ ret = irq_id;
-+ return dev_err_probe(dev, ret, "No irq found\n");
-+ }
-+ ret = devm_request_irq(dev, irq_id, mt7986_afe_irq_handler,
-+ IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Failed to request irq for asys-isr\n");
-+
-+ /* init sub_dais */
-+ INIT_LIST_HEAD(&afe->sub_dais);
-+
-+ for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {
-+ ret = dai_register_cbs[i](afe);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "DAI register failed, i: %d\n", i);
-+ }
-+
-+ /* init dai_driver and component_driver */
-+ ret = mtk_afe_combine_sub_dai(afe);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "mtk_afe_combine_sub_dai fail\n");
-+
-+ afe->mtk_afe_hardware = &mt7986_afe_hardware;
-+ afe->memif_fs = mt7986_memif_fs;
-+ afe->irq_fs = mt7986_irq_fs;
-+
-+ afe->runtime_resume = mt7986_afe_runtime_resume;
-+ afe->runtime_suspend = mt7986_afe_runtime_suspend;
-+
-+ /* register component */
-+ ret = devm_snd_soc_register_component(&pdev->dev,
-+ &mt7986_afe_component,
-+ NULL, 0);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Cannot register AFE component\n");
-+
-+ ret = devm_snd_soc_register_component(afe->dev,
-+ &mt7986_afe_pcm_dai_component,
-+ afe->dai_drivers,
-+ afe->num_dai_drivers);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Cannot register PCM DAI component\n");
-+
-+ return 0;
-+}
-+
-+static void mt7986_afe_pcm_dev_remove(struct platform_device *pdev)
-+{
-+ pm_runtime_disable(&pdev->dev);
-+ if (!pm_runtime_status_suspended(&pdev->dev))
-+ mt7986_afe_runtime_suspend(&pdev->dev);
-+}
-+
-+static const struct of_device_id mt7986_afe_pcm_dt_match[] = {
-+ { .compatible = "mediatek,mt7986-afe" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, mt7986_afe_pcm_dt_match);
-+
-+static const struct dev_pm_ops mt7986_afe_pm_ops = {
-+ SET_RUNTIME_PM_OPS(mt7986_afe_runtime_suspend,
-+ mt7986_afe_runtime_resume, NULL)
-+};
-+
-+static struct platform_driver mt7986_afe_pcm_driver = {
-+ .driver = {
-+ .name = "mt7986-audio",
-+ .of_match_table = mt7986_afe_pcm_dt_match,
-+ .pm = &mt7986_afe_pm_ops,
-+ },
-+ .probe = mt7986_afe_pcm_dev_probe,
-+ .remove_new = mt7986_afe_pcm_dev_remove,
-+};
-+module_platform_driver(mt7986_afe_pcm_driver);
-+
-+MODULE_DESCRIPTION("MediaTek SoC AFE platform driver for ALSA MT7986");
-+MODULE_AUTHOR("Vic Wu <vic.wu@mediatek.com>");
-+MODULE_LICENSE("GPL");
+++ /dev/null
-From ddf6abc1c78072f8ccad59166be95f0ca5af8ca4 Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Thu, 17 Aug 2023 18:13:36 +0800
-Subject: [PATCH 4/9] ASoC: mediatek: mt7986: add machine driver with wm8960
-
-Add support for mt7986 board with wm8960.
-
-Signed-off-by: Maso Huang <maso.huang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230817101338.18782-5-maso.huang@mediatek.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- sound/soc/mediatek/Kconfig | 10 ++
- sound/soc/mediatek/mt7986/Makefile | 1 +
- sound/soc/mediatek/mt7986/mt7986-wm8960.c | 196 ++++++++++++++++++++++
- 3 files changed, 207 insertions(+)
- create mode 100644 sound/soc/mediatek/mt7986/mt7986-wm8960.c
-
---- a/sound/soc/mediatek/Kconfig
-+++ b/sound/soc/mediatek/Kconfig
-@@ -64,6 +64,16 @@ config SND_SOC_MT7986
- Select Y if you have such device.
- If unsure select "N".
-
-+config SND_SOC_MT7986_WM8960
-+ tristate "ASoc Audio driver for MT7986 with WM8960 codec"
-+ depends on SND_SOC_MT7986 && I2C
-+ select SND_SOC_WM8960
-+ help
-+ This adds support for ASoC machine driver for MediaTek MT7986
-+ boards with the WM8960 codecs.
-+ Select Y if you have such device.
-+ If unsure select "N".
-+
- config SND_SOC_MT8173
- tristate "ASoC support for Mediatek MT8173 chip"
- depends on ARCH_MEDIATEK
---- a/sound/soc/mediatek/mt7986/Makefile
-+++ b/sound/soc/mediatek/mt7986/Makefile
-@@ -6,3 +6,4 @@ snd-soc-mt7986-afe-objs := \
- mt7986-dai-etdm.o
-
- obj-$(CONFIG_SND_SOC_MT7986) += snd-soc-mt7986-afe.o
-+obj-$(CONFIG_SND_SOC_MT7986_WM8960) += mt7986-wm8960.o
---- /dev/null
-+++ b/sound/soc/mediatek/mt7986/mt7986-wm8960.c
-@@ -0,0 +1,196 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * mt7986-wm8960.c -- MT7986-WM8960 ALSA SoC machine driver
-+ *
-+ * Copyright (c) 2023 MediaTek Inc.
-+ * Authors: Vic Wu <vic.wu@mediatek.com>
-+ * Maso Huang <maso.huang@mediatek.com>
-+ */
-+
-+#include <linux/module.h>
-+#include <sound/soc.h>
-+
-+#include "mt7986-afe-common.h"
-+
-+struct mt7986_wm8960_priv {
-+ struct device_node *platform_node;
-+ struct device_node *codec_node;
-+};
-+
-+static const struct snd_soc_dapm_widget mt7986_wm8960_widgets[] = {
-+ SND_SOC_DAPM_HP("Headphone", NULL),
-+ SND_SOC_DAPM_MIC("AMIC", NULL),
-+};
-+
-+static const struct snd_kcontrol_new mt7986_wm8960_controls[] = {
-+ SOC_DAPM_PIN_SWITCH("Headphone"),
-+ SOC_DAPM_PIN_SWITCH("AMIC"),
-+};
-+
-+SND_SOC_DAILINK_DEFS(playback,
-+ DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
-+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
-+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
-+
-+SND_SOC_DAILINK_DEFS(capture,
-+ DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
-+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
-+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
-+
-+SND_SOC_DAILINK_DEFS(codec,
-+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM")),
-+ DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8960-hifi")),
-+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
-+
-+static struct snd_soc_dai_link mt7986_wm8960_dai_links[] = {
-+ /* FE */
-+ {
-+ .name = "wm8960-playback",
-+ .stream_name = "wm8960-playback",
-+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
-+ SND_SOC_DPCM_TRIGGER_POST},
-+ .dynamic = 1,
-+ .dpcm_playback = 1,
-+ SND_SOC_DAILINK_REG(playback),
-+ },
-+ {
-+ .name = "wm8960-capture",
-+ .stream_name = "wm8960-capture",
-+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
-+ SND_SOC_DPCM_TRIGGER_POST},
-+ .dynamic = 1,
-+ .dpcm_capture = 1,
-+ SND_SOC_DAILINK_REG(capture),
-+ },
-+ /* BE */
-+ {
-+ .name = "wm8960-codec",
-+ .no_pcm = 1,
-+ .dai_fmt = SND_SOC_DAIFMT_I2S |
-+ SND_SOC_DAIFMT_NB_NF |
-+ SND_SOC_DAIFMT_CBS_CFS |
-+ SND_SOC_DAIFMT_GATED,
-+ .dpcm_playback = 1,
-+ .dpcm_capture = 1,
-+ SND_SOC_DAILINK_REG(codec),
-+ },
-+};
-+
-+static struct snd_soc_card mt7986_wm8960_card = {
-+ .name = "mt7986-wm8960",
-+ .owner = THIS_MODULE,
-+ .dai_link = mt7986_wm8960_dai_links,
-+ .num_links = ARRAY_SIZE(mt7986_wm8960_dai_links),
-+ .controls = mt7986_wm8960_controls,
-+ .num_controls = ARRAY_SIZE(mt7986_wm8960_controls),
-+ .dapm_widgets = mt7986_wm8960_widgets,
-+ .num_dapm_widgets = ARRAY_SIZE(mt7986_wm8960_widgets),
-+};
-+
-+static int mt7986_wm8960_machine_probe(struct platform_device *pdev)
-+{
-+ struct snd_soc_card *card = &mt7986_wm8960_card;
-+ struct snd_soc_dai_link *dai_link;
-+ struct device_node *platform, *codec;
-+ struct mt7986_wm8960_priv *priv;
-+ int ret, i;
-+
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ platform = of_get_child_by_name(pdev->dev.of_node, "platform");
-+
-+ if (platform) {
-+ priv->platform_node = of_parse_phandle(platform, "sound-dai", 0);
-+ of_node_put(platform);
-+
-+ if (!priv->platform_node) {
-+ dev_err(&pdev->dev, "Failed to parse platform/sound-dai property\n");
-+ return -EINVAL;
-+ }
-+ } else {
-+ dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
-+ return -EINVAL;
-+ }
-+
-+ for_each_card_prelinks(card, i, dai_link) {
-+ if (dai_link->platforms->name)
-+ continue;
-+ dai_link->platforms->of_node = priv->platform_node;
-+ }
-+
-+ card->dev = &pdev->dev;
-+
-+ codec = of_get_child_by_name(pdev->dev.of_node, "codec");
-+
-+ if (codec) {
-+ priv->codec_node = of_parse_phandle(codec, "sound-dai", 0);
-+ of_node_put(codec);
-+
-+ if (!priv->codec_node) {
-+ of_node_put(priv->platform_node);
-+ dev_err(&pdev->dev, "Failed to parse codec/sound-dai property\n");
-+ return -EINVAL;
-+ }
-+ } else {
-+ of_node_put(priv->platform_node);
-+ dev_err(&pdev->dev, "Property 'codec' missing or invalid\n");
-+ return -EINVAL;
-+ }
-+
-+ for_each_card_prelinks(card, i, dai_link) {
-+ if (dai_link->codecs->name)
-+ continue;
-+ dai_link->codecs->of_node = priv->codec_node;
-+ }
-+
-+ ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to parse audio-routing: %d\n", ret);
-+ goto err_of_node_put;
-+ }
-+
-+ ret = devm_snd_soc_register_card(&pdev->dev, card);
-+ if (ret) {
-+ dev_err(&pdev->dev, "%s snd_soc_register_card fail: %d\n", __func__, ret);
-+ goto err_of_node_put;
-+ }
-+
-+err_of_node_put:
-+ of_node_put(priv->codec_node);
-+ of_node_put(priv->platform_node);
-+ return ret;
-+}
-+
-+static void mt7986_wm8960_machine_remove(struct platform_device *pdev)
-+{
-+ struct snd_soc_card *card = platform_get_drvdata(pdev);
-+ struct mt7986_wm8960_priv *priv = snd_soc_card_get_drvdata(card);
-+
-+ of_node_put(priv->codec_node);
-+ of_node_put(priv->platform_node);
-+}
-+
-+static const struct of_device_id mt7986_wm8960_machine_dt_match[] = {
-+ {.compatible = "mediatek,mt7986-wm8960-sound"},
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, mt7986_wm8960_machine_dt_match);
-+
-+static struct platform_driver mt7986_wm8960_machine = {
-+ .driver = {
-+ .name = "mt7986-wm8960",
-+ .of_match_table = mt7986_wm8960_machine_dt_match,
-+ },
-+ .probe = mt7986_wm8960_machine_probe,
-+ .remove_new = mt7986_wm8960_machine_remove,
-+};
-+
-+module_platform_driver(mt7986_wm8960_machine);
-+
-+/* Module information */
-+MODULE_DESCRIPTION("MT7986 WM8960 ALSA SoC machine driver");
-+MODULE_AUTHOR("Vic Wu <vic.wu@mediatek.com>");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("mt7986 wm8960 soc card");
+++ /dev/null
-From 72469f950b629e57e60fbcbefed45e083619b986 Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Thu, 17 Aug 2023 18:13:37 +0800
-Subject: [PATCH 5/9] ASoC: dt-bindings: mediatek,mt7986-wm8960: add
- mt7986-wm8960 document
-
-Add document for mt7986 board with wm8960.
-
-Signed-off-by: Maso Huang <maso.huang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230817101338.18782-6-maso.huang@mediatek.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- .../sound/mediatek,mt7986-wm8960.yaml | 67 +++++++++++++++++++
- 1 file changed, 67 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt7986-wm8960.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/sound/mediatek,mt7986-wm8960.yaml
-@@ -0,0 +1,67 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/sound/mediatek,mt7986-wm8960.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MediaTek MT7986 sound card with WM8960 codec
-+
-+maintainers:
-+ - Maso Huang <maso.huang@mediatek.com>
-+
-+allOf:
-+ - $ref: sound-card-common.yaml#
-+
-+properties:
-+ compatible:
-+ const: mediatek,mt7986-wm8960-sound
-+
-+ platform:
-+ type: object
-+ additionalProperties: false
-+ properties:
-+ sound-dai:
-+ description: The phandle of MT7986 platform.
-+ maxItems: 1
-+ required:
-+ - sound-dai
-+
-+ codec:
-+ type: object
-+ additionalProperties: false
-+ properties:
-+ sound-dai:
-+ description: The phandle of wm8960 codec.
-+ maxItems: 1
-+ required:
-+ - sound-dai
-+
-+unevaluatedProperties: false
-+
-+required:
-+ - compatible
-+ - audio-routing
-+ - platform
-+ - codec
-+
-+examples:
-+ - |
-+ sound {
-+ compatible = "mediatek,mt7986-wm8960-sound";
-+ model = "mt7986-wm8960";
-+ audio-routing =
-+ "Headphone", "HP_L",
-+ "Headphone", "HP_R",
-+ "LINPUT1", "AMIC",
-+ "RINPUT1", "AMIC";
-+
-+ platform {
-+ sound-dai = <&afe>;
-+ };
-+
-+ codec {
-+ sound-dai = <&wm8960>;
-+ };
-+ };
-+
-+...
+++ /dev/null
-From d16202eb38585adbc16e32d11188dbc2127015de Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Thu, 17 Aug 2023 18:13:38 +0800
-Subject: [PATCH 6/9] ASoC: dt-bindings: mediatek,mt7986-afe: add audio afe
- document
-
-Add mt7986 audio afe document.
-
-Signed-off-by: Maso Huang <maso.huang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20230817101338.18782-7-maso.huang@mediatek.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- .../bindings/sound/mediatek,mt7986-afe.yaml | 160 ++++++++++++++++++
- 1 file changed, 160 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt7986-afe.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/sound/mediatek,mt7986-afe.yaml
-@@ -0,0 +1,160 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/sound/mediatek,mt7986-afe.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MediaTek AFE PCM controller for MT7986
-+
-+maintainers:
-+ - Maso Huang <maso.huang@mediatek.com>
-+
-+properties:
-+ compatible:
-+ oneOf:
-+ - const: mediatek,mt7986-afe
-+ - items:
-+ - enum:
-+ - mediatek,mt7981-afe
-+ - mediatek,mt7988-afe
-+ - const: mediatek,mt7986-afe
-+
-+ reg:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ clocks:
-+ minItems: 5
-+ items:
-+ - description: audio bus clock
-+ - description: audio 26M clock
-+ - description: audio intbus clock
-+ - description: audio hopping clock
-+ - description: audio pll clock
-+ - description: mux for pcm_mck
-+ - description: audio i2s/pcm mck
-+
-+ clock-names:
-+ minItems: 5
-+ items:
-+ - const: bus_ck
-+ - const: 26m_ck
-+ - const: l_ck
-+ - const: aud_ck
-+ - const: eg2_ck
-+ - const: sel
-+ - const: i2s_m
-+
-+required:
-+ - compatible
-+ - reg
-+ - interrupts
-+ - clocks
-+ - clock-names
-+
-+allOf:
-+ - if:
-+ properties:
-+ compatible:
-+ contains:
-+ const: mediatek,mt7986-afe
-+ then:
-+ properties:
-+ clocks:
-+ items:
-+ - description: audio bus clock
-+ - description: audio 26M clock
-+ - description: audio intbus clock
-+ - description: audio hopping clock
-+ - description: audio pll clock
-+ clock-names:
-+ items:
-+ - const: bus_ck
-+ - const: 26m_ck
-+ - const: l_ck
-+ - const: aud_ck
-+ - const: eg2_ck
-+
-+ - if:
-+ properties:
-+ compatible:
-+ contains:
-+ const: mediatek,mt7981-afe
-+ then:
-+ properties:
-+ clocks:
-+ items:
-+ - description: audio bus clock
-+ - description: audio 26M clock
-+ - description: audio intbus clock
-+ - description: audio hopping clock
-+ - description: audio pll clock
-+ - description: mux for pcm_mck
-+ clock-names:
-+ items:
-+ - const: bus_ck
-+ - const: 26m_ck
-+ - const: l_ck
-+ - const: aud_ck
-+ - const: eg2_ck
-+ - const: sel
-+
-+ - if:
-+ properties:
-+ compatible:
-+ contains:
-+ const: mediatek,mt7988-afe
-+ then:
-+ properties:
-+ clocks:
-+ items:
-+ - description: audio bus clock
-+ - description: audio 26M clock
-+ - description: audio intbus clock
-+ - description: audio hopping clock
-+ - description: audio pll clock
-+ - description: mux for pcm_mck
-+ - description: audio i2s/pcm mck
-+ clock-names:
-+ items:
-+ - const: bus_ck
-+ - const: 26m_ck
-+ - const: l_ck
-+ - const: aud_ck
-+ - const: eg2_ck
-+ - const: sel
-+ - const: i2s_m
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/interrupt-controller/arm-gic.h>
-+ #include <dt-bindings/interrupt-controller/irq.h>
-+ #include <dt-bindings/clock/mt7986-clk.h>
-+
-+ afe@11210000 {
-+ compatible = "mediatek,mt7986-afe";
-+ reg = <0x11210000 0x9000>;
-+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&infracfg_ao CLK_INFRA_AUD_BUS_CK>,
-+ <&infracfg_ao CLK_INFRA_AUD_26M_CK>,
-+ <&infracfg_ao CLK_INFRA_AUD_L_CK>,
-+ <&infracfg_ao CLK_INFRA_AUD_AUD_CK>,
-+ <&infracfg_ao CLK_INFRA_AUD_EG2_CK>;
-+ clock-names = "bus_ck",
-+ "26m_ck",
-+ "l_ck",
-+ "aud_ck",
-+ "eg2_ck";
-+ assigned-clocks = <&topckgen CLK_TOP_A1SYS_SEL>,
-+ <&topckgen CLK_TOP_AUD_L_SEL>,
-+ <&topckgen CLK_TOP_A_TUNER_SEL>;
-+ assigned-clock-parents = <&topckgen CLK_TOP_APLL2_D4>,
-+ <&apmixedsys CLK_APMIXED_APLL2>,
-+ <&topckgen CLK_TOP_APLL2_D4>;
-+ };
-+
-+...
+++ /dev/null
-From f3f0934e5c7b9c16e0cb2435be3555382e6293ad Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Tue, 24 Oct 2023 11:50:17 +0800
-Subject: [PATCH 7/9] ASoC: mediatek: mt7986: drop the remove callback of
- mt7986_wm8960
-
-Drop the remove callback of mt7986_wm8960.
-
-Signed-off-by: Maso Huang <maso.huang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20231024035019.11732-2-maso.huang@mediatek.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- sound/soc/mediatek/mt7986/mt7986-wm8960.c | 10 ----------
- 1 file changed, 10 deletions(-)
-
---- a/sound/soc/mediatek/mt7986/mt7986-wm8960.c
-+++ b/sound/soc/mediatek/mt7986/mt7986-wm8960.c
-@@ -163,15 +163,6 @@ err_of_node_put:
- return ret;
- }
-
--static void mt7986_wm8960_machine_remove(struct platform_device *pdev)
--{
-- struct snd_soc_card *card = platform_get_drvdata(pdev);
-- struct mt7986_wm8960_priv *priv = snd_soc_card_get_drvdata(card);
--
-- of_node_put(priv->codec_node);
-- of_node_put(priv->platform_node);
--}
--
- static const struct of_device_id mt7986_wm8960_machine_dt_match[] = {
- {.compatible = "mediatek,mt7986-wm8960-sound"},
- { /* sentinel */ }
-@@ -184,7 +175,6 @@ static struct platform_driver mt7986_wm8
- .of_match_table = mt7986_wm8960_machine_dt_match,
- },
- .probe = mt7986_wm8960_machine_probe,
-- .remove_new = mt7986_wm8960_machine_remove,
- };
-
- module_platform_driver(mt7986_wm8960_machine);
+++ /dev/null
-From 98b8fb2cb4fcab1903d0baf611bf0c3f822a08dc Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Tue, 24 Oct 2023 11:50:18 +0800
-Subject: [PATCH 8/9] ASoC: mediatek: mt7986: remove the mt7986_wm8960_priv
- structure
-
-Remove the mt7986_wm8960_priv structure.
-
-Signed-off-by: Maso Huang <maso.huang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20231024035019.11732-3-maso.huang@mediatek.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- sound/soc/mediatek/mt7986/mt7986-wm8960.c | 33 +++++++++--------------
- 1 file changed, 12 insertions(+), 21 deletions(-)
-
---- a/sound/soc/mediatek/mt7986/mt7986-wm8960.c
-+++ b/sound/soc/mediatek/mt7986/mt7986-wm8960.c
-@@ -12,11 +12,6 @@
-
- #include "mt7986-afe-common.h"
-
--struct mt7986_wm8960_priv {
-- struct device_node *platform_node;
-- struct device_node *codec_node;
--};
--
- static const struct snd_soc_dapm_widget mt7986_wm8960_widgets[] = {
- SND_SOC_DAPM_HP("Headphone", NULL),
- SND_SOC_DAPM_MIC("AMIC", NULL),
-@@ -92,20 +87,18 @@ static int mt7986_wm8960_machine_probe(s
- struct snd_soc_card *card = &mt7986_wm8960_card;
- struct snd_soc_dai_link *dai_link;
- struct device_node *platform, *codec;
-- struct mt7986_wm8960_priv *priv;
-+ struct device_node *platform_dai_node, *codec_dai_node;
- int ret, i;
-
-- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-- if (!priv)
-- return -ENOMEM;
-+ card->dev = &pdev->dev;
-
- platform = of_get_child_by_name(pdev->dev.of_node, "platform");
-
- if (platform) {
-- priv->platform_node = of_parse_phandle(platform, "sound-dai", 0);
-+ platform_dai_node = of_parse_phandle(platform, "sound-dai", 0);
- of_node_put(platform);
-
-- if (!priv->platform_node) {
-+ if (!platform_dai_node) {
- dev_err(&pdev->dev, "Failed to parse platform/sound-dai property\n");
- return -EINVAL;
- }
-@@ -117,24 +110,22 @@ static int mt7986_wm8960_machine_probe(s
- for_each_card_prelinks(card, i, dai_link) {
- if (dai_link->platforms->name)
- continue;
-- dai_link->platforms->of_node = priv->platform_node;
-+ dai_link->platforms->of_node = platform_dai_node;
- }
-
-- card->dev = &pdev->dev;
--
- codec = of_get_child_by_name(pdev->dev.of_node, "codec");
-
- if (codec) {
-- priv->codec_node = of_parse_phandle(codec, "sound-dai", 0);
-+ codec_dai_node = of_parse_phandle(codec, "sound-dai", 0);
- of_node_put(codec);
-
-- if (!priv->codec_node) {
-- of_node_put(priv->platform_node);
-+ if (!codec_dai_node) {
-+ of_node_put(platform_dai_node);
- dev_err(&pdev->dev, "Failed to parse codec/sound-dai property\n");
- return -EINVAL;
- }
- } else {
-- of_node_put(priv->platform_node);
-+ of_node_put(platform_dai_node);
- dev_err(&pdev->dev, "Property 'codec' missing or invalid\n");
- return -EINVAL;
- }
-@@ -142,7 +133,7 @@ static int mt7986_wm8960_machine_probe(s
- for_each_card_prelinks(card, i, dai_link) {
- if (dai_link->codecs->name)
- continue;
-- dai_link->codecs->of_node = priv->codec_node;
-+ dai_link->codecs->of_node = codec_dai_node;
- }
-
- ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
-@@ -158,8 +149,8 @@ static int mt7986_wm8960_machine_probe(s
- }
-
- err_of_node_put:
-- of_node_put(priv->codec_node);
-- of_node_put(priv->platform_node);
-+ of_node_put(platform_dai_node);
-+ of_node_put(codec_dai_node);
- return ret;
- }
-
+++ /dev/null
-From 4e229f4264f4be7a6a554487714c0913ef59cf7f Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Tue, 24 Oct 2023 11:50:19 +0800
-Subject: [PATCH 9/9] ASoC: mediatek: mt7986: add sample rate checker
-
-mt7986 only supports 8/12/16/24/32/48/96/192 kHz
-
-Signed-off-by: Maso Huang <maso.huang@mediatek.com>
-Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
-Link: https://lore.kernel.org/r/20231024035019.11732-4-maso.huang@mediatek.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- sound/soc/mediatek/mt7986/mt7986-dai-etdm.c | 23 +++++++++++++++++----
- 1 file changed, 19 insertions(+), 4 deletions(-)
-
---- a/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c
-+++ b/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c
-@@ -237,12 +237,27 @@ static int mtk_dai_etdm_hw_params(struct
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
- {
-+ unsigned int rate = params_rate(params);
- struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-
-- mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_PLAYBACK);
-- mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_CAPTURE);
--
-- return 0;
-+ switch (rate) {
-+ case 8000:
-+ case 12000:
-+ case 16000:
-+ case 24000:
-+ case 32000:
-+ case 48000:
-+ case 96000:
-+ case 192000:
-+ mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_PLAYBACK);
-+ mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_CAPTURE);
-+ return 0;
-+ default:
-+ dev_err(afe->dev,
-+ "Sample rate %d invalid. Supported rates: 8/12/16/24/32/48/96/192 kHz\n",
-+ rate);
-+ return -EINVAL;
-+ }
- }
-
- static int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int cmd,
+++ /dev/null
-From e4cde335d1771863a60b6931e51357b8470e85c4 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 10 Dec 2023 22:41:39 +0000
-Subject: [PATCH] ASoC: mediatek: mt7986: silence error in case of
- -EPROBE_DEFER
-
-If probe is defered no error should be printed. Mute it.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- sound/soc/mediatek/mt7986/mt7986-wm8960.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/sound/soc/mediatek/mt7986/mt7986-wm8960.c
-+++ b/sound/soc/mediatek/mt7986/mt7986-wm8960.c
-@@ -144,7 +144,9 @@ static int mt7986_wm8960_machine_probe(s
-
- ret = devm_snd_soc_register_card(&pdev->dev, card);
- if (ret) {
-- dev_err(&pdev->dev, "%s snd_soc_register_card fail: %d\n", __func__, ret);
-+ if (ret != -EPROBE_DEFER)
-+ dev_err(&pdev->dev, "%s snd_soc_register_card fail: %d\n", __func__, ret);
-+
- goto err_of_node_put;
- }
-
+++ /dev/null
-From 1c09b694a1e9378931085e77d834a4d9786a5356 Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Thu, 7 Sep 2023 10:54:37 +0800
-Subject: [PATCH] arm64: dts: mt7986: add afe
-
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 23 +++++++++++
- 1 files changed, 23 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -249,6 +249,28 @@
- status = "disabled";
- };
-
-+ afe: audio-controller@11210000 {
-+ compatible = "mediatek,mt7986-afe";
-+ reg = <0 0x11210000 0 0x9000>;
-+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&infracfg CLK_INFRA_AUD_BUS_CK>,
-+ <&infracfg CLK_INFRA_AUD_26M_CK>,
-+ <&infracfg CLK_INFRA_AUD_L_CK>,
-+ <&infracfg CLK_INFRA_AUD_AUD_CK>,
-+ <&infracfg CLK_INFRA_AUD_EG2_CK>;
-+ clock-names = "aud_bus_ck",
-+ "aud_26m_ck",
-+ "aud_l_ck",
-+ "aud_aud_ck",
-+ "aud_eg2_ck";
-+ assigned-clocks = <&topckgen CLK_TOP_A1SYS_SEL>,
-+ <&topckgen CLK_TOP_AUD_L_SEL>,
-+ <&topckgen CLK_TOP_A_TUNER_SEL>;
-+ assigned-clock-parents = <&topckgen CLK_TOP_APLL2_D4>,
-+ <&apmixedsys CLK_APMIXED_APLL2>,
-+ <&topckgen CLK_TOP_APLL2_D4>;
-+ };
-+
- pwm: pwm@10048000 {
- compatible = "mediatek,mt7986-pwm";
- reg = <0 0x10048000 0 0x1000>;
+++ /dev/null
-From 1c09b694a1e9378931085e77d834a4d9786a5356 Mon Sep 17 00:00:00 2001
-From: Maso Huang <maso.huang@mediatek.com>
-Date: Thu, 7 Sep 2023 10:54:37 +0800
-Subject: [PATCH] arm64: dts: mt7986: add sound wm8960
-
----
- .../dts/mediatek/mt7986a-rfb-spim-nand.dts | 39 +++++++++++++++++++
- 1 files changed, 39 insertions(+)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts
-@@ -4,6 +4,35 @@
-
- / {
- compatible = "mediatek,mt7986a-rfb-snand";
-+
-+ sound_wm8960 {
-+ compatible = "mediatek,mt7986-wm8960-sound";
-+ audio-routing = "Headphone", "HP_L",
-+ "Headphone", "HP_R",
-+ "LINPUT1", "AMIC",
-+ "RINPUT1", "AMIC";
-+
-+ status = "okay";
-+
-+ platform {
-+ sound-dai = <&afe>;
-+ };
-+
-+ codec {
-+ sound-dai = <&wm8960>;
-+ };
-+ };
-+};
-+
-+&i2c0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c_pins>;
-+ status = "okay";
-+
-+ wm8960: wm8960@1a {
-+ compatible = "wlf,wm8960";
-+ reg = <0x1a>;
-+ };
- };
-
- &spi0 {
-@@ -50,3 +79,13 @@
- &wifi {
- mediatek,mtd-eeprom = <&factory 0>;
- };
-+
-+&pio {
-+ i2c_pins: i2c-pins-3-4 {
-+ mux {
-+ function = "i2c";
-+ groups = "i2c";
-+ };
-+ };
-+};
-+
+++ /dev/null
---- /dev/null
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-respeaker-2mics.dtso
-@@ -0,0 +1,62 @@
-+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-+/*
-+ * Copyright (C) 2023 MediaTek Inc.
-+ * Author: Maso Huang <Maso.Huang@mediatek.com>
-+ */
-+
-+/dts-v1/;
-+/plugin/;
-+
-+/ {
-+ compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
-+
-+ fragment@0 {
-+ target-path = "/";
-+ __overlay__ {
-+ sound_wm8960 {
-+ compatible = "mediatek,mt7986-wm8960-sound";
-+ audio-routing = "Headphone", "HP_L",
-+ "Headphone", "HP_R",
-+ "LINPUT1", "AMIC",
-+ "RINPUT1", "AMIC";
-+
-+ status = "okay";
-+
-+ platform {
-+ sound-dai = <&afe>;
-+ };
-+
-+ codec {
-+ sound-dai = <&wm8960>;
-+ };
-+ };
-+ };
-+ };
-+
-+ fragment@1 {
-+ target = <&i2c0>;
-+ __overlay__ {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c_pins>;
-+ clock-frequency = <400000>;
-+ status = "okay";
-+
-+ wm8960: wm8960@1a {
-+ compatible = "wlf,wm8960";
-+ reg = <0x1a>;
-+ };
-+ };
-+ };
-+
-+ fragment@2 {
-+ target = <&pio>;
-+ __overlay__ {
-+ i2c_pins: i2c-pins-3-4 {
-+ mux {
-+ function = "i2c";
-+ groups = "i2c";
-+ };
-+ };
-+ };
-+ };
-+};
---- a/arch/arm64/boot/dts/mediatek/Makefile
-+++ b/arch/arm64/boot/dts/mediatek/Makefile
-@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-b
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo
-+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-respeaker-2mics.dtbo
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb
- dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -313,7 +313,7 @@
- /* Attention: GPIO 90 is used to switch between PCIe@1,0 and
- * SATA functions. i.e. output-high: PCIe, output-low: SATA
- */
-- asm_sel {
-+ asmsel: asm_sel {
- gpio-hog;
- gpios = <90 GPIO_ACTIVE_HIGH>;
- output-high;
---- /dev/null
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-sata.dtso
-@@ -0,0 +1,31 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
-+
-+#include <dt-bindings/gpio/gpio.h>
-+
-+/dts-v1/;
-+/plugin/;
-+
-+/ {
-+ compatible = "bananapi,bpi-r64", "mediatek,mt7622";
-+
-+ fragment@0 {
-+ target = <&asmsel>;
-+ __overlay__ {
-+ gpios = <90 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ fragment@1 {
-+ target = <&sata>;
-+ __overlay__ {
-+ status = "okay";
-+ };
-+ };
-+
-+ fragment@2 {
-+ target = <&sata_phy>;
-+ __overlay__ {
-+ status = "okay";
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-pcie1.dtso
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
-+
-+#include <dt-bindings/gpio/gpio.h>
-+
-+/dts-v1/;
-+/plugin/;
-+
-+/ {
-+ compatible = "bananapi,bpi-r64", "mediatek,mt7622";
-+
-+ fragment@0 {
-+ target = <&asmsel>;
-+ __overlay__ {
-+ gpios = <90 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
+++ /dev/null
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -1589,6 +1589,14 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
-
- 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 CMDLINE
- string "Default kernel command string"
- default ""
---- 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
---- a/arch/arm64/Kconfig
-+++ b/arch/arm64/Kconfig
-@@ -2240,6 +2240,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 EFI_STUB
- bool
-
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -640,5 +640,28 @@
- };
-
- &wmac {
-+ mediatek,eeprom-data = <0x22760500 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x0 0x44000020 0x0 0x10002000
-+ 0x4400 0x4000000 0x0 0x0
-+ 0x200000b3 0x40b6c3c3 0x26000000 0x41c42600
-+ 0x41c4 0x26000000 0xc0c52600 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0xc6c6
-+ 0xc3c3c2c1 0xc300c3 0x818181 0x83c1c182
-+ 0x83838382 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x84002e00 0x90000087 0x8a000000 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0xb000009 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x0
-+ 0x0 0x0 0x0 0x7707>;
-+
- status = "okay";
- };
+++ /dev/null
---- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
-@@ -32,6 +32,9 @@
- chosen {
- stdout-path = "serial0:115200n8";
- bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
-+ rootdisk-emmc = <&emmc_rootfs>;
-+ rootdisk-sd = <&sd_rootfs>;
-+ rootdisk-snfi = <&ubi_rootfs>;
- };
-
- cpus {
-@@ -234,6 +237,26 @@
- assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
- non-removable;
-+
-+ card@0 {
-+ compatible = "mmc-card";
-+ reg = <0>;
-+
-+ block {
-+ compatible = "block-device";
-+ partitions {
-+ block-partition-env {
-+ partname = "ubootenv";
-+ nvmem-layout {
-+ compatible = "u-boot,env-layout";
-+ };
-+ };
-+ emmc_rootfs: block-partition-production {
-+ partname = "production";
-+ };
-+ };
-+ };
-+ };
- };
-
- &mmc1 {
-@@ -250,6 +273,26 @@
- vqmmc-supply = <®_3p3v>;
- assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>;
- assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
-+
-+ card@0 {
-+ compatible = "mmc-card";
-+ reg = <0>;
-+
-+ block {
-+ compatible = "block-device";
-+ partitions {
-+ block-partition-env {
-+ partname = "ubootenv";
-+ nvmem-layout {
-+ compatible = "u-boot,env-layout";
-+ };
-+ };
-+ sd_rootfs: block-partition-production {
-+ partname = "production";
-+ };
-+ };
-+ };
-+ };
- };
-
- &nandc {
-@@ -284,14 +327,29 @@
- };
-
- partition@80000 {
-- label = "fip";
-- reg = <0x80000 0x200000>;
-- read-only;
-- };
--
-- ubi: partition@280000 {
- label = "ubi";
-- reg = <0x280000 0x7d80000>;
-+ reg = <0x80000 0x7f80000>;
-+ compatible = "linux,ubi";
-+
-+ volumes {
-+ ubi-volume-ubootenv {
-+ volname = "ubootenv";
-+ nvmem-layout {
-+ compatible = "u-boot,env-redundant-bool-layout";
-+ };
-+ };
-+
-+ ubi-volume-ubootenv2 {
-+ volname = "ubootenv2";
-+ nvmem-layout {
-+ compatible = "u-boot,env-redundant-bool-layout";
-+ };
-+ };
-+
-+ ubi_rootfs: ubi-volume-fit {
-+ volname = "fit";
-+ };
-+ };
- };
- };
- };
+++ /dev/null
---- a/drivers/spi/spi-mt65xx.c
-+++ b/drivers/spi/spi-mt65xx.c
-@@ -1227,8 +1227,15 @@ static int mtk_spi_probe(struct platform
- if (ret < 0)
- return dev_err_probe(dev, ret, "failed to enable hclk\n");
-
-+ ret = clk_prepare_enable(mdata->sel_clk);
-+ if (ret < 0) {
-+ clk_disable_unprepare(mdata->spi_hclk);
-+ return dev_err_probe(dev, ret, "failed to enable sel_clk\n");
-+ }
-+
- ret = clk_prepare_enable(mdata->spi_clk);
- if (ret < 0) {
-+ clk_disable_unprepare(mdata->sel_clk);
- clk_disable_unprepare(mdata->spi_hclk);
- return dev_err_probe(dev, ret, "failed to enable spi_clk\n");
- }
+++ /dev/null
-From 3cf212c4ce6cd72c09bc47f35f539ba0afd4d106 Mon Sep 17 00:00:00 2001
-Message-Id: <3cf212c4ce6cd72c09bc47f35f539ba0afd4d106.1678716918.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sun, 12 Mar 2023 16:40:31 +0100
-Subject: [PATCH net-next 1/2] net: ethernet: mtk_wed: rename
- mtk_wed_get_memory_region in mtk_wed_get_reserved_memory_region
-
-This is a preliminary patch to move wed ilm/dlm and cpuboot properties in
-dedicated dts nodes.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -234,8 +234,8 @@ int mtk_wed_mcu_msg_update(struct mtk_we
- }
-
- static int
--mtk_wed_get_memory_region(struct mtk_wed_hw *hw, int index,
-- struct mtk_wed_wo_memory_region *region)
-+mtk_wed_get_reserved_memory_region(struct mtk_wed_hw *hw, int index,
-+ struct mtk_wed_wo_memory_region *region)
- {
- struct reserved_mem *rmem;
- struct device_node *np;
-@@ -321,7 +321,7 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- if (index < 0)
- continue;
-
-- ret = mtk_wed_get_memory_region(wo->hw, index, &mem_region[i]);
-+ ret = mtk_wed_get_reserved_memory_region(wo->hw, index, &mem_region[i]);
- if (ret)
- return ret;
- }
+++ /dev/null
-From 247e566e3459481f1fa98733534bfed767e18b42 Mon Sep 17 00:00:00 2001
-Message-Id: <247e566e3459481f1fa98733534bfed767e18b42.1678620342.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 11 Mar 2023 16:32:41 +0100
-Subject: [PATCH net-next] arm64: dts: mt7986: move cpuboot in a dedicated node
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 21 +++++++++++----------
- 1 file changed, 11 insertions(+), 10 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -121,12 +121,6 @@
- reg = <0 0x151f8000 0 0x2000>;
- no-map;
- };
--
-- wo_boot: wo-boot@15194000 {
-- reg = <0 0x15194000 0 0x1000>;
-- no-map;
-- };
--
- };
-
- timer {
-@@ -541,10 +535,11 @@
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
- memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>,
-- <&wo_data>, <&wo_boot>;
-+ <&wo_data>;
- memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
-- "wo-data", "wo-boot";
-+ "wo-data";
- mediatek,wo-ccif = <&wo_ccif0>;
-+ mediatek,wo-cpuboot = <&wo_cpuboot>;
- };
-
- wed1: wed@15011000 {
-@@ -554,10 +549,11 @@
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
- memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>,
-- <&wo_data>, <&wo_boot>;
-+ <&wo_data>;
- memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
-- "wo-data", "wo-boot";
-+ "wo-data";
- mediatek,wo-ccif = <&wo_ccif1>;
-+ mediatek,wo-cpuboot = <&wo_cpuboot>;
- };
-
- wo_ccif0: syscon@151a5000 {
-@@ -574,6 +570,11 @@
- interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
- };
-
-+ wo_cpuboot: syscon@15194000 {
-+ compatible = "mediatek,mt7986-wo-cpuboot", "syscon";
-+ reg = <0 0x15194000 0 0x1000>;
-+ };
-+
- eth: ethernet@15100000 {
- compatible = "mediatek,mt7986-eth";
- reg = <0 0x15100000 0 0x80000>;
+++ /dev/null
-From f292d1bf83ec160bef2532b58aa08f5b71041923 Mon Sep 17 00:00:00 2001
-Message-Id: <f292d1bf83ec160bef2532b58aa08f5b71041923.1678716918.git.lorenzo@kernel.org>
-In-Reply-To: <3cf212c4ce6cd72c09bc47f35f539ba0afd4d106.1678716918.git.lorenzo@kernel.org>
-References: <3cf212c4ce6cd72c09bc47f35f539ba0afd4d106.1678716918.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 11 Mar 2023 18:13:04 +0100
-Subject: [PATCH net-next 2/2] net: ethernet: mtk_wed: move cpuboot in a
- dedicated dts node
-
-Since the cpuboot memory region is not part of the RAM SoC, move cpuboot
-in a deidicated syscon node.
-This patch helps to keep backward-compatibility with older version of
-uboot codebase where we have a limit of 8 reserved-memory dts child
-nodes.
-Keep backward-compatibility with older dts version where cpuboot was
-defined as reserved-memory child node.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 34 +++++++++++++++++----
- drivers/net/ethernet/mediatek/mtk_wed_wo.h | 3 +-
- 2 files changed, 30 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -34,12 +34,23 @@ static struct mtk_wed_wo_memory_region m
-
- static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg)
- {
-- return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
-+ u32 val;
-+
-+ if (!wo->boot_regmap)
-+ return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
-+
-+ if (regmap_read(wo->boot_regmap, reg, &val))
-+ val = ~0;
-+
-+ return val;
- }
-
- static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
- {
-- writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
-+ if (wo->boot_regmap)
-+ regmap_write(wo->boot_regmap, reg, val);
-+ else
-+ writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
- }
-
- static struct sk_buff *
-@@ -313,6 +324,9 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- u32 val, boot_cr;
- int ret, i;
-
-+ wo->boot_regmap = syscon_regmap_lookup_by_phandle(wo->hw->node,
-+ "mediatek,wo-cpuboot");
-+
- /* load firmware region metadata */
- for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
- int index = of_property_match_string(wo->hw->node,
-@@ -321,6 +335,9 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- if (index < 0)
- continue;
-
-+ if (index == MTK_WED_WO_REGION_BOOT && !IS_ERR(wo->boot_regmap))
-+ continue;
-+
- ret = mtk_wed_get_reserved_memory_region(wo->hw, index, &mem_region[i]);
- if (ret)
- return ret;
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -231,6 +231,7 @@ struct mtk_wed_wo_queue {
- struct mtk_wed_wo {
- struct mtk_wed_hw *hw;
-
-+ struct regmap *boot_regmap;
- struct mtk_wed_wo_queue q_tx;
- struct mtk_wed_wo_queue q_rx;
-
+++ /dev/null
-From f3565e6c2276411275e707a5442d3f69cc111273 Mon Sep 17 00:00:00 2001
-Message-Id: <f3565e6c2276411275e707a5442d3f69cc111273.1678718888.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sun, 12 Mar 2023 18:51:47 +0100
-Subject: [PATCH net-next 1/3] net: ethernet: mtk_wed: move ilm a dedicated dts
- node
-
-Since the ilm memory region is not part of the RAM SoC, move ilm in a
-deidicated syscon node.
-This patch helps to keep backward-compatibility with older version of
-uboot codebase where we have a limit of 8 reserved-memory dts child
-nodes.
-Keep backward-compatibility with older dts version where ilm was defined
-as reserved-memory child node.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 55 ++++++++++++++++++---
- 1 file changed, 49 insertions(+), 6 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -316,6 +316,39 @@ next:
- }
-
- static int
-+mtk_wed_mcu_load_ilm(struct mtk_wed_wo *wo)
-+{
-+ struct mtk_wed_wo_memory_region *ilm_region;
-+ struct resource res;
-+ struct device_node *np;
-+ int ret;
-+
-+ np = of_parse_phandle(wo->hw->node, "mediatek,wo-ilm", 0);
-+ if (!np)
-+ return 0;
-+
-+ ret = of_address_to_resource(np, 0, &res);
-+ of_node_put(np);
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ ilm_region = &mem_region[MTK_WED_WO_REGION_ILM];
-+ ilm_region->phy_addr = res.start;
-+ ilm_region->size = resource_size(&res);
-+ ilm_region->addr = devm_ioremap(wo->hw->dev, res.start,
-+ resource_size(&res));
-+
-+ if (!IS_ERR(ilm_region->addr))
-+ return 0;
-+
-+ ret = PTR_ERR(ilm_region->addr);
-+ ilm_region->addr = NULL;
-+
-+ return ret;
-+}
-+
-+static int
- mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
- {
- const struct mtk_wed_fw_trailer *trailer;
-@@ -324,14 +357,20 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
- u32 val, boot_cr;
- int ret, i;
-
-+ mtk_wed_mcu_load_ilm(wo);
- wo->boot_regmap = syscon_regmap_lookup_by_phandle(wo->hw->node,
- "mediatek,wo-cpuboot");
-
- /* load firmware region metadata */
- for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
-- int index = of_property_match_string(wo->hw->node,
-- "memory-region-names",
-- mem_region[i].name);
-+ int index;
-+
-+ if (mem_region[i].addr)
-+ continue;
-+
-+ index = of_property_match_string(wo->hw->node,
-+ "memory-region-names",
-+ mem_region[i].name);
- if (index < 0)
- continue;
-
+++ /dev/null
-From b74ba226be2c45091b93bd49192bdd6d2178729e Mon Sep 17 00:00:00 2001
-Message-Id: <b74ba226be2c45091b93bd49192bdd6d2178729e.1678718888.git.lorenzo@kernel.org>
-In-Reply-To: <f3565e6c2276411275e707a5442d3f69cc111273.1678718888.git.lorenzo@kernel.org>
-References: <f3565e6c2276411275e707a5442d3f69cc111273.1678718888.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 13 Mar 2023 15:45:16 +0100
-Subject: [PATCH net-next 3/3] net: ethernet: mtk_wed: move dlm a dedicated dts
- node
-
-Since the dlm memory region is not part of the RAM SoC, move dlm in a
-deidicated syscon node.
-This patch helps to keep backward-compatibility with older version of
-uboot codebase where we have a limit of 8 reserved-memory dts child
-nodes.
-Keep backward-compatibility with older dts version where dlm was defined
-as reserved-memory child node.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1320,6 +1320,24 @@ mtk_wed_rro_alloc(struct mtk_wed_device
- struct device_node *np;
- int index;
-
-+ np = of_parse_phandle(dev->hw->node, "mediatek,wo-dlm", 0);
-+ if (np) {
-+ struct resource res;
-+ int ret;
-+
-+ ret = of_address_to_resource(np, 0, &res);
-+ of_node_put(np);
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ dev->rro.miod_phys = res.start;
-+ goto out;
-+ }
-+
-+ /* For backward compatibility, we need to check if DLM
-+ * node is defined through reserved memory property.
-+ */
- index = of_property_match_string(dev->hw->node, "memory-region-names",
- "wo-dlm");
- if (index < 0)
-@@ -1336,6 +1354,7 @@ mtk_wed_rro_alloc(struct mtk_wed_device
- return -ENODEV;
-
- dev->rro.miod_phys = rmem->base;
-+out:
- dev->rro.fdbk_phys = MTK_WED_MIOD_COUNT + dev->rro.miod_phys;
-
- return mtk_wed_rro_ring_alloc(dev, &dev->rro.ring,
+++ /dev/null
-From 01561065af5bf1d2a4244896d897e3a1eafbcd46 Mon Sep 17 00:00:00 2001
-Message-Id: <01561065af5bf1d2a4244896d897e3a1eafbcd46.1678717704.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 13 Mar 2023 15:10:56 +0100
-Subject: [PATCH net-next] arm64: dts: mt7986: move ilm in a dedicated node
-
-Since the ilm memory region is not part of the RAM SoC, move ilm in a
-deidicated syscon node.
-This patch helps to keep backward-compatibility with older version of
-uboot codebase where we have a limit of 8 reserved-memory dts child
-nodes.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 34 +++++++++++------------
- 1 file changed, 16 insertions(+), 18 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -97,16 +97,6 @@
- no-map;
- };
-
-- wo_ilm0: wo-ilm@151e0000 {
-- reg = <0 0x151e0000 0 0x8000>;
-- no-map;
-- };
--
-- wo_ilm1: wo-ilm@151f0000 {
-- reg = <0 0x151f0000 0 0x8000>;
-- no-map;
-- };
--
- wo_data: wo-data@4fd80000 {
- reg = <0 0x4fd80000 0 0x240000>;
- no-map;
-@@ -534,11 +524,10 @@
- reg = <0 0x15010000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
-- memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>,
-- <&wo_data>;
-- memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
-- "wo-data";
-+ memory-region = <&wo_emi0>, <&wo_dlm0>, <&wo_data>;
-+ memory-region-names = "wo-emi", "wo-dlm", "wo-data";
- mediatek,wo-ccif = <&wo_ccif0>;
-+ mediatek,wo-ilm = <&wo_ilm0>;
- mediatek,wo-cpuboot = <&wo_cpuboot>;
- };
-
-@@ -548,11 +537,10 @@
- reg = <0 0x15011000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
-- memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>,
-- <&wo_data>;
-- memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
-- "wo-data";
-+ memory-region = <&wo_emi1>, <&wo_dlm1>, <&wo_data>;
-+ memory-region-names = "wo-emi", "wo-dlm", "wo-data";
- mediatek,wo-ccif = <&wo_ccif1>;
-+ mediatek,wo-ilm = <&wo_ilm1>;
- mediatek,wo-cpuboot = <&wo_cpuboot>;
- };
-
-@@ -570,6 +558,16 @@
- interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
- };
-
-+ wo_ilm0: syscon@151e0000 {
-+ compatible = "mediatek,mt7986-wo-ilm", "syscon";
-+ reg = <0 0x151e0000 0 0x8000>;
-+ };
-+
-+ wo_ilm1: syscon@151f0000 {
-+ compatible = "mediatek,mt7986-wo-ilm", "syscon";
-+ reg = <0 0x151f0000 0 0x8000>;
-+ };
-+
- wo_cpuboot: syscon@15194000 {
- compatible = "mediatek,mt7986-wo-cpuboot", "syscon";
- reg = <0 0x15194000 0 0x1000>;
+++ /dev/null
-From 9f76be683a8ec498563c294bc1cc279468058302 Mon Sep 17 00:00:00 2001
-Message-Id: <9f76be683a8ec498563c294bc1cc279468058302.1678719283.git.lorenzo@kernel.org>
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Mon, 13 Mar 2023 15:53:30 +0100
-Subject: [PATCH net-next] arm64: dts: mt7986: move dlm in a dedicated node
-
-Since the dlm memory region is not part of the RAM SoC, move dlm in a
-deidicated syscon node.
-This patch helps to keep backward-compatibility with older version of
-uboot codebase where we have a limit of 8 reserved-memory dts child
-nodes.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 30 ++++++++++++-----------
- 1 file changed, 16 insertions(+), 14 deletions(-)
-
---- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -101,16 +101,6 @@
- reg = <0 0x4fd80000 0 0x240000>;
- no-map;
- };
--
-- wo_dlm0: wo-dlm@151e8000 {
-- reg = <0 0x151e8000 0 0x2000>;
-- no-map;
-- };
--
-- wo_dlm1: wo-dlm@151f8000 {
-- reg = <0 0x151f8000 0 0x2000>;
-- no-map;
-- };
- };
-
- timer {
-@@ -524,10 +514,11 @@
- reg = <0 0x15010000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
-- memory-region = <&wo_emi0>, <&wo_dlm0>, <&wo_data>;
-- memory-region-names = "wo-emi", "wo-dlm", "wo-data";
-+ memory-region = <&wo_emi0>, <&wo_data>;
-+ memory-region-names = "wo-emi", "wo-data";
- mediatek,wo-ccif = <&wo_ccif0>;
- mediatek,wo-ilm = <&wo_ilm0>;
-+ mediatek,wo-dlm = <&wo_dlm0>;
- mediatek,wo-cpuboot = <&wo_cpuboot>;
- };
-
-@@ -537,10 +528,11 @@
- reg = <0 0x15011000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
-- memory-region = <&wo_emi1>, <&wo_dlm1>, <&wo_data>;
-- memory-region-names = "wo-emi", "wo-dlm", "wo-data";
-+ memory-region = <&wo_emi1>, <&wo_data>;
-+ memory-region-names = "wo-emi", "wo-data";
- mediatek,wo-ccif = <&wo_ccif1>;
- mediatek,wo-ilm = <&wo_ilm1>;
-+ mediatek,wo-dlm = <&wo_dlm1>;
- mediatek,wo-cpuboot = <&wo_cpuboot>;
- };
-
-@@ -568,6 +560,16 @@
- reg = <0 0x151f0000 0 0x8000>;
- };
-
-+ wo_dlm0: syscon@151e8000 {
-+ compatible = "mediatek,mt7986-wo-dlm", "syscon";
-+ reg = <0 0x151e8000 0 0x2000>;
-+ };
-+
-+ wo_dlm1: syscon@151f8000 {
-+ compatible = "mediatek,mt7986-wo-dlm", "syscon";
-+ reg = <0 0x151f8000 0 0x2000>;
-+ };
-+
- wo_cpuboot: syscon@15194000 {
- compatible = "mediatek,mt7986-wo-cpuboot", "syscon";
- reg = <0 0x15194000 0 0x1000>;
+++ /dev/null
----
- drivers/leds/Kconfig | 10 ++++++++++
- drivers/leds/Makefile | 1 +
- 2 files changed, 11 insertions(+)
-
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -874,6 +874,16 @@ source "drivers/leds/flash/Kconfig"
- comment "RGB LED drivers"
- source "drivers/leds/rgb/Kconfig"
-
-+config LEDS_SMARTRG_LED
-+ tristate "LED support for Adtran SmartRG"
-+ depends on LEDS_CLASS && I2C && OF
-+ help
-+ This option enables support for the Adtran SmartRG platform
-+ system LED driver.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called leds-smartrg-system.
-+
- comment "LED Triggers"
- source "drivers/leds/trigger/Kconfig"
-
---- a/drivers/leds/Makefile
-+++ b/drivers/leds/Makefile
-@@ -76,6 +76,7 @@ obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
- obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o
- obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
- obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o
-+obj-$(CONFIG_LEDS_SMARTRG_LED) += leds-smartrg-system.o
- obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o
- obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o
- obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
+++ /dev/null
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Thu, 2 Nov 2023 16:47:07 +0100
-Subject: [PATCH net-next 1/2] net: ethernet: mediatek: split tx and rx fields
- in mtk_soc_data struct
-
-Split tx and rx fields in mtk_soc_data struct. This is a preliminary
-patch to roll back to QDMA for MT7986 SoC in order to fix a hw hang
-if the device receives a corrupted packet.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 210 ++++++++++++--------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 29 +--
- 2 files changed, 139 insertions(+), 100 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1264,7 +1264,7 @@ static int mtk_init_fq_dma(struct mtk_et
- eth->scratch_ring = eth->sram_base;
- else
- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
-- cnt * soc->txrx.txd_size,
-+ cnt * soc->tx.desc_size,
- ð->phy_scratch_ring,
- GFP_KERNEL);
- if (unlikely(!eth->scratch_ring))
-@@ -1280,16 +1280,16 @@ 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 + soc->txrx.txd_size * (cnt - 1);
-+ phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
-
- for (i = 0; i < cnt; i++) {
- struct mtk_tx_dma_v2 *txd;
-
-- txd = eth->scratch_ring + i * soc->txrx.txd_size;
-+ txd = eth->scratch_ring + i * soc->tx.desc_size;
- txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
- if (i < cnt - 1)
- txd->txd2 = eth->phy_scratch_ring +
-- (i + 1) * soc->txrx.txd_size;
-+ (i + 1) * soc->tx.desc_size;
-
- txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
- txd->txd4 = 0;
-@@ -1538,7 +1538,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, soc->txrx.txd_size);
-+ itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
- memset(itx_buf, 0, sizeof(*itx_buf));
-
- txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
-@@ -1579,7 +1579,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);
-+ soc->tx.dma_max_len);
- txd_info.qid = queue;
- txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
- !(frag_size - txd_info.size);
-@@ -1592,7 +1592,7 @@ 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,
-- soc->txrx.txd_size);
-+ soc->tx.desc_size);
- if (new_desc)
- memset(tx_buf, 0, sizeof(*tx_buf));
- tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
-@@ -1635,7 +1635,7 @@ static int mtk_tx_map(struct sk_buff *sk
- } else {
- int next_idx;
-
-- next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->txrx.txd_size),
-+ next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_size),
- ring->dma_size);
- mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
- }
-@@ -1644,7 +1644,7 @@ static int mtk_tx_map(struct sk_buff *sk
-
- err_dma:
- do {
-- tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size);
-+ tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
-
- /* unmap dma */
- mtk_tx_unmap(eth, tx_buf, NULL, false);
-@@ -1669,7 +1669,7 @@ static int mtk_cal_txd_req(struct mtk_et
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- frag = &skb_shinfo(skb)->frags[i];
- nfrags += DIV_ROUND_UP(skb_frag_size(frag),
-- eth->soc->txrx.dma_max_len);
-+ eth->soc->tx.dma_max_len);
- }
- } else {
- nfrags += skb_shinfo(skb)->nr_frags;
-@@ -1810,7 +1810,7 @@ static struct mtk_rx_ring *mtk_get_rx_ri
-
- ring = ð->rx_ring[i];
- idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
-- rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
-+ rxd = ring->dma + idx * eth->soc->rx.desc_size;
- if (rxd->rxd2 & RX_DMA_DONE) {
- ring->calc_idx_update = true;
- return ring;
-@@ -1978,7 +1978,7 @@ static int mtk_xdp_submit_frame(struct m
- }
- htxd = txd;
-
-- tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size);
-+ tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_size);
- memset(tx_buf, 0, sizeof(*tx_buf));
- htx_buf = tx_buf;
-
-@@ -1997,7 +1997,7 @@ static int mtk_xdp_submit_frame(struct m
- goto unmap;
-
- tx_buf = mtk_desc_to_tx_buf(ring, txd,
-- soc->txrx.txd_size);
-+ soc->tx.desc_size);
- memset(tx_buf, 0, sizeof(*tx_buf));
- n_desc++;
- }
-@@ -2035,7 +2035,7 @@ static int mtk_xdp_submit_frame(struct m
- } else {
- int idx;
-
-- idx = txd_to_idx(ring, txd, soc->txrx.txd_size);
-+ idx = txd_to_idx(ring, txd, soc->tx.desc_size);
- mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
- MT7628_TX_CTX_IDX0);
- }
-@@ -2046,7 +2046,7 @@ static int mtk_xdp_submit_frame(struct m
-
- unmap:
- while (htxd != txd) {
-- tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->txrx.txd_size);
-+ tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_size);
- mtk_tx_unmap(eth, tx_buf, NULL, false);
-
- htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-@@ -2177,7 +2177,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 * eth->soc->txrx.rxd_size;
-+ rxd = ring->dma + idx * eth->soc->rx.desc_size;
- data = ring->data[idx];
-
- if (!mtk_rx_get_desc(eth, &trxd, rxd))
-@@ -2312,7 +2312,7 @@ static int mtk_poll_rx(struct napi_struc
- rxdcsum = &trxd.rxd4;
- }
-
-- if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid)
-+ if (*rxdcsum & eth->soc->rx.dma_l4_valid)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb_checksum_none_assert(skb);
-@@ -2436,7 +2436,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
- break;
-
- tx_buf = mtk_desc_to_tx_buf(ring, desc,
-- eth->soc->txrx.txd_size);
-+ eth->soc->tx.desc_size);
- if (!tx_buf->data)
- break;
-
-@@ -2487,7 +2487,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
- }
- mtk_tx_unmap(eth, tx_buf, &bq, true);
-
-- desc = ring->dma + cpu * eth->soc->txrx.txd_size;
-+ desc = ring->dma + cpu * eth->soc->tx.desc_size;
- ring->last_free = desc;
- atomic_inc(&ring->free_count);
-
-@@ -2577,7 +2577,7 @@ static int mtk_napi_rx(struct napi_struc
- do {
- int rx_done;
-
-- mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask,
-+ mtk_w32(eth, eth->soc->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;
-@@ -2593,10 +2593,10 @@ static int mtk_napi_rx(struct napi_struc
- return budget;
-
- } while (mtk_r32(eth, reg_map->pdma.irq_status) &
-- eth->soc->txrx.rx_irq_done_mask);
-+ eth->soc->rx.irq_done_mask);
-
- if (napi_complete_done(napi, rx_done_total))
-- mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
-+ mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
-
- return rx_done_total;
- }
-@@ -2605,7 +2605,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- {
- const struct mtk_soc_data *soc = eth->soc;
- struct mtk_tx_ring *ring = ð->tx_ring;
-- int i, sz = soc->txrx.txd_size;
-+ int i, sz = soc->tx.desc_size;
- struct mtk_tx_dma_v2 *txd;
- int ring_size;
- u32 ofs, val;
-@@ -2728,14 +2728,14 @@ static void mtk_tx_clean(struct mtk_eth
- }
- 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_size * soc->tx.desc_size,
- ring->dma, ring->phys);
- ring->dma = NULL;
- }
-
- if (ring->dma_pdma) {
- dma_free_coherent(eth->dma_dev,
-- ring->dma_size * soc->txrx.txd_size,
-+ ring->dma_size * soc->tx.desc_size,
- ring->dma_pdma, ring->phys_pdma);
- ring->dma_pdma = NULL;
- }
-@@ -2790,15 +2790,15 @@ static int mtk_rx_alloc(struct mtk_eth *
- 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);
-+ rx_dma_size * eth->soc->rx.desc_size,
-+ &ring->phys, GFP_KERNEL);
- } else {
- struct mtk_tx_ring *tx_ring = ð->tx_ring;
-
- ring->dma = tx_ring->dma + tx_ring_size *
-- eth->soc->txrx.txd_size * (ring_no + 1);
-+ eth->soc->tx.desc_size * (ring_no + 1);
- ring->phys = tx_ring->phys + tx_ring_size *
-- eth->soc->txrx.txd_size * (ring_no + 1);
-+ eth->soc->tx.desc_size * (ring_no + 1);
- }
-
- if (!ring->dma)
-@@ -2809,7 +2809,7 @@ static int mtk_rx_alloc(struct mtk_eth *
- dma_addr_t dma_addr;
- void *data;
-
-- rxd = ring->dma + i * eth->soc->txrx.rxd_size;
-+ rxd = ring->dma + i * eth->soc->rx.desc_size;
- if (ring->page_pool) {
- data = mtk_page_pool_get_buff(ring->page_pool,
- &dma_addr, GFP_KERNEL);
-@@ -2900,7 +2900,7 @@ static void mtk_rx_clean(struct mtk_eth
- if (!ring->data[i])
- continue;
-
-- rxd = ring->dma + i * eth->soc->txrx.rxd_size;
-+ rxd = ring->dma + i * eth->soc->rx.desc_size;
- if (!rxd->rxd1)
- continue;
-
-@@ -2917,7 +2917,7 @@ static void mtk_rx_clean(struct mtk_eth
-
- if (!in_sram && ring->dma) {
- dma_free_coherent(eth->dma_dev,
-- ring->dma_size * eth->soc->txrx.rxd_size,
-+ ring->dma_size * eth->soc->rx.desc_size,
- ring->dma, ring->phys);
- ring->dma = NULL;
- }
-@@ -3280,7 +3280,7 @@ static void mtk_dma_free(struct mtk_eth
- 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->txrx.txd_size,
-+ MTK_QDMA_RING_SIZE * soc->tx.desc_size,
- eth->scratch_ring, eth->phy_scratch_ring);
- eth->scratch_ring = NULL;
- eth->phy_scratch_ring = 0;
-@@ -3330,7 +3330,7 @@ static irqreturn_t mtk_handle_irq_rx(int
-
- eth->rx_events++;
- if (likely(napi_schedule_prep(ð->rx_napi))) {
-- mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
-+ mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
- __napi_schedule(ð->rx_napi);
- }
-
-@@ -3356,9 +3356,9 @@ static irqreturn_t mtk_handle_irq(int ir
- const struct mtk_reg_map *reg_map = eth->soc->reg_map;
-
- if (mtk_r32(eth, reg_map->pdma.irq_mask) &
-- eth->soc->txrx.rx_irq_done_mask) {
-+ eth->soc->rx.irq_done_mask) {
- if (mtk_r32(eth, reg_map->pdma.irq_status) &
-- eth->soc->txrx.rx_irq_done_mask)
-+ eth->soc->rx.irq_done_mask)
- mtk_handle_irq_rx(irq, _eth);
- }
- if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) {
-@@ -3376,10 +3376,10 @@ 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, eth->soc->txrx.rx_irq_done_mask);
-+ mtk_rx_irq_disable(eth, eth->soc->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, eth->soc->txrx.rx_irq_done_mask);
-+ mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
- }
- #endif
-
-@@ -3545,7 +3545,7 @@ static int mtk_open(struct net_device *d
- napi_enable(ð->tx_napi);
- napi_enable(ð->rx_napi);
- mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
-- mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask);
-+ mtk_rx_irq_enable(eth, soc->rx.irq_done_mask);
- refcount_set(ð->dma_refcnt, 1);
- }
- else
-@@ -3628,7 +3628,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, eth->soc->txrx.rx_irq_done_mask);
-+ mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
- napi_disable(ð->tx_napi);
- napi_disable(ð->rx_napi);
-
-@@ -4107,9 +4107,9 @@ 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, eth->soc->txrx.rx_irq_done_mask, reg_map->pdma.int_grp + 4);
-+ mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->pdma.int_grp + 4);
- mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp);
-- mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
-+ mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->qdma.int_grp + 4);
- mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
-
- if (mtk_is_netsys_v3_or_greater(eth)) {
-@@ -5270,11 +5270,15 @@ static const struct mtk_soc_data mt2701_
- .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),
-- .rx_irq_done_mask = MTK_RX_DONE_INT,
-- .rx_dma_l4_valid = RX_DMA_L4_VALID,
-+ .tx = {
-+ .desc_size = sizeof(struct mtk_tx_dma),
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
-+ },
-+ .rx = {
-+ .desc_size = sizeof(struct mtk_rx_dma),
-+ .irq_done_mask = MTK_RX_DONE_INT,
-+ .dma_l4_valid = RX_DMA_L4_VALID,
- .dma_max_len = MTK_TX_DMA_BUF_LEN,
- .dma_len_offset = 16,
- },
-@@ -5290,11 +5294,15 @@ static const struct mtk_soc_data mt7621_
- .offload_version = 1,
- .hash_offset = 2,
- .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-- .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,
-+ .tx = {
-+ .desc_size = sizeof(struct mtk_tx_dma),
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
-+ },
-+ .rx = {
-+ .desc_size = sizeof(struct mtk_rx_dma),
-+ .irq_done_mask = MTK_RX_DONE_INT,
-+ .dma_l4_valid = RX_DMA_L4_VALID,
- .dma_max_len = MTK_TX_DMA_BUF_LEN,
- .dma_len_offset = 16,
- },
-@@ -5312,11 +5320,15 @@ static const struct mtk_soc_data mt7622_
- .hash_offset = 2,
- .has_accounting = true,
- .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-- .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,
-+ .tx = {
-+ .desc_size = sizeof(struct mtk_tx_dma),
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
-+ },
-+ .rx = {
-+ .desc_size = sizeof(struct mtk_rx_dma),
-+ .irq_done_mask = MTK_RX_DONE_INT,
-+ .dma_l4_valid = RX_DMA_L4_VALID,
- .dma_max_len = MTK_TX_DMA_BUF_LEN,
- .dma_len_offset = 16,
- },
-@@ -5333,11 +5345,15 @@ static const struct mtk_soc_data mt7623_
- .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),
-- .rx_irq_done_mask = MTK_RX_DONE_INT,
-- .rx_dma_l4_valid = RX_DMA_L4_VALID,
-+ .tx = {
-+ .desc_size = sizeof(struct mtk_tx_dma),
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
-+ },
-+ .rx = {
-+ .desc_size = sizeof(struct mtk_rx_dma),
-+ .irq_done_mask = MTK_RX_DONE_INT,
-+ .dma_l4_valid = RX_DMA_L4_VALID,
- .dma_max_len = MTK_TX_DMA_BUF_LEN,
- .dma_len_offset = 16,
- },
-@@ -5352,11 +5368,15 @@ static const struct mtk_soc_data mt7629_
- .required_pctl = false,
- .has_accounting = true,
- .version = 1,
-- .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,
-+ .tx = {
-+ .desc_size = sizeof(struct mtk_tx_dma),
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
-+ },
-+ .rx = {
-+ .desc_size = sizeof(struct mtk_rx_dma),
-+ .irq_done_mask = MTK_RX_DONE_INT,
-+ .dma_l4_valid = RX_DMA_L4_VALID,
- .dma_max_len = MTK_TX_DMA_BUF_LEN,
- .dma_len_offset = 16,
- },
-@@ -5374,11 +5394,15 @@ static const struct mtk_soc_data mt7981_
- .hash_offset = 4,
- .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),
-- .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-- .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
-+ .tx = {
-+ .desc_size = sizeof(struct mtk_tx_dma_v2),
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+ .dma_len_offset = 8,
-+ },
-+ .rx = {
-+ .desc_size = sizeof(struct mtk_rx_dma_v2),
-+ .irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .dma_l4_valid = RX_DMA_L4_VALID_V2,
- .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
- .dma_len_offset = 8,
- },
-@@ -5396,11 +5420,15 @@ static const struct mtk_soc_data mt7986_
- .hash_offset = 4,
- .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),
-- .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-- .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
-+ .tx = {
-+ .desc_size = sizeof(struct mtk_tx_dma_v2),
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+ .dma_len_offset = 8,
-+ },
-+ .rx = {
-+ .desc_size = sizeof(struct mtk_rx_dma_v2),
-+ .irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .dma_l4_valid = RX_DMA_L4_VALID_V2,
- .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
- .dma_len_offset = 8,
- },
-@@ -5418,11 +5446,15 @@ static const struct mtk_soc_data mt7988_
- .hash_offset = 4,
- .has_accounting = true,
- .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),
-- .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-- .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
-+ .tx = {
-+ .desc_size = sizeof(struct mtk_tx_dma_v2),
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+ .dma_len_offset = 8,
-+ },
-+ .rx = {
-+ .desc_size = sizeof(struct mtk_rx_dma_v2),
-+ .irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .dma_l4_valid = RX_DMA_L4_VALID_V2,
- .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
- .dma_len_offset = 8,
- },
-@@ -5435,11 +5467,15 @@ static const struct mtk_soc_data rt5350_
- .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),
-- .rx_irq_done_mask = MTK_RX_DONE_INT,
-- .rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA,
-+ .tx = {
-+ .desc_size = sizeof(struct mtk_tx_dma),
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
-+ },
-+ .rx = {
-+ .desc_size = sizeof(struct mtk_rx_dma),
-+ .irq_done_mask = MTK_RX_DONE_INT,
-+ .dma_l4_valid = RX_DMA_L4_VALID_PDMA,
- .dma_max_len = MTK_TX_DMA_BUF_LEN,
- .dma_len_offset = 16,
- },
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -327,8 +327,8 @@
- /* QDMA descriptor txd3 */
- #define TX_DMA_OWNER_CPU BIT(31)
- #define TX_DMA_LS0 BIT(30)
--#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_PLEN0(x) (((x) & eth->soc->tx.dma_max_len) << eth->soc->tx.dma_len_offset)
-+#define TX_DMA_PLEN1(x) ((x) & eth->soc->tx.dma_max_len)
- #define TX_DMA_SWC BIT(14)
- #define TX_DMA_PQID GENMASK(3, 0)
- #define TX_DMA_ADDR64_MASK GENMASK(3, 0)
-@@ -348,8 +348,8 @@
- /* QDMA descriptor rxd2 */
- #define RX_DMA_DONE BIT(31)
- #define RX_DMA_LSO BIT(30)
--#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_PREP_PLEN0(x) (((x) & eth->soc->rx.dma_max_len) << eth->soc->rx.dma_len_offset)
-+#define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->rx.dma_len_offset) & eth->soc->rx.dma_max_len)
- #define RX_DMA_VTAG BIT(15)
- #define RX_DMA_ADDR64_MASK GENMASK(3, 0)
- #if IS_ENABLED(CONFIG_64BIT)
-@@ -1209,10 +1209,9 @@ struct mtk_reg_map {
- * @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.
-- * @rx_dma_l4_valid Rx DMA valid register mask.
-+ * @desc_size Tx/Rx DMA descriptor size.
-+ * @irq_done_mask Rx irq done register mask.
-+ * @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.
- */
-@@ -1230,13 +1229,17 @@ struct mtk_soc_data {
- bool has_accounting;
- bool disable_pll_modes;
- struct {
-- u32 txd_size;
-- u32 rxd_size;
-- u32 rx_irq_done_mask;
-- u32 rx_dma_l4_valid;
-+ u32 desc_size;
- u32 dma_max_len;
- u32 dma_len_offset;
-- } txrx;
-+ } tx;
-+ struct {
-+ u32 desc_size;
-+ u32 irq_done_mask;
-+ u32 dma_l4_valid;
-+ u32 dma_max_len;
-+ u32 dma_len_offset;
-+ } rx;
- };
-
- #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
+++ /dev/null
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 10 Oct 2023 21:06:43 +0200
-Subject: [PATCH net-next 2/2] net: ethernet: mediatek: use QDMA instead of
- ADMAv2 on MT7981 and MT7986
-
-ADMA is plagued by RX hangs which can't easily detected and happen upon
-receival of a corrupted package.
-Use QDMA just like on netsys v1 which is also still present and usable, and
-doesn't suffer from that problem.
-
-Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 46 ++++++++++-----------
- 1 file changed, 23 insertions(+), 23 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -110,16 +110,16 @@ static const struct mtk_reg_map mt7986_r
- .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,
-- .adma_rx_dbg0 = 0x6238,
-- .int_grp = 0x6250,
-+ .rx_ptr = 0x4100,
-+ .rx_cnt_cfg = 0x4104,
-+ .pcrx_ptr = 0x4108,
-+ .glo_cfg = 0x4204,
-+ .rst_idx = 0x4208,
-+ .delay_irq = 0x420c,
-+ .irq_status = 0x4220,
-+ .irq_mask = 0x4228,
-+ .adma_rx_dbg0 = 0x4238,
-+ .int_grp = 0x4250,
- },
- .qdma = {
- .qtx_cfg = 0x4400,
-@@ -1232,7 +1232,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_is_netsys_v2_or_greater(eth)) {
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
- rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
- rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
- }
-@@ -2184,7 +2184,7 @@ 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)) {
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
- u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
-
- switch (val) {
-@@ -2296,7 +2296,7 @@ static int mtk_poll_rx(struct napi_struc
- skb->dev = netdev;
- bytes += skb->len;
-
-- if (mtk_is_netsys_v2_or_greater(eth)) {
-+ if (mtk_is_netsys_v3_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)
-@@ -2846,7 +2846,7 @@ static int mtk_rx_alloc(struct mtk_eth *
-
- rxd->rxd3 = 0;
- rxd->rxd4 = 0;
-- if (mtk_is_netsys_v2_or_greater(eth)) {
-+ if (mtk_is_netsys_v3_or_greater(eth)) {
- rxd->rxd5 = 0;
- rxd->rxd6 = 0;
- rxd->rxd7 = 0;
-@@ -4053,7 +4053,7 @@ static int mtk_hw_init(struct mtk_eth *e
- else
- mtk_hw_reset(eth);
-
-- if (mtk_is_netsys_v2_or_greater(eth)) {
-+ if (mtk_is_netsys_v3_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);
-@@ -5400,11 +5400,11 @@ static const struct mtk_soc_data mt7981_
- .dma_len_offset = 8,
- },
- .rx = {
-- .desc_size = sizeof(struct mtk_rx_dma_v2),
-- .irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .desc_size = sizeof(struct mtk_rx_dma),
-+ .irq_done_mask = MTK_RX_DONE_INT,
- .dma_l4_valid = RX_DMA_L4_VALID_V2,
-- .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-- .dma_len_offset = 8,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
- },
- };
-
-@@ -5426,11 +5426,11 @@ static const struct mtk_soc_data mt7986_
- .dma_len_offset = 8,
- },
- .rx = {
-- .desc_size = sizeof(struct mtk_rx_dma_v2),
-- .irq_done_mask = MTK_RX_DONE_INT_V2,
-+ .desc_size = sizeof(struct mtk_rx_dma),
-+ .irq_done_mask = MTK_RX_DONE_INT,
- .dma_l4_valid = RX_DMA_L4_VALID_V2,
-- .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-- .dma_len_offset = 8,
-+ .dma_max_len = MTK_TX_DMA_BUF_LEN,
-+ .dma_len_offset = 16,
- },
- };
-
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 18 Jan 2024 12:51:32 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix WED + wifi reset
-
-The WLAN + WED reset sequence relies on being able to receive interrupts from
-the card, in order to synchronize individual steps with the firmware.
-When WED is stopped, leave interrupts running and rely on the driver turning
-off unwanted ones.
-WED DMA also needs to be disabled before resetting.
-
-Fixes: f78cd9c783e0 ("net: ethernet: mtk_wed: update mtk_wed_stop")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -1071,13 +1071,13 @@ 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_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);
-
- if (!mtk_wed_get_rx_capa(dev))
- return;
-@@ -1090,7 +1090,6 @@ 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 |
-@@ -2621,9 +2620,6 @@ mtk_wed_irq_get(struct mtk_wed_device *d
- 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);
- }
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -578,6 +578,7 @@
+@@ -575,6 +575,7 @@
compatible = "mediatek,mt7622-nor",
"mediatek,mt8173-nor";
reg = <0 0x11014000 0 0xe0>;
chosen {
stdout-path = "serial2:115200n8";
- bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
-+ bootargs = "root=/dev/fit0 earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
++ bootargs = "root=/dev/fit0 rootwait earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
+ rootdisk-emmc = <&emmc_rootdisk>;
+ rootdisk-sd = <&sd_rootdisk>;
};
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -347,7 +347,7 @@
+@@ -345,7 +345,7 @@
#interrupt-cells = <3>;
interrupt-parent = <&gic>;
reg = <0 0x10310000 0 0x1000>,
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -849,6 +849,12 @@
+@@ -844,6 +844,12 @@
#address-cells = <0>;
#interrupt-cells = <1>;
};
};
pcie1: pcie@1a145000 {
-@@ -887,6 +893,12 @@
+@@ -882,6 +888,12 @@
#address-cells = <0>;
#interrupt-cells = <1>;
};
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -837,6 +837,9 @@
+@@ -832,6 +832,9 @@
bus-range = <0x00 0xff>;
ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
status = "disabled";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
-@@ -881,6 +884,9 @@
+@@ -876,6 +879,9 @@
bus-range = <0x00 0xff>;
ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
status = "disabled";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
+@@ -937,7 +943,7 @@
+ };
+
+ hifsys: clock-controller@1af00000 {
+- compatible = "mediatek,mt7622-hifsys";
++ compatible = "mediatek,mt7622-hifsys", "syscon";
+ reg = <0 0x1af00000 0 0x70>;
+ #clock-cells = <1>;
+ };
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -20,6 +20,7 @@
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
-@@ -248,6 +248,28 @@
- status = "disabled";
+@@ -202,6 +202,28 @@
+ #interrupt-cells = <2>;
};
+ afe: audio-controller@11210000 {
-
};
- timer {
-@@ -543,10 +537,11 @@
+ soc {
+@@ -532,10 +526,11 @@
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>,
};
wed1: wed@15011000 {
-@@ -556,10 +551,11 @@
+@@ -545,10 +540,11 @@
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>,
+ mediatek,wo-cpuboot = <&wo_cpuboot>;
};
- wo_ccif0: syscon@151a5000 {
-@@ -576,6 +572,11 @@
+ eth: ethernet@15100000 {
+@@ -606,6 +602,11 @@
interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
};
+ reg = <0 0x15194000 0 0x1000>;
+ };
+
- eth: ethernet@15100000 {
- compatible = "mediatek,mt7986-eth";
- reg = <0 0x15100000 0 0x80000>;
+ wifi: wifi@18000000 {
+ compatible = "mediatek,mt7986-wmac";
+ reg = <0 0x18000000 0 0x1000000>,
wo_data: wo-data@4fd80000 {
reg = <0 0x4fd80000 0 0x240000>;
no-map;
-@@ -536,11 +526,10 @@
+@@ -525,11 +515,10 @@
reg = <0 0x15010000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
mediatek,wo-cpuboot = <&wo_cpuboot>;
};
-@@ -550,11 +539,10 @@
+@@ -539,11 +528,10 @@
reg = <0 0x15011000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
mediatek,wo-cpuboot = <&wo_cpuboot>;
};
-@@ -572,6 +560,16 @@
+@@ -602,6 +590,16 @@
interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
};
- };
};
- timer {
-@@ -526,10 +516,11 @@
+ soc {
+@@ -515,10 +505,11 @@
reg = <0 0x15010000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
mediatek,wo-cpuboot = <&wo_cpuboot>;
};
-@@ -539,10 +530,11 @@
+@@ -528,10 +519,11 @@
reg = <0 0x15011000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
mediatek,wo-cpuboot = <&wo_cpuboot>;
};
-@@ -570,6 +562,16 @@
+@@ -600,6 +592,16 @@
reg = <0 0x151f0000 0 0x8000>;
};
FEATURES:=fpu usb pci pcie gpio nand squashfs ramdisk boot-part rootfs-part legacy-sdcard targz
SUBTARGETS:=cortexa9 cortexa53 cortexa72
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
+++ /dev/null
-CONFIG_AHCI_MVEBU=y
-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_MVEBU=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_ARMADA_370_CLK=y
-CONFIG_ARMADA_370_XP_IRQ=y
-CONFIG_ARMADA_370_XP_TIMER=y
-# CONFIG_ARMADA_37XX_WATCHDOG is not set
-CONFIG_ARMADA_38X_CLK=y
-CONFIG_ARMADA_THERMAL=y
-CONFIG_ARMADA_XP_CLK=y
-CONFIG_ARM_APPENDED_DTB=y
-# CONFIG_ARM_ARMADA_37XX_CPUFREQ is not set
-# CONFIG_ARM_ARMADA_8K_CPUFREQ is not set
-CONFIG_ARM_ATAG_DTB_COMPAT=y
-# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_ERRATA_720789=y
-CONFIG_ARM_ERRATA_764369=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GLOBAL_TIMER=y
-CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=1
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_MVEBU_V7_CPUIDLE=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_ASYNC_TX_ENABLE_CHANNEL_SWITCH=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_LOOP=y
-CONFIG_BLK_DEV_NVME=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BOUNCE=y
-# CONFIG_CACHE_FEROCEON_L2 is not set
-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_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_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_USERSPACE is not set
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PJ4B=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_CRYPTO_AES_ARM=y
-CONFIG_CRYPTO_AES_ARM_BS=y
-CONFIG_CRYPTO_AUTHENC=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEV_MARVELL=y
-CONFIG_CRYPTO_DEV_MARVELL_CESA=y
-CONFIG_CRYPTO_ESSIV=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_SHA1=y
-CONFIG_CRYPTO_SHA1_ARM=y
-CONFIG_CRYPTO_SHA1_ARM_NEON=y
-CONFIG_CRYPTO_SHA256_ARM=y
-CONFIG_CRYPTO_SHA512_ARM=y
-CONFIG_CRYPTO_SIMD=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_ALIGN_RODATA=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
-CONFIG_DEBUG_MVEBU_UART0=y
-# CONFIG_DEBUG_MVEBU_UART0_ALTERNATE is not set
-# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set
-CONFIG_DEBUG_UART_8250=y
-CONFIG_DEBUG_UART_8250_SHIFT=2
-CONFIG_DEBUG_UART_PHYS=0xd0012000
-CONFIG_DEBUG_UART_VIRT=0xfec12000
-CONFIG_DEBUG_USER=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_ENGINE_RAID=y
-CONFIG_DMA_OF=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_EXT4_FS=y
-CONFIG_EXTCON=y
-CONFIG_F2FS_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_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_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_MVEBU=y
-CONFIG_GPIO_PCA953X=y
-CONFIG_GPIO_PCA953X_IRQ=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_HOTPLUG_CPU=y
-CONFIG_HWBM=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_MV64XXX=y
-# CONFIG_I2C_PXA 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_WORK=y
-# CONFIG_IWMMXT is not set
-CONFIG_JBD2=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_PCA963X=y
-CONFIG_LEDS_TLC591XX=y
-CONFIG_LEDS_TRIGGER_DISK=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACH_ARMADA_370=y
-# CONFIG_MACH_ARMADA_375 is not set
-CONFIG_MACH_ARMADA_38X=y
-# CONFIG_MACH_ARMADA_39X is not set
-CONFIG_MACH_ARMADA_XP=y
-# CONFIG_MACH_DOVE is not set
-CONFIG_MACH_MVEBU_ANY=y
-CONFIG_MACH_MVEBU_V7=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MANGLE_BOOTARGS=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MDIO_I2C=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_MVSDIO=y
-CONFIG_MMC_SDHCI=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMC_SDHCI_PXAV3=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_CFI_STAA=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_MARVELL=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_FIRMWARE=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_MVEBU_CLK_COMMON=y
-CONFIG_MVEBU_CLK_COREDIV=y
-CONFIG_MVEBU_CLK_CPU=y
-CONFIG_MVEBU_DEVBUS=y
-CONFIG_MVEBU_MBUS=y
-CONFIG_MVMDIO=y
-CONFIG_MVNETA=y
-CONFIG_MVNETA_BM=y
-CONFIG_MVNETA_BM_ENABLE=y
-# CONFIG_MVPP2 is not set
-CONFIG_MV_XOR=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEON=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_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NOP_USB_XCEIV=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-CONFIG_NVME_CORE=y
-# CONFIG_NVME_HWMON is not set
-# CONFIG_NVME_MULTIPATH is not set
-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_WATCHDOG=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_POOL_STATS=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_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCI_MVEBU=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_MVEBU_A3700_COMPHY is not set
-# CONFIG_PHY_MVEBU_A3700_UTMI is not set
-# CONFIG_PHY_MVEBU_A38X_COMPHY is not set
-# CONFIG_PHY_MVEBU_CP110_COMPHY is not set
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_ARMADA_370=y
-CONFIG_PINCTRL_ARMADA_38X=y
-CONFIG_PINCTRL_ARMADA_XP=y
-CONFIG_PINCTRL_MVEBU=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PJ4B_ERRATA_4742=y
-CONFIG_PL310_ERRATA_753970=y
-CONFIG_PLAT_ORION=y
-CONFIG_PM_OPP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=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_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_ARMADA38X=y
-# CONFIG_RTC_DRV_MV is not set
-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_SATA_MV=y
-CONFIG_SATA_PMP=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SENSORS_PWM_FAN=y
-CONFIG_SENSORS_TMP421=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_MVEBU_CONSOLE=y
-CONFIG_SERIAL_MVEBU_UART=y
-CONFIG_SFP=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_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_SRAM=y
-CONFIG_SRAM_EXEC=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_HWMON=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=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_ORION=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-CONFIG_USB_LEDS_TRIGGER_USBPORT=y
-CONFIG_USB_PHY=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_MVEBU=y
-CONFIG_USB_XHCI_PLATFORM=y
-CONFIG_USE_OF=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-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
+++ /dev/null
-CONFIG_64BIT=y
-CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
-CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=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_STACKWALK=y
-CONFIG_ARCH_WANTS_NO_INSTR=y
-CONFIG_ARCH_WANTS_THP_SWAP=y
-CONFIG_ARM64=y
-CONFIG_ARM64_4K_PAGES=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_TAGGED_ADDR_ABI=y
-CONFIG_ARM64_VA_BITS=39
-CONFIG_ARM64_VA_BITS_39=y
-CONFIG_ARMADA_37XX_CLK=y
-CONFIG_ARMADA_37XX_RWTM_MBOX=y
-CONFIG_ARMADA_37XX_WATCHDOG=y
-CONFIG_ARMADA_AP806_SYSCON=y
-CONFIG_ARMADA_AP_CP_HELPER=y
-CONFIG_ARMADA_CP110_SYSCON=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_ARCH_TIMER=y
-# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
-CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
-CONFIG_ARM_GIC_V2M=y
-CONFIG_ARM_GIC_V3=y
-CONFIG_ARM_GIC_V3_ITS=y
-CONFIG_ARM_GIC_V3_ITS_PCI=y
-# CONFIG_ARM_MHU_V2 is not set
-# CONFIG_ARM_PL172_MPMC is not set
-CONFIG_ARM_PSCI_FW=y
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
-CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_FRAME_POINTER=y
-CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_CSUM=y
-CONFIG_GENERIC_IOREMAP=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_MAILBOX=y
-# CONFIG_MAILBOX_TEST is not set
-CONFIG_MFD_SYSCON=y
-# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
-CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MVEBU_GICP=y
-CONFIG_MVEBU_ICU=y
-CONFIG_MVEBU_ODMI=y
-CONFIG_MVEBU_PIC=y
-CONFIG_MVEBU_SEI=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_PARTITION_PERCPU=y
-CONFIG_PCI_AARDVARK=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PHY_MVEBU_A3700_COMPHY=y
-CONFIG_PHY_MVEBU_A3700_UTMI=y
-CONFIG_PINCTRL_AC5=y
-CONFIG_PINCTRL_ARMADA_37XX=y
-CONFIG_PINCTRL_ARMADA_AP806=y
-CONFIG_PINCTRL_ARMADA_CP110=y
-CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_REGULATOR_GPIO=y
-CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
-CONFIG_SPARSEMEM=y
-CONFIG_SPARSEMEM_EXTREME=y
-CONFIG_SPARSEMEM_VMEMMAP=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPI_ARMADA_3700=y
-CONFIG_SWIOTLB=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
-CONFIG_TURRIS_MOX_RWTM=y
-CONFIG_UNMAP_KERNEL_AT_EL0=y
-CONFIG_VMAP_STACK=y
-CONFIG_ZONE_DMA32=y
+++ /dev/null
-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_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_STACKWALK=y
-CONFIG_ARCH_WANTS_NO_INSTR=y
-CONFIG_ARCH_WANTS_THP_SWAP=y
-CONFIG_ARM64=y
-CONFIG_ARM64_4K_PAGES=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_SVE=y
-# CONFIG_ARM64_TAGGED_ADDR_ABI is not set
-CONFIG_ARM64_VA_BITS=39
-CONFIG_ARM64_VA_BITS_39=y
-CONFIG_ARMADA_37XX_CLK=y
-CONFIG_ARMADA_AP806_SYSCON=y
-CONFIG_ARMADA_AP_CPU_CLK=y
-CONFIG_ARMADA_AP_CP_HELPER=y
-CONFIG_ARMADA_CP110_SYSCON=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_ARCH_TIMER=y
-# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set
-CONFIG_ARM_ARMADA_8K_CPUFREQ=y
-CONFIG_ARM_GIC_V2M=y
-CONFIG_ARM_GIC_V3=y
-CONFIG_ARM_GIC_V3_ITS=y
-CONFIG_ARM_GIC_V3_ITS_PCI=y
-# CONFIG_ARM_PL172_MPMC is not set
-CONFIG_ARM_PSCI_FW=y
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
-CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CRC_CCITT=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_EEPROM_AT24=y
-CONFIG_FRAME_POINTER=y
-CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_CSUM=y
-CONFIG_GENERIC_IOREMAP=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_HW_RANDOM_OMAP=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_LEDS_IEI_WT61P803_PUZZLE=y
-CONFIG_LEDS_IS31FL319X=y
-CONFIG_MARVELL_10G_PHY=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_IEI_WT61P803_PUZZLE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MMC_SDHCI_XENON=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MVEBU_GICP=y
-CONFIG_MVEBU_ICU=y
-CONFIG_MVEBU_ODMI=y
-CONFIG_MVEBU_PIC=y
-CONFIG_MVEBU_SEI=y
-CONFIG_MVPP2=y
-CONFIG_MV_XOR_V2=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_NVMEM_LAYOUT_ONIE_TLV=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_PARTITION_PERCPU=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_ARMADA_8K=y
-CONFIG_PCIE_DW=y
-CONFIG_PCIE_DW_HOST=y
-# CONFIG_PCI_AARDVARK is not set
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PHY_MVEBU_CP110_COMPHY=y
-CONFIG_PHY_MVEBU_CP110_UTMI=y
-CONFIG_PINCTRL_AC5=y
-CONFIG_PINCTRL_ARMADA_37XX=y
-CONFIG_PINCTRL_ARMADA_AP806=y
-CONFIG_PINCTRL_ARMADA_CP110=y
-CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RAS=y
-# CONFIG_RAVE_SP_CORE is not set
-CONFIG_REGULATOR_GPIO=y
-# CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set
-CONFIG_SENSORS_IEI_WT61P803_PUZZLE_HWMON=y
-CONFIG_SERIAL_DEV_BUS=y
-CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
-CONFIG_SPARSEMEM=y
-CONFIG_SPARSEMEM_EXTREME=y
-CONFIG_SPARSEMEM_VMEMMAP=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SWIOTLB=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
-CONFIG_UNMAP_KERNEL_AT_EL0=y
-CONFIG_VMAP_STACK=y
-CONFIG_ZONE_DMA32=y
+++ /dev/null
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_IRQSTACKS=y
-CONFIG_LED_TRIGGER_PHY=y
-CONFIG_MTD_SPLIT_SEIL_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_MTD_VIRT_CONCAT=y
-CONFIG_PHY_MVEBU_A38X_COMPHY=y
-CONFIG_POWER_RESET_QNAP=y
-CONFIG_RTC_DRV_MV=y
-CONFIG_THREAD_INFO_IN_TASK=y
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
-/*
- * Device Tree file for Buffalo LinkStation LS220DE
- *
- * Copyright (C) 2023 Daniel González Cabanelas <dgcbueu@gmail.com>
- */
-
-/dts-v1/;
-
-#include "armada-370.dtsi"
-#include "mvebu-linkstation-fan.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/thermal/thermal.h>
-
-/ {
- model = "Buffalo LinkStation LS220DE";
- compatible = "buffalo,ls220de", "marvell,armada370", "marvell,armada-370-xp";
-
- aliases {
- led-boot = &led_boot;
- led-failsafe = &led_failsafe;
- led-running = &led_power;
- led-upgrade = &led_upgrade;
- };
-
- chosen {
- bootargs = "earlycon";
- stdout-path = "serial0:115200n8";
- append-rootblock = "nullparameter="; /* override the bootloader args */
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>; /* 256 MB */
- };
-
- soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
- MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
- };
-
- system_fan: gpio_fan {
- gpios = <&gpio0 13 GPIO_ACTIVE_HIGH
- &gpio0 14 GPIO_ACTIVE_HIGH>;
- alarm-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
-
- #cooling-cells = <2>;
- };
-
- thermal-zones {
- hdd-thermal {
- polling-delay = <20000>;
- polling-delay-passive = <2000>;
-
- thermal-sensors = <&hdd0_temp>; /* only one drivetemp sensor is supported */
-
- trips {
- hdd_alert1: trip1 {
- temperature = <34000>;
- hysteresis = <2000>;
- type = "active";
- };
- hdd_alert2: trip2 {
- temperature = <40000>;
- hysteresis = <2000>;
- type = "active";
- };
- hdd_alert3: trip3 {
- temperature = <45000>;
- hysteresis = <2000>;
- type = "passive";
- };
- hdd_hot {
- temperature = <50000>;
- hysteresis = <2000>;
- type = "hot";
- };
- hdd_crit {
- temperature = <60000>;
- hysteresis = <2000>;
- type = "critical";
- };
- };
-
- cooling-maps {
- map1 {
- trip = <&hdd_alert1>;
- cooling-device = <&system_fan THERMAL_NO_LIMIT 1>;
- };
- map2 {
- trip = <&hdd_alert2>;
- cooling-device = <&system_fan 2 2>;
- };
- map3 {
- trip = <&hdd_alert3>;
- cooling-device = <&system_fan 3 THERMAL_NO_LIMIT>;
- };
- };
- };
- };
-
- gpio_keys {
- compatible = "gpio-keys";
- pinctrl-0 = <&pmx_buttons>;
- pinctrl-names = "default";
-
- power {
- label = "Power Switch";
- linux,code = <KEY_POWER>;
- linux,input-type = <EV_SW>;
- gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
- };
-
- function {
- label = "Function Button";
- linux,code = <KEY_CONFIG>;
- gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio_leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&pmx_leds1 &pmx_leds2>;
-
- indicator_red {
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
- panic-indicator;
- };
-
- led_power: power_white {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_WHITE>;
- gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
-
- led_failsafe: power_red {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
- };
-
- led_upgrade: power_orange {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
- };
-
- led_boot: indicator_white {
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_WHITE>;
- gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
- };
-
- hdd1_red {
- function = LED_FUNCTION_DISK;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "ata1";
- function-enumerator = <1>;
- };
-
- hdd2_red {
- function = LED_FUNCTION_DISK;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "ata2";
- function-enumerator = <2>;
- };
- };
-
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-0 = <&pmx_power_hdd1 &pmx_power_hdd2>;
- pinctrl-names = "default";
-
- sata1_power: regulator@1 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "HDD1";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- startup-delay-us = <2000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio0 8 GPIO_ACTIVE_HIGH>;
- };
-
- sata2_power: regulator@2 {
- compatible = "regulator-fixed";
- reg = <2>;
- regulator-name = "HDD2";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- startup-delay-us = <4000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio0 2 GPIO_ACTIVE_HIGH>;
- };
- };
-};
-
-&coherencyfab {
- broken-idle;
-};
-
-ð1 {
- pinctrl-0 = <&ge1_rgmii_pins>;
- pinctrl-names = "default";
- status = "okay";
- phy-handle = <ðphy0>;
- phy-connection-type = "rgmii-id";
-};
-
-&mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
-
- ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
- reg = <0>;
- marvell,reg-init = <0x3 0x10 0xf000 0x091A>, /* LED function */
- <0x3 0x11 0x0000 0x4401>, /* LED polarity */
- <0x3 0x12 0x0000 0x4905>; /* LED timer */
- #thermal-sensor-cells = <0>;
- };
-};
-
-&nand_controller {
- status = "okay";
-
- nand@0 {
- reg = <0>;
- label = "pxa3xx_nand-0";
- nand-rb = <0>;
- marvell,nand-keep-config;
- nand-on-flash-bbt;
- nand-ecc-strength = <4>;
- nand-ecc-step-size = <512>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "ubi_kernel";
- reg = <0x00000000 0x02000000>; /* 32 MiB */
- };
-
- partition@2000000 {
- label = "ubi";
- reg = <0x02000000 0x1df00000>; /* 479 MiB */
- };
- };
- };
-};
-
-&sata {
- nr-ports = <2>;
- status = "okay";
- #address-cells = <1>;
- #size-cells = <0>;
-
- hdd0_temp: sata-port@0 {
- reg = <0>;
- #thermal-sensor-cells = <0>;
- };
-
- hdd1_temp: sata-port@1 {
- reg = <1>;
- #thermal-sensor-cells = <0>;
- };
-};
-
-&spi0 {
- status = "okay";
- pinctrl-0 = <&spi0_pins2>;
- pinctrl-names = "default";
-
- spi-flash@0 {
- compatible = "mxicy,mx25l8005", "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <50000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- reg = <0x00000 0xf0000>; /* 960 KiB*/
- label = "u-boot";
- read-only;
- };
- partition@f0000 {
- reg = <0xf0000 0x10000>; /* 64 KiB */
- label = "u-boot-env";
- };
- };
- };
-};
-
-&pmsu {
- pinctrl-0 = <&pmx_power_cpu>;
- pinctrl-names = "default";
-};
-
-&uart0 {
- status = "okay";
-};
-
-&usb0 {
- status = "okay";
-};
-
-&pinctrl {
- pmx_power_hdd2: pmx-power-hdd2 {
- marvell,pins = "mpp2";
- marvell,function = "gpio";
- };
-
- pmx_power_cpu: pmx-power-cpu {
- marvell,pins = "mpp4";
- marvell,function = "vdd";
- };
-
- pmx_power_hdd1: pmx-power-hdd1 {
- marvell,pins = "mpp8";
- marvell,function = "gpio";
- };
-
- pmx_fan_lock: pmx-fan-lock {
- marvell,pins = "mpp10";
- marvell,function = "gpio";
- };
-
- pmx_hdd_present: pmx-hdd-present {
- marvell,pins = "mpp11", "mpp12";
- marvell,function = "gpio";
- };
-
- pmx_fan_high: pmx-fan-high {
- marvell,pins = "mpp13";
- marvell,function = "gpio";
- };
-
- pmx_fan_low: pmx-fan-low {
- marvell,pins = "mpp14";
- marvell,function = "gpio";
- };
-
- pmx_buttons: pmx-buttons {
- marvell,pins = "mpp15", "mpp16";
- marvell,function = "gpio";
- };
-
- pmx_leds1: pmx-leds {
- marvell,pins = "mpp7", "mpp54", "mpp59", "mpp61";
- marvell,function = "gpo";
- };
-
- pmx_leds2: pmx-leds {
- marvell,pins = "mpp55", "mpp57", "mpp62";
- marvell,function = "gpio";
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
-/*
- * Device Tree file for Buffalo LinkStation LS421DE
- *
- * Copyright (C) 2020 Daniel González Cabanelas <dgcbueu@gmail.com>
- */
-
-/dts-v1/;
-
-#include "armada-370.dtsi"
-#include "mvebu-linkstation-fan.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/thermal/thermal.h>
-
-/ {
- model = "Buffalo LinkStation LS421DE";
- compatible = "buffalo,ls421de", "marvell,armada370", "marvell,armada-370-xp";
-
- aliases {
- led-boot = &led_boot;
- led-failsafe = &led_failsafe;
- led-running = &led_power;
- led-upgrade = &led_upgrade;
- };
-
- chosen {
- bootargs = "earlycon";
- stdout-path = "serial0:115200n8";
- append-rootblock = "nullparameter="; /* override the bootloader args */
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x20000000>; /* 512 MB */
- };
-
- soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
- MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
- };
-
- system_fan: gpio_fan {
- gpios = <&gpio0 13 GPIO_ACTIVE_HIGH
- &gpio0 14 GPIO_ACTIVE_HIGH>;
- alarm-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
-
- #cooling-cells = <2>;
- };
-
- thermal-zones {
- hdd-thermal {
- polling-delay = <20000>;
- polling-delay-passive = <2000>;
-
- thermal-sensors = <&hdd0_temp>; /* only one drivetemp sensor is supported */
-
- trips {
- hdd_alert1: trip1 {
- temperature = <36000>;
- hysteresis = <2000>;
- type = "active";
- };
- hdd_alert2: trip2 {
- temperature = <44000>;
- hysteresis = <2000>;
- type = "active";
- };
- hdd_alert3: trip3 {
- temperature = <52000>;
- hysteresis = <2000>;
- type = "passive";
- };
- hdd_crit: trip4 {
- temperature = <60000>;
- hysteresis = <2000>;
- type = "critical";
- };
- };
-
- cooling-maps {
- map1 {
- trip = <&hdd_alert1>;
- cooling-device = <&system_fan THERMAL_NO_LIMIT 1>;
- };
- map2 {
- trip = <&hdd_alert2>;
- cooling-device = <&system_fan 2 2>;
- };
- map3 {
- trip = <&hdd_alert3>;
- cooling-device = <&system_fan 3 THERMAL_NO_LIMIT>;
- };
- };
- };
-
- ethphy-thermal {
- polling-delay = <20000>;
- polling-delay-passive = <2000>;
-
- thermal-sensors = <ðphy0>;
-
- trips {
- ethphy_alert1: trip1 {
- temperature = <65000>;
- hysteresis = <4000>;
- type = "passive";
- };
-
- ethphy_crit: trip2 {
- temperature = <100000>;
- hysteresis = <2000>;
- type = "critical";
- };
- };
-
- cooling-maps {
- map1 {
- trip = <ðphy_alert1>;
- cooling-device = <&system_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
- };
-
- };
- };
- };
-
- gpio_keys {
- compatible = "gpio-keys";
- pinctrl-0 = <&pmx_buttons>;
- pinctrl-names = "default";
-
- power {
- label = "Power Switch";
- linux,code = <KEY_POWER>;
- linux,input-type = <EV_SW>;
- gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
- };
-
- function {
- label = "Function Button";
- linux,code = <KEY_CONFIG>;
- gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio_leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&pmx_leds1 &pmx_leds2>;
-
- system_red {
- label = "ls421de:red:system";
- gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
- };
-
- led_power: power_white {
- label = "ls421de:white:power";
- gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
-
- led_failsafe: power_red {
- label = "ls421de:red:power";
- gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
- };
-
- led_upgrade: power_orange {
- label = "ls421de:orange:power";
- gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
- };
-
- led_boot: system_white {
- label = "ls421de:white:system";
- gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
- };
-
- hdd1_red {
- label = "ls421de:red:hdd1";
- gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "ata1";
- };
-
- hdd2_red {
- label = "ls421de:red:hdd2";
- gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "ata2";
- };
- };
-
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-0 = <&pmx_power_usb &pmx_power_hdd1 &pmx_power_hdd2>;
- pinctrl-names = "default";
-
- usb_power: regulator@0 {
- compatible = "regulator-fixed";
- reg = <0>;
- regulator-name = "USB";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
- };
-
- sata1_power: regulator@1 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "HDD1";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- startup-delay-us = <2000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio0 8 GPIO_ACTIVE_HIGH>;
- };
-
- sata2_power: regulator@2 {
- compatible = "regulator-fixed";
- reg = <2>;
- regulator-name = "HDD2";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- startup-delay-us = <4000000>;
- enable-active-high;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>;
- };
- };
-};
-
-&coherencyfab {
- broken-idle;
-};
-
-ð1 {
- pinctrl-0 = <&ge1_rgmii_pins>;
- pinctrl-names = "default";
- status = "okay";
- phy-handle = <ðphy0>;
- phy-connection-type = "rgmii-id";
-};
-
-&i2c0 {
- pinctrl-0 = <&i2c0_pins>;
- pinctrl-names = "default";
- clock-frequency = <100000>;
- status = "okay";
-
- rs5c372a: rs5c372a@32 {
- compatible = "ricoh,rs5c372a";
- reg = <0x32>;
- wakeup-source;
- };
-};
-
-&mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
-
- ethphy0: ethernet-phy@0 { /* Marvell 88E1518 */
- reg = <0>;
- marvell,reg-init = <0x2 0x10 0xffff 0x0006>, /* disable CLK125 */
- <0x3 0x10 0x0000 0x1991>, /* LED function */
- <0x3 0x11 0x0000 0x4401>, /* LED polarity */
- <0x3 0x12 0x0000 0x4905>; /* LED timer */
- #thermal-sensor-cells = <0>;
- };
-};
-
-&pciec {
- status = "okay";
- pinctrl-0 = <&pmx_pcie>;
- pinctrl-names = "default";
-
- /* Connected to uPD720202 USB 3.0 Host */
- pcie@1,0 {
- status = "okay";
- };
-};
-
-&pmsu {
- pinctrl-0 = <&pmx_power_cpu>;
- pinctrl-names = "default";
-};
-
-&rtc {
- status = "disabled";
-};
-
-&sata {
- nr-ports = <2>;
- status = "okay";
- #address-cells = <1>;
- #size-cells = <0>;
-
- hdd0_temp: sata-port@0 {
- reg = <0>;
- #thermal-sensor-cells = <0>;
- };
-
- hdd1_temp: sata-port@1 {
- reg = <1>;
- #thermal-sensor-cells = <0>;
- };
-};
-
-&sdio {
- pinctrl-0 = <&sdio_pins2>;
- pinctrl-names = "default";
- status = "okay";
- /* No CD or WP GPIOs */
- broken-cd;
-};
-
-&uart0 {
- status = "okay";
-};
-
-&usb0 {
- status = "okay";
-};
-
-&nand_controller {
- status = "okay";
-
- nand@0 {
- reg = <0>;
- label = "pxa3xx_nand-0";
- nand-rb = <0>;
- marvell,nand-keep-config;
- nand-on-flash-bbt;
- nand-ecc-strength = <4>;
- nand-ecc-step-size = <512>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "kernel";
- reg = <0x00000000 0x02000000>; /* 32 MiB */
- };
-
- partition@2000000 {
- label = "ubi";
- reg = <0x02000000 0x1e000000>; /* 480 MiB */
- };
- };
- };
-};
-
-&spi0 {
- status = "okay";
- pinctrl-0 = <&spi0_pins2>;
- pinctrl-names = "default";
-
- spi-flash@0 {
- compatible = "mxicy,mx25l8005", "jedec,spi-nor";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <50000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- reg = <0x00000 0xf0000>; /* 960 KiB*/
- label = "u-boot";
- read-only;
- };
- partition@f0000 {
- reg = <0xf0000 0x10000>; /* 64 KiB */
- label = "u-boot-env";
- };
- };
- };
-};
-
-&pinctrl {
- pmx_power_cpu: pmx-power-cpu {
- marvell,pins = "mpp4";
- marvell,function = "vdd";
- };
-
- pmx_power_usb: pmx-power-usb {
- marvell,pins = "mpp5";
- marvell,function = "gpo";
- };
-
- pmx_power_hdd1: pmx-power-hdd1 {
- marvell,pins = "mpp8";
- marvell,function = "gpio";
- };
-
- pmx_power_hdd2: pmx-power-hdd2 {
- marvell,pins = "mpp9";
- marvell,function = "gpo";
- };
-
- pmx_fan_lock: pmx-fan-lock {
- marvell,pins = "mpp10";
- marvell,function = "gpio";
- };
-
- pmx_hdd_present: pmx-hdd-present {
- marvell,pins = "mpp11", "mpp12";
- marvell,function = "gpio";
- };
-
- pmx_fan_high: pmx-fan-high {
- marvell,pins = "mpp13";
- marvell,function = "gpio";
- };
-
- pmx_fan_low: pmx-fan-low {
- marvell,pins = "mpp14";
- marvell,function = "gpio";
- };
-
- pmx_buttons: pmx-buttons {
- marvell,pins = "mpp15", "mpp16";
- marvell,function = "gpio";
- };
-
- pmx_leds1: pmx-leds {
- marvell,pins = "mpp7", "mpp54", "mpp59", "mpp61";
- marvell,function = "gpo";
- };
-
- pmx_leds2: pmx-leds {
- marvell,pins = "mpp55", "mpp57", "mpp62";
- marvell,function = "gpio";
- };
-
- pmx_pcie: pmx-pcie {
- marvell,pins = "mpp56", "mpp60";
- marvell,function = "pcie";
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
-/*
- * Device Tree file for Ctera C200-V2
- *
- * Copyright (C) 2021 Pawel Dembicki <paweldembicki@gmail.com>
- */
-
-/dts-v1/;
-
-#include "armada-370.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/thermal/thermal.h>
-#include <dt-bindings/leds/common.h>
-
-/ {
- model = "Ctera C200 V2";
- compatible = "ctera,c200-v2", "marvell,armada370", "marvell,armada-370-xp";
-
- 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 = "serial0:115200n8";
- };
-
- memory {
- device_type = "memory";
- reg = <0x00000000 0x40000000>; /* 1024 MB */
- };
-
- soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
- MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
- };
-
- thermal-zones {
- ethphy-thermal {
- polling-delay = <20000>;
- polling-delay-passive = <2000>;
-
- thermal-sensors = <ðphy0>;
-
- trips {
- ethphy_alert1: trip1 {
- temperature = <65000>;
- hysteresis = <4000>;
- type = "passive";
- };
-
- ethphy_crit: trip2 {
- temperature = <100000>;
- hysteresis = <2000>;
- type = "critical";
- };
- };
- };
- };
-
- keys {
- compatible = "gpio-keys";
- pinctrl-0 = <&pmx_buttons>;
- pinctrl-names = "default";
-
- power {
- label = "Power Button";
- linux,code = <KEY_POWER>;
- gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
- };
-
- reset {
- label = "Reset Button";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
- };
-
- usb1 {
- label = "USB1 Button";
- linux,code = <BTN_0>;
- gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
- };
-
- usb2 {
- label = "USB2 Button";
- linux,code = <BTN_1>;
- gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-poweroff {
- compatible = "gpio-poweroff";
- pinctrl-0 = <&pmx_poweroff>;
- pinctrl-names = "default";
- gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
- };
-
- leds {
- compatible = "gpio-leds";
- pinctrl-0 = <&pmx_leds1 &pmx_leds2>;
- pinctrl-names = "default";
-
- led-0 {
- function = LED_FUNCTION_USB;
- function-enumerator = <2>;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
- };
-
- led-1 {
- function = LED_FUNCTION_USB;
- function-enumerator = <2>;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "usbport";
- trigger-sources = <&usb1_port 1>, <&usb2_port 1>;
- };
-
- led-2 {
- function = LED_FUNCTION_USB;
- function-enumerator = <1>;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
- };
-
- led-3 {
- function = LED_FUNCTION_USB;
- function-enumerator = <1>;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "usbport";
- trigger-sources = <&usb1_port 2>, <&usb2_port 2>;
- };
-
- led-4 {
- function = LED_FUNCTION_DISK;
- function-enumerator = <2>;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "ata2";
- };
-
- led-5 {
- function = LED_FUNCTION_DISK;
- function-enumerator = <1>;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
- };
-
- led-6 {
- function = LED_FUNCTION_DISK;
- function-enumerator = <2>;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
- };
-
- led-7 {
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&gpio1 20 GPIO_ACTIVE_HIGH>;
- };
-
- led-8 {
- function = LED_FUNCTION_DISK_ERR;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
- };
-
- led-9 {
- function = LED_FUNCTION_DISK_ERR;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
- };
-
- led_status_red: led-10 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
- };
-
- led-11 {
- function = LED_FUNCTION_DISK;
- function-enumerator = <1>;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "ata1";
- };
-
- led_status_green: led-12 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
- };
- };
-};
-
-&coherencyfab {
- broken-idle;
-};
-
-ð1 {
- pinctrl-0 = <&ge1_rgmii_pins>;
- pinctrl-names = "default";
- status = "okay";
- phy-handle = <ðphy0>;
- phy-connection-type = "rgmii-id";
-};
-
-&i2c0 {
- pinctrl-0 = <&i2c0_pins>;
- pinctrl-names = "default";
- clock-frequency = <100000>;
- status = "okay";
-
- hwmon@2a {
- compatible = "nuvoton,nct7802";
- reg = <0x2a>;
- };
-
- rtc@30 {
- compatible = "sii,s35390a";
- reg = <0x30>;
- };
-};
-
-&mdio {
- pinctrl-0 = <&mdio_pins>;
- pinctrl-names = "default";
-
- ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */
- reg = <0>;
- #thermal-sensor-cells = <0>;
- };
-};
-
-&nand_controller {
- status = "okay";
-
- nand@0 {
- reg = <0>;
- label = "pxa3xx_nand-0";
- nand-rb = <0>;
- marvell,nand-keep-config;
- nand-on-flash-bbt;
- nand-ecc-strength = <4>;
- nand-ecc-step-size = <512>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "uboot";
- reg = <0x0000000 0x200000>;
- read-only;
- };
-
- partition@200000 {
- label = "certificate";
- reg = <0x0200000 0x100000>;
- read-only;
- };
-
- partition@300000 {
- label = "preset_cfg";
- reg = <0x0300000 0x100000>;
- read-only;
- };
-
- partition@400000 {
- label = "dev_params";
- reg = <0x0400000 0x100000>;
- read-only;
- };
- partition@500000 {
- label = "active_bank";
- reg = <0x0500000 0x0100000>;
- };
-
- partition@600000 {
- label = "magic";
- reg = <0x0600000 0x0100000>;
- read-only;
- };
-
- partition@700000 {
- label = "bank1";
- reg = <0x0700000 0x2800000>;
- };
-
- partition@2f00000 {
- label = "bank2";
- reg = <0x2f00000 0x2800000>;
- };
-
- /* 0x5700000-0x5a00000 undefined in vendor firmware */
-
- partition@5a00000 {
- label = "reserved";
- reg = <0x5a00000 0x2000000>;
- };
-
- partition@7a00000 {
- label = "ubi";
- reg = <0x7a00000 0x8600000>;
- };
- };
- };
-};
-
-&pciec {
- status = "okay";
-
- pcie@1,0 {
- pinctrl-0 = <&pmx_pcie>;
- pinctrl-names = "default";
- status = "okay";
- reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
-
- /* -[0000:00]---01.0-[01]----00.0 */
- /* usbport trigger won't work */
- bridge@0,1 {
- compatible = "pci11ab,6710";
- reg = <0x3800 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
-
- usb@1,0 {
- /* Renesas uPD720202 */
- compatible = "pci1912,0015";
- reg = <0x1000 0 0 0 0>;
- #address-cells = <3>;
- #size-cells = <2>;
-
- usb1_port: port@1 {
- reg = <1>;
- #trigger-source-cells = <1>;
- };
-
- usb2_port: port@2 {
- reg = <2>;
- #trigger-source-cells = <1>;
- };
- };
- };
- };
-};
-
-&pinctrl {
- pmx_poweroff: pmx-poweroff {
- marvell,pins = "mpp7";
- marvell,function = "gpo";
- };
-
- pmx_power_cpu: pmx-power-cpu {
- marvell,pins = "mpp4";
- marvell,function = "vdd";
- };
-
- pmx_buttons: pmx-buttons {
- marvell,pins = "mpp6", "mpp10", "mpp14", "mpp32";
- marvell,function = "gpio";
- };
-
- pmx_leds1: pmx-leds1 {
- marvell,pins = "mpp47";
- marvell,function = "gpo";
- };
-
- pmx_leds2: pmx-leds2 {
- marvell,pins = "mpp12", "mpp13", "mpp15", "mpp16", "mpp50", "mpp51",
- "mpp52", "mpp53", "mpp55", "mpp56", "mpp57", "mpp58";
- marvell,function = "gpio";
- };
-
- pmx_pcie: pmx-pcie {
- marvell,pins = "mpp59";
- marvell,function = "gpio";
- };
-
- /* this gpio is connected to the pin of buzzer
- * leave it as is due lack of proper driver
- */
- pmx_buzzer: pmx-buzzer {
- marvell,pins = "mpp63";
- marvell,function = "gpio";
- };
-};
-
-&pmsu {
- pinctrl-0 = <&pmx_power_cpu>;
- pinctrl-names = "default";
-};
-
-&rtc {
- status = "disabled";
-};
-
-&sata {
- nr-ports = <2>;
- status = "okay";
- #address-cells = <1>;
- #size-cells = <0>;
-
- hdd0_temp: sata-port@0 {
- reg = <0>;
- #thermal-sensor-cells = <0>;
- };
-
- hdd1_temp: sata-port@1 {
- reg = <1>;
- #thermal-sensor-cells = <0>;
- };
-};
-
-&uart0 {
- status = "okay";
-};
+++ /dev/null
-// 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 "armada-380.dtsi"
-
-/ {
- model = "IIJ SA-W2";
- compatible = "iij,sa-w2", "marvell,armada380";
-
- aliases {
- led-boot = &led_power_green;
- led-failsafe = &led_power_red;
- led-running = &led_power_green;
- led-upgrade = &led_power_green;
- label-mac-device = &ge0;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x10000000>; /* 256MB */
- };
-
- soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
- MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
- MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
- MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
-
- pcie {
- status = "okay";
-
- pcie@1,0 {
- status = "okay";
- };
-
- pcie@3,0 {
- status = "okay";
- };
- };
- };
-
- keys {
- compatible = "gpio-keys";
- pinctrl-names = "default";
- pinctrl-0 = <&pmx_keys_pins>;
-
- button-init {
- label = "init";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
- };
- };
-
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&pmx_leds_pins>;
-
- led-0 {
- gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_WLAN_5GHZ;
- linux,default-trigger = "phy0tpt";
- };
-
- led-1 {
- gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_WLAN_5GHZ;
- };
-
- led-2 {
- gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_STATUS;
- };
-
- led-3 {
- gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_STATUS;
- };
-
- led-4 {
- gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_MOBILE;
- };
-
- led-5 {
- gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_MOBILE;
- };
-
- led-6 {
- gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_WLAN_2GHZ;
- linux,default-trigger = "phy1tpt";
- };
-
- led-7 {
- gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_WLAN_2GHZ;
- };
-
- led_power_green: led-8 {
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_POWER;
- };
-
- led_power_red: led-9 {
- gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_POWER;
- };
-
- led-10 {
- gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_USB;
- function-enumerator = <1>;
- linux,default-trigger = "usbport";
- trigger-sources = <&hub_port2>;
- };
-
- led-11 {
- gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_USB;
- function-enumerator = <0>;
- linux,default-trigger = "usbport";
- trigger-sources = <&hub_port1>;
- };
- };
-
- regulator-vbus-usb0 {
- compatible = "regulator-fixed";
- regulator-name = "vbus-usb0";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio1 20 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- regulator-always-on;
- };
-
- regulator-vbus-usb1 {
- compatible = "regulator-fixed";
- regulator-name = "vbus-usb1";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio1 21 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- regulator-always-on;
- };
-};
-
-&uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins>;
- status = "okay";
-};
-
-&pinctrl {
- pmx_usb_pins: usb-pins {
- marvell,pins = "mpp2", /* smsc usb2514b reset */
- "mpp48", "mpp49", /* port over current */
- "mpp52", "mpp53"; /* port vbus */
- marvell,function = "gpio";
- };
-
- pmx_keys_pins: keys-pins {
- marvell,pins = "mpp18";
- marvell,function = "gpio";
- };
-
- pmx_leds_pins: leds-pins {
- marvell,pins = "mpp19", "mpp20", "mpp33", "mpp34", "mpp35",
- "mpp36", "mpp44", "mpp45", "mpp46", "mpp47",
- "mpp54", "mpp55";
- marvell,function = "gpio";
- };
-};
-
-&gpio0 {
- usb-hub-reset {
- gpio-hog;
- gpios = <2 GPIO_ACTIVE_HIGH>;
- output-high;
- };
-};
-
-&usb0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pmx_usb_pins>;
- status = "okay";
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* SMSC USB2514B on PCB */
- hub@1 {
- compatible = "usb424,2514";
- reg = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- hub_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- hub_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
- };
-};
-
-&bm {
- status = "okay";
-};
-
-&bm_bppi {
- status = "okay";
-};
-
-ð1 {
- pinctrl-names = "default";
- pinctrl-0 = <&ge1_rgmii_pins>;
- status = "okay";
-
- phy-connection-type = "rgmii-id";
- buffer-manager = <&bm>;
- bm,pool-long = <2>;
- bm,pool-short = <3>;
-
- nvmem-cells = <&macaddr_bdinfo_6 1>;
- nvmem-cell-names = "mac-address";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
-};
-
-&mdio {
- pinctrl-names = "default";
- pinctrl-0 = <&mdio_pins>;
- status = "okay";
-
- /* Marvell 88E6172 */
- switch@0 {
- compatible = "marvell,mv88e6085";
- reg = <0x0>;
- interrupt-controller;
- #interrupt-cells = <2>;
- interrupt-parent = <&gpio1>;
- interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- label = "ge1_0";
- };
-
- port@1 {
- reg = <1>;
- label = "ge1_1";
- };
-
- port@2 {
- reg = <2>;
- label = "ge1_2";
- };
-
- port@3 {
- reg = <3>;
- label = "ge1_3";
- };
-
- ge0: port@4 {
- reg = <4>;
- label = "ge0";
- nvmem-cells = <&macaddr_bdinfo_6 0>;
- nvmem-cell-names = "mac-address";
- };
-
- /*
- * eth0 is connected to port5 for WAN connection
- * on port4 ("GE0")
- */
-
- port@6 {
- reg = <6>;
- label = "cpu";
- ethernet = <ð1>;
- phy-connection-type = "rgmii-id";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
- };
- };
-};
-
-&rtc {
- status = "disabled";
-};
-
-&spi1 {
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins>;
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <40000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- reg = <0x0 0x100000>;
- label = "bootloader";
- read-only;
- };
-
- partition@100000 {
- reg = <0x100000 0x10000>;
- label = "bootloader-env";
- read-only;
- };
-
- partition@110000 {
- reg = <0x110000 0xf0000>;
- label = "board_info";
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_bdinfo_6: macaddr@6 {
- compatible = "mac-base";
- reg = <0x6 0x6>;
- #nvmem-cell-cells = <1>;
- };
- };
- };
-
- partition@200000 {
- compatible = "iij,seil-firmware";
- reg = <0x200000 0xf00000>;
- label = "firmware";
- iij,bootdev-name = "flash";
- iij,seil-id = <0x5345494c 0x32303135>;
- };
-
- partition@1100000 {
- compatible = "iij,seil-firmware";
- reg = <0x1100000 0xf00000>;
- label = "rescue";
- iij,bootdev-name = "rescue";
- iij,seil-id = <0x5345494c 0x32303135>;
- };
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "armada-385-fortinet-fg-x0e.dtsi"
-
-/ {
- model = "Fortinet FortiGate 30E";
- compatible = "fortinet,fg-30e", "marvell,armada385", "marvell,armada380";
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x40000000>; /* 1GB */
- };
-};
-
-&gpio_leds {
- led-14 {
- gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_AMBER>;
- function = LED_FUNCTION_SPEED_WAN;
- linux,default-trigger = "mv88e6xxx-1: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";
- };
-};
-
-&pinctrl {
- pmx_switch_pins: switch-pins {
- marvell,pins = "mpp19";
- marvell,function = "gpio";
- };
-};
-
-&mdio {
- pinctrl-names = "default";
- pinctrl-0 = <&mdio_pins>, <&pmx_switch_pins>;
-
- /* Marvell 88E6176 */
- switch@2 {
- compatible = "marvell,mv88e6085";
- reg = <0x2>;
- reset-gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- label = "wan";
- nvmem-cells = <&macaddr_bdinfo_d880 1>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
- reg = <1>;
- label = "lan4";
- nvmem-cells = <&macaddr_bdinfo_d880 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@2 {
- reg = <2>;
- label = "lan3";
- nvmem-cells = <&macaddr_bdinfo_d880 4>;
- nvmem-cell-names = "mac-address";
- };
-
- port@3 {
- reg = <3>;
- label = "lan2";
- nvmem-cells = <&macaddr_bdinfo_d880 3>;
- nvmem-cell-names = "mac-address";
- };
-
- port@4 {
- reg = <4>;
- label = "lan1";
- nvmem-cells = <&macaddr_bdinfo_d880 2>;
- nvmem-cell-names = "mac-address";
- };
-
- port@6 {
- reg = <6>;
- ethernet = <ð0>;
- phy-connection-type = "rgmii-id";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "armada-385-fortinet-fg-x0e.dtsi"
-
-/ {
- model = "Fortinet FortiGate 50E";
- compatible = "fortinet,fg-50e", "marvell,armada385", "marvell,armada380";
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x80000000>; /* 2GB */
- };
-};
-
-&gpio_leds {
- led-14 {
- gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_SPEED_WAN;
- function-enumerator = <1>;
- linux,default-trigger = "f1072004.mdio-mii:00:1Gbps";
- };
-
- led-15 {
- gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_SPEED_WAN;
- function-enumerator = <2>;
- linux,default-trigger = "f1072004.mdio-mii:01:1Gbps";
- };
-
- led-16 {
- gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_AMBER>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <5>;
- linux,default-trigger = "mv88e6xxx-1:00:100Mbps";
- };
-
- led-17 {
- gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <5>;
- linux,default-trigger = "mv88e6xxx-1:00:1Gbps";
- };
-};
-
-&pinctrl {
- pmx_phy_switch_pins: phy-switch-pins {
- marvell,pins = "mpp19", "mpp20", "mpp23", "mpp34", "mpp41";
- marvell,function = "gpio";
- };
-};
-
-ð1 {
- status = "okay";
-
- phy-handle = <ðphy0>;
- phy-connection-type = "sgmii";
- buffer-manager = <&bm>;
- bm,pool-long = <2>;
- nvmem-cells = <&macaddr_bdinfo_d880 1>;
- nvmem-cell-names = "mac-address";
-};
-
-ð2 {
- status = "okay";
-
- phy-handle = <ðphy1>;
- phy-connection-type = "sgmii";
- buffer-manager = <&bm>;
- bm,pool-long = <3>;
- nvmem-cells = <&macaddr_bdinfo_d880 2>;
- nvmem-cell-names = "mac-address";
-};
-
-&mdio {
- pinctrl-names = "default";
- pinctrl-0 = <&mdio_pins>, <&pmx_phy_switch_pins>;
-
- /* Marvell 88E1512 */
- ethphy0: ethernet-phy@0 {
- compatible = "ethernet-phy-id0141,0dd1",
- "ethernet-phy-ieee802.3-c22";
- reg = <0>;
- interrupt-parent = <&gpio0>;
- interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
- reset-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
- reset-assert-us = <10000>;
- reset-deassert-us = <10000>;
- /*
- * LINK/ACT (Green): LED[0], Active Low
- * SPEED 100M (Amber): LED[1], Active High
- */
- marvell,reg-init = <3 16 0 0x71>,
- <3 17 0 0x4>;
- };
-
- /* Marvell 88E1512 */
- ethphy1: ethernet-phy@1 {
- compatible = "ethernet-phy-id0141,0dd1",
- "ethernet-phy-ieee802.3-c22";
- reg = <1>;
- interrupt-parent = <&gpio1>;
- interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
- reset-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
- reset-assert-us = <10000>;
- reset-deassert-us = <10000>;
- /*
- * LINK/ACT (Green): LED[0], Active Low
- * SPEED 100M (Amber): LED[1], Active High
- */
- marvell,reg-init = <3 16 0 0x71>,
- <3 17 0 0x4>;
- };
-
- /* Marvell 88E6176 */
- switch@2 {
- compatible = "marvell,mv88e6085";
- reg = <0x2>;
- reset-gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- label = "lan5";
- nvmem-cells = <&macaddr_bdinfo_d880 7>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
- reg = <1>;
- label = "lan4";
- nvmem-cells = <&macaddr_bdinfo_d880 6>;
- nvmem-cell-names = "mac-address";
- };
-
- port@2 {
- reg = <2>;
- label = "lan3";
- nvmem-cells = <&macaddr_bdinfo_d880 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@3 {
- reg = <3>;
- label = "lan2";
- nvmem-cells = <&macaddr_bdinfo_d880 4>;
- nvmem-cell-names = "mac-address";
- };
-
- port@4 {
- reg = <4>;
- label = "lan1";
- nvmem-cells = <&macaddr_bdinfo_d880 3>;
- nvmem-cell-names = "mac-address";
- };
-
- port@6 {
- reg = <6>;
- ethernet = <ð0>;
- phy-connection-type = "rgmii-id";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
- };
- };
-};
+++ /dev/null
-// 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 "armada-385.dtsi"
-
-/ {
- aliases {
- led-boot = &led_status_green;
- led-failsafe = &led_status_red;
- led-running = &led_status_green;
- led-upgrade = &led_status_green;
- label-mac-device = ð0;
- };
-
- chosen {
- stdout-path = "serial0:9600n8";
- };
-
- soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
- MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
- MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
- MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
- };
-
- gpio-keys {
- compatible = "gpio-keys";
- pinctrl-names = "default";
- pinctrl-0 = <&pmx_gpio_keys_pins>;
-
- reset {
- label = "reset";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio_leds: gpio-leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&pmx_gpio_leds_pins>;
-
- led-0 {
- gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_ALARM;
- };
-
- led-1 {
- gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_RED>;
- function = "ha";
- };
-
- led_status_green: led-2 {
- gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_STATUS;
- };
-
- led-3 {
- gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_GREEN>;
- function = "ha";
- };
-
- led-4 {
- gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_AMBER>;
- function = LED_FUNCTION_ALARM;
- };
-
- led_status_red: led-5 {
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_STATUS;
- };
-
- led-6 {
- gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <4>;
- linux,default-trigger = "mv88e6xxx-1:01:1Gbps";
- };
-
- led-7 {
- gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_AMBER>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <4>;
- linux,default-trigger = "mv88e6xxx-1:01:100Mbps";
- };
-
- led-8 {
- gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_AMBER>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <3>;
- linux,default-trigger = "mv88e6xxx-1:02:100Mbps";
- };
-
- led-9 {
- gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <3>;
- linux,default-trigger = "mv88e6xxx-1:02:1Gbps";
- };
-
- led-10 {
- gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <1>;
- linux,default-trigger = "mv88e6xxx-1:04:1Gbps";
- };
-
- led-11 {
- gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_AMBER>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <1>;
- linux,default-trigger = "mv88e6xxx-1:04:100Mbps";
- };
-
- led-12 {
- gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <2>;
- linux,default-trigger = "mv88e6xxx-1:03:1Gbps";
- };
-
- led-13 {
- gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
- color = <LED_COLOR_ID_AMBER>;
- function = LED_FUNCTION_SPEED_LAN;
- function-enumerator = <2>;
- linux,default-trigger = "mv88e6xxx-1:03:100Mbps";
- };
- };
-
- reg_usb_vbus: regulator-usb-vbus {
- compatible = "fixed-regulator";
- regulator-name = "usb-vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio1 21 GPIO_ACTIVE_LOW>;
- regulator-always-on;
- };
-};
-
-&i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins>;
- status = "okay";
-
- gpio2: gpio@24 {
- compatible = "nxp,pca9555";
- reg = <0x24>;
- gpio-controller;
- #gpio-cells = <0x2>;
- };
-
- hwmon@28 {
- compatible = "nuvoton,nct7802";
- reg = <0x28>;
- };
-};
-
-&uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins>;
- status = "okay";
-};
-
-&pinctrl {
- pmx_gpio_leds_pins: gpio-leds-pins {
- marvell,pins = "mpp30", "mpp32", "mpp33", "mpp35",
- "mpp45", "mpp47";
- marvell,function = "gpio";
- };
-
- pmx_usb_pins: usb-pins {
- marvell,pins = "mpp53";
- marvell,function = "gpio";
- };
-
- pmx_gpio_keys_pins: gpio-keys-pins {
- marvell,pins = "mpp54";
- marvell,function = "gpio";
- };
-};
-
-&bm {
- status = "okay";
-};
-
-&bm_bppi {
- status = "okay";
-};
-
-ð0 {
- pinctrl-names = "default";
- pinctrl-0 = <&ge0_rgmii_pins>;
- status = "okay";
-
- phy-connection-type = "rgmii-id";
- buffer-manager = <&bm>;
- bm,pool-long = <0>;
- bm,pool-short = <1>;
- nvmem-cells = <&macaddr_bdinfo_d880 0>;
- nvmem-cell-names = "mac-address";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
-};
-
-&usb3_0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pmx_usb_pins>;
- status = "okay";
-
- vbus-supply = <®_usb_vbus>;
-};
-
-&spi1 {
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins>;
- 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 {
- reg = <0x0 0x1c0000>;
- label = "u-boot";
- read-only;
- };
-
- partition@1c0000 {
- reg = <0x1c0000 0x10000>;
- label = "firmware-info";
-
- /*
- * 0x10 - 0x2f : image name (image1)
- * 0x30 - 0x4f : image name (image2)
- * 0x170 (1byte): active image (0x0/0x1)
- * 0x184 - 0x185: kernel block count (image1)
- * 0x18c - 0x18d: rootfs block count (image1)
- * 0x194 - 0x195: kernel block count (image2)
- * 0x19c - 0x19d: rootfs block count (image2)
- * 0x1be (1byte): bit7 -> active flag (image1)?
- * 0x1ce (1byte): bit7 -> active flag (image2)?
- *
- * Note: block size --> 0x200 (512 bytes)
- */
- };
-
- partition@1d0000 {
- reg = <0x1d0000 0x10000>;
- label = "dtb";
- read-only;
- };
-
- partition@1e0000 {
- reg = <0x1e0000 0x10000>;
- label = "u-boot-env";
- read-only;
- };
-
- partition@1f0000 {
- reg = <0x1f0000 0x10000>;
- label = "board-info";
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_bdinfo_d880: macaddr@d880 {
- compatible = "mac-base";
- reg = <0xd880 0x6>;
- #nvmem-cell-cells = <1>;
- };
- };
- };
-
- partition@200000 {
- reg = <0x200000 0x600000>;
- label = "kernel";
- };
-
- partition@800000 {
- reg = <0x800000 0x1800000>;
- label = "rootfs";
- };
-
- partition@2000000 {
- reg = <0x2000000 0x600000>;
- label = "kn2";
- read-only;
- };
-
- partition@2600000 {
- reg = <0x2600000 0x1800000>;
- label = "rfs2";
- read-only;
- };
-
- partition@3e00000 {
- reg = <0x3e00000 0x1200000>;
- label = "part1";
- read-only;
- };
-
- partition@5000000 {
- reg = <0x5000000 0x1200000>;
- label = "part2";
- read-only;
- };
-
- partition@6200000 {
- reg = <0x6200000 0x1e00000>;
- label = "config";
- read-only;
- };
- };
- };
-};
+++ /dev/null
-/*
- * Device Tree file for the Linksys WRT32X (Venom)
- *
- * Copyright (C) 2017 Imre Kaloz <kaloz@openwrt.org>
- *
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- * a) This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without
- * any warranty of any kind, whether express or implied.
- *
- * Or, alternatively,
- *
- * b) Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/dts-v1/;
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include "armada-385-linksys.dtsi"
-
-/ {
- model = "Linksys WRT32X";
- compatible = "linksys,wrt32x", "linksys,venom", "linksys,armada385",
- "marvell,armada385", "marvell,armada380";
-
- chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = "serial0:115200n8";
- append-rootblock = "root=/dev/mtdblock";
- };
-};
-
-&expander0 {
- wan_amber@0 {
- label = "venom:amber:wan";
- reg = <0x0>;
- };
-
- wan_blue@1 {
- label = "venom:blue:wan";
- reg = <0x1>;
- };
-
- usb2@5 {
- label = "venom:blue:usb2";
- reg = <0x5>;
- };
-
- usb3_1@6 {
- label = "venom:blue:usb3_1";
- reg = <0x6>;
- };
-
- usb3_2@7 {
- label = "venom:blue:usb3_2";
- reg = <0x7>;
- };
-
- wps_blue@8 {
- label = "venom:blue:wps";
- reg = <0x8>;
- };
-
- wps_amber@9 {
- label = "venom:amber:wps";
- reg = <0x9>;
- };
-};
-
-&gpio_leds {
- power {
- gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
- label = "venom:blue:power";
- };
-
- sata {
- gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
- label = "venom:blue:sata";
- };
-
- wlan_2g {
- gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
- label = "venom:blue:wlan_2g";
- };
-
- wlan_5g {
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
- label = "venom:blue:wlan_5g";
- };
-};
-
-&gpio_leds_pins {
- marvell,pins = "mpp21", "mpp45", "mpp46", "mpp56";
-};
-
-&nand {
- /* Spansion S34ML02G2 256MiB, OEM Layout */
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0000000 0x200000>; /* 2MB */
- read-only;
- };
-
- partition@200000 {
- label = "u_env";
- reg = <0x200000 0x20000>; /* 128KB */
- };
-
- partition@220000 {
- label = "s_env";
- reg = <0x220000 0x40000>; /* 256KB */
- };
-
- partition@180000 {
- label = "unused_area";
- reg = <0x260000 0x5c0000>; /* 5.75MB */
- };
-
- partition@7e0000 {
- label = "devinfo";
- reg = <0x7e0000 0x40000>; /* 256KB */
- read-only;
- };
-
- /* kernel1 overlaps with rootfs1 by design */
- partition@900000 {
- label = "kernel1";
- reg = <0x900000 0x7b00000>; /* 123MB */
- };
-
- partition@f00000 {
- label = "rootfs1";
- reg = <0xf00000 0x7500000>; /* 117MB */
- };
-
- /* kernel2 overlaps with rootfs2 by design */
- partition@8400000 {
- label = "kernel2";
- reg = <0x8400000 0x7b00000>; /* 123MB */
- };
-
- partition@8a00000 {
- label = "rootfs2";
- reg = <0x8a00000 0x7500000>; /* 117MB */
- };
-
- /* last MB is for the BBT, not writable */
- partition@ff00000 {
- label = "BBT";
- reg = <0xff00000 0x100000>;
- };
- };
-};
-
-
-&pcie1 {
- mwlwifi {
- marvell,chainmask = <4 4>;
- };
-};
-
-&pcie2 {
- mwlwifi {
- marvell,chainmask = <4 4>;
- };
-};
-
-&sdhci {
- pinctrl-names = "default";
- pinctrl-0 = <&sdhci_pins>;
- no-1-8-v;
- non-removable;
- wp-inverted;
- bus-width = <8>;
- status = "okay";
-};
-
-&usb3_1_vbus {
- gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
-};
-
-&usb3_1_vbus_pins {
- marvell,pins = "mpp44";
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
-/*
- * Device Tree file for ipTIME NAS1dual
- *
- * Copyright (C) 2020 Sungbo Eo <mans0n@gorani.run>
- *
- * Based on armada-385-linksys.dtsi
- * Copyright (C) 2015 Imre Kaloz <kaloz@openwrt.org>
- */
-
-/dts-v1/;
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-#include "armada-385.dtsi"
-
-/ {
- model = "ipTIME NAS1dual";
- compatible = "iptime,nas1dual", "marvell,armada385", "marvell,armada380";
-
- aliases {
- led-boot = &led_ready;
- led-failsafe = &led_ready;
- led-running = &led_ready;
- led-upgrade = &led_ready;
- label-mac-device = ð0;
- };
-
- chosen {
- bootargs = "console=ttyS0,115200n8";
- stdout-path = "serial0:115200n8";
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x80000000>; /* 2GB */
- };
-
- soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
- MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
- MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
- MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
- };
-
- gpio-keys {
- compatible = "gpio-keys";
- pinctrl-names = "default";
- pinctrl-0 = <&gpio_keys_pins>;
-
- power {
- label = "Power Button";
- linux,input-type = <EV_SW>;
- linux,code = <KEY_POWER>;
- gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
- };
-
- reset {
- label = "Reset Button";
- linux,code = <KEY_RESTART>;
- gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
- };
-
- copy {
- label = "USB Copy Button";
- linux,code = <KEY_COPY>;
- gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
- };
- };
-
- gpio-leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&gpio_leds_pins>;
-
- led_ready: ready {
- label = "blue:ready";
- gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
- };
-
- hdd {
- label = "blue:hdd";
- gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "disk-activity";
- };
-
- usb {
- function = LED_FUNCTION_USB;
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&usb3_0_port1 &usb3_0_port2>;
- linux,default-trigger = "usbport";
- };
- };
-
- gpio-fan {
- compatible = "gpio-fan";
- pinctrl-names = "default";
- pinctrl-0 = <&gpio_fan_pins>;
- gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>,
- <&gpio1 18 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 1 GPIO_ACTIVE_LOW>;
- };
-
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&sata_power_pins>;
-
- reg_sata_power: regulator@1 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "sata-power";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- gpio = <&gpio1 20 GPIO_ACTIVE_LOW>;
- regulator-always-on;
- };
- };
-};
-
-&ahci0 {
- status = "okay";
- #address-cells = <1>;
- #size-cells = <0>;
-
- sata-port@0 {
- reg = <0>;
- target-supply = <®_sata_power>;
- #thermal-sensor-cells = <0>;
- };
-};
-
-&bm {
- status = "okay";
-};
-
-&bm_bppi {
- status = "okay";
-};
-
-ð0 {
- pinctrl-names = "default";
- pinctrl-0 = <&ge0_rgmii_pins>;
- status = "okay";
- phy-handle = <ðphy1>;
- phy-connection-type = "rgmii-id";
- buffer-manager = <&bm>;
- bm,pool-long = <0>;
- bm,pool-short = <1>;
- nvmem-cells = <&macaddr_uboot_fffa8>;
- nvmem-cell-names = "mac-address";
-};
-
-ð1 {
- pinctrl-names = "default";
- pinctrl-0 = <&ge1_rgmii_pins>;
- status = "okay";
- phy-handle = <ðphy0>;
- phy-connection-type = "rgmii-id";
- buffer-manager = <&bm>;
- bm,pool-long = <2>;
- bm,pool-short = <3>;
- nvmem-cells = <&macaddr_uboot_fffa8>;
- nvmem-cell-names = "mac-address";
-};
-
-&i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&i2c0_pins>;
- status = "okay";
-
- pca9536: gpio@41 {
- compatible = "nxp,pca9536";
- reg = <0x41>;
- gpio-controller;
- #gpio-cells = <2>;
- gpio-line-names = "power-led", "power-board";
- };
-};
-
-&mdio {
- pinctrl-names = "default";
- pinctrl-0 = <&mdio_pins>;
-
- /* LED1: On - Link, Blink - Activity, Off - No Link */
-
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- marvell,reg-init = <3 16 0 0x1017>;
- };
-
- ethphy1: ethernet-phy@1 {
- reg = <1>;
- marvell,reg-init = <3 16 0 0x1017>;
- };
-};
-
-&pinctrl {
- gpio_keys_pins: gpio-keys-pins {
- marvell,pins = "mpp24", "mpp26", "mpp48";
- marvell,function = "gpio";
- };
-
- gpio_leds_pins: gpio-leds-pins {
- marvell,pins = "mpp18", "mpp20", "mpp51";
- marvell,function = "gpio";
- };
-
- gpio_fan_pins: gpio-fan-pins {
- marvell,pins = "mpp25", "mpp50";
- marvell,function = "gpio";
- };
-
- sata_power_pins: sata-power-pins {
- marvell,pins = "mpp52";
- marvell,function = "gpio";
- };
-
- uart1_pins_alt: uart-pins-1-alt {
- marvell,pins = "mpp45", "mpp46";
- marvell,function = "ua1";
- };
-};
-
-&spi1 {
- pinctrl-names = "default";
- pinctrl-0 = <&spi1_pins>;
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <40000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- reg = <0x00000000 0x00100000>;
- label = "u-boot";
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_uboot_fffa8: macaddr@fffa8 {
- reg = <0xfffa8 0x6>;
- };
- };
- };
-
- partition@100000 {
- reg = <0x00100000 0x03ec0000>;
- label = "firmware";
-
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- reg = <0x00000000 0x00600000>;
- label = "kernel";
- };
-
- partition@600000 {
- reg = <0x00600000 0x038c0000>;
- label = "rootfs";
- };
- };
-
- partition@3fc0000 {
- reg = <0x03fc0000 0x00040000>;
- label = "config";
- read-only;
- };
- };
- };
-};
-
-&uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins>;
- status = "okay";
-};
-
-&uart1 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart1_pins_alt>;
- status = "okay";
-};
-
-&usb3_0 {
- status = "okay";
- #address-cells = <1>;
- #size-cells = <0>;
-
- usb3_0_port1: port@1 {
- reg = <1>;
- #trigger-source-cells = <0>;
- };
-
- usb3_0_port2: port@2 {
- reg = <2>;
- #trigger-source-cells = <0>;
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-
-/dts-v1/;
-
-#include "armada-3720-uDPU.dtsi"
-
-/ {
- model = "Methode eDPU Board";
- compatible = "methode,edpu", "marvell,armada3720", "marvell,armada3710";
-};
-
-/* PHY mode is set to 1000Base-X despite Maxlinear IC being capable of
- * 2500Base-X since until 5.15 support for mvebu is available trying to
- * use 2500Base-X will cause buffer overruns for which the fix is not
- * easily backportable.
- */
-ð0 {
- phy-mode = "1000base-x";
-};
-
-/*
- * External MV88E6361 switch is only available on v2 of the board.
- * U-Boot will enable the MDIO bus and switch nodes.
- */
-&mdio {
- status = "disabled";
- pinctrl-names = "default";
- pinctrl-0 = <&smi_pins>;
-
- /* Actual device is MV88E6361 */
- switch: switch@0 {
- compatible = "marvell,mv88e6190";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- status = "disabled";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- label = "cpu";
- phy-mode = "2500base-x";
- managed = "in-band-status";
- ethernet = <ð0>;
- };
-
- port@9 {
- reg = <9>;
- label = "downlink";
- phy-mode = "2500base-x";
- managed = "in-band-status";
- };
-
- port@a {
- reg = <10>;
- label = "uplink";
- phy-mode = "2500base-x";
- managed = "in-band-status";
- sfp = <&sfp_eth1>;
- };
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Device Tree file for ESPRESSObin-Ultra
- * Copyright (C) 2019 Globalscale technologies, Inc.
- *
- * Jason Hung <jhung@globalscaletechnologies.com>
- */
-
-/dts-v1/;
-
-#include <dt-bindings/gpio/gpio.h>
-#include "armada-372x.dtsi"
-
-/ {
- model = "Globalscale Marvell ESPRESSOBin Ultra Board";
- compatible = "globalscale,espressobin-ultra", "marvell,armada3720",
- "marvell,armada3710";
-
- aliases {
- /* for dsa slave device */
- ethernet1 = &switch0port1;
- ethernet2 = &switch0port2;
- ethernet3 = &switch0port3;
- ethernet4 = &switch0port4;
- ethernet5 = &switch0port5;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
- };
-
- reg_usb3_vbus: usb3-vbus {
- compatible = "regulator-fixed";
- regulator-name = "usb3-vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- gpio = <&gpionb 19 GPIO_ACTIVE_HIGH>;
- };
-
- usb3_phy: usb3-phy {
- compatible = "usb-nop-xceiv";
- vcc-supply = <®_usb3_vbus>;
- };
-
- leds {
- pinctrl-names = "default";
- compatible = "gpio-leds";
- /* No assigned functions to the LEDs by default */
- led1 {
- label = "ebin-ultra:blue:led1";
- gpios = <&gpionb 11 GPIO_ACTIVE_LOW>;
- };
- led2 {
- label = "ebin-ultra:green:led2";
- gpios = <&gpionb 12 GPIO_ACTIVE_LOW>;
- };
- led3 {
- label = "ebin-ultra:red:led3";
- gpios = <&gpionb 13 GPIO_ACTIVE_LOW>;
- };
- led4 {
- label = "ebin-ultra:yellow:led4";
- gpios = <&gpionb 14 GPIO_ACTIVE_LOW>;
- };
- };
-};
-
-&pcie0 {
- status = "okay";
-};
-
-&sata {
- status = "okay";
-};
-
-&sdhci0 {
- status = "okay";
- non-removable;
- bus-width = <8>;
- mmc-ddr-1_8v;
- mmc-hs400-1_8v;
- marvell,pad-type = "fixed-1-8v";
-};
-
-&spi0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&spi_quad_pins>;
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <108000000>;
- spi-rx-bus-width = <4>;
- spi-tx-bus-width = <4>;
- m25p,fast-read;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "firmware";
- reg = <0x0 0x3e0000>;
- };
- partition@3e0000 {
- label = "hw-info";
- reg = <0x3e0000 0x10000>;
- read-only;
- };
- partition@3f0000 {
- label = "u-boot-env";
- reg = <0x3f0000 0x10000>;
- };
- };
- };
-};
-
-&uart0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&uart1_pins>;
-};
-
-&i2c0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&i2c1_pins>;
-
- clock-frequency = <100000>;
-
- rtc@51 {
- compatible = "nxp,pcf8563";
- reg = <0x51>;
- };
-};
-
-&usb3 {
- status = "okay";
- usb-phy = <&usb3_phy>;
-};
-
-&usb2 {
- status = "okay";
-};
-
-ð0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&rgmii_pins>;
- phy-mode = "rgmii-id";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
-};
-
-&mdio {
- status = "okay";
-
- extphy: ethernet-phy@0 {
- reg = <1>;
- };
-
- switch0: switch0@1 {
- compatible = "marvell,mv88e6085";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
-
- dsa,member = <0 0>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- switch0port0: port@0 {
- reg = <0>;
- ethernet = <ð0>;
- };
-
- switch0port1: port@1 {
- reg = <1>;
- label = "lan0";
- phy-handle = <&switch0phy1>;
- };
-
- switch0port2: port@2 {
- reg = <2>;
- label = "lan1";
- phy-handle = <&switch0phy2>;
- };
-
- switch0port3: port@3 {
- reg = <3>;
- label = "lan2";
- phy-handle = <&switch0phy3>;
- };
-
- switch0port4: port@4 {
- reg = <4>;
- label = "lan3";
- phy-handle = <&switch0phy4>;
- };
-
- switch0port5: port@5 {
- reg = <5>;
- label = "wan";
- phy-handle = <&extphy>;
- phy-mode = "sgmii";
- };
- };
-
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
-
- switch0phy1: switch0phy1@11 {
- reg = <0x11>;
- };
- switch0phy2: switch0phy2@12 {
- reg = <0x12>;
- };
- switch0phy3: switch0phy3@13 {
- reg = <0x13>;
- };
- switch0phy4: switch0phy4@14 {
- reg = <0x14>;
- };
- };
- };
-};
+++ /dev/null
-// 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 "armada-372x.dtsi"
-
-/ {
- model = "GL.iNet GL-MV1000";
- compatible = "glinet,gl-mv1000", "marvell,armada3720";
-
- aliases {
- led-boot = &led_power;
- led-failsafe = &led_power;
- led-running = &led_power;
- led-upgrade = &led_power;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
- };
-
- vcc_sd_reg1: regulator {
- compatible = "regulator-gpio";
- regulator-name = "vcc_sd1";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- regulator-boot-on;
-
- gpios-states = <0>;
- states = <1800000 0x1
- 3300000 0x0>;
- enable-active-high;
- };
-
- keys {
- compatible = "gpio-keys";
-
- reset {
- label = "reset";
- linux,code = <KEY_RESTART>;
- gpios = <&gpionb 14 GPIO_ACTIVE_LOW>;
- };
-
- switch {
- label = "switch";
- linux,code = <BTN_0>;
- gpios = <&gpiosb 22 GPIO_ACTIVE_LOW>;
- };
- };
-
- leds {
- compatible = "gpio-leds";
-
- vpn {
- label = "green:vpn";
- gpios = <&gpionb 11 GPIO_ACTIVE_LOW>;
- };
-
- wan {
- function = LED_FUNCTION_WAN;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpionb 12 GPIO_ACTIVE_LOW>;
- };
-
- led_power: power {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpionb 13 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
- };
-};
-
-&spi0 {
- status = "okay";
-
- flash@0 {
- reg = <0>;
- compatible = "jedec,spi-nor";
- spi-max-frequency = <104000000>;
- m25p,fast-read;
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0 0xf0000>;
- read-only;
- };
-
- partition@f0000 {
- label = "u-boot-env";
- reg = <0xf0000 0x8000>;
- read-only;
- };
-
- factory: partition@f8000 {
- label = "factory";
- reg = <0xf8000 0x8000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_factory_0: macaddr@0 {
- reg = <0x0 0x6>;
- };
-
- macaddr_factory_6: macaddr@6 {
- reg = <0x6 0x6>;
- };
- };
- };
-
- partition@100000 {
- label = "gl-firmware-dtb";
- reg = <0x100000 0x10000>;
- read-only;
- };
-
- partition@110000 {
- label = "gl-firmware";
- reg = <0x110000 0xef0000>;
- read-only;
- };
-
- partition@ef0000 {
- label = "gl-firmware-jffs2";
- reg = <0xef0000 0x110000>;
- read-only;
- };
- };
- };
-};
-
-&sdhci1 {
- wp-inverted;
- bus-width = <4>;
- cd-gpios = <&gpionb 17 GPIO_ACTIVE_LOW>;
- marvell,pad-type = "sd";
- no-1-8-v;
- vqmmc-supply = <&vcc_sd_reg1>;
- status = "okay";
-};
-
-&sdhci0 {
- bus-width = <8>;
- mmc-ddr-1_8v;
- mmc-hs400-1_8v;
- non-removable;
- no-sd;
- no-sdio;
- marvell,pad-type = "fixed-1-8v";
- status = "okay";
-};
-
-&usb3 {
- status = "okay";
-};
-
-&usb2 {
- status = "okay";
-};
-
-&uart0 {
- status = "okay";
-};
-
-&mdio {
- switch0: switch0@1 {
- compatible = "marvell,mv88e6085";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
-
- dsa,member = <0 0>;
-
- ports: ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- ethernet = <ð0>;
- };
-
- port@1 {
- reg = <1>;
- label = "wan";
- phy-handle = <&switch0phy0>;
- };
-
- port@2 {
- reg = <2>;
- label = "lan0";
- phy-handle = <&switch0phy1>;
-
- nvmem-cells = <&macaddr_factory_6>;
- nvmem-cell-names = "mac-address";
- };
-
- port@3 {
- reg = <3>;
- label = "lan1";
- phy-handle = <&switch0phy2>;
-
- nvmem-cells = <&macaddr_factory_6>;
- nvmem-cell-names = "mac-address";
- };
- };
-
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
-
- switch0phy0: switch0phy0@11 {
- reg = <0x11>;
- };
- switch0phy1: switch0phy1@12 {
- reg = <0x12>;
- };
- switch0phy2: switch0phy2@13 {
- reg = <0x13>;
- };
- };
- };
-};
-
-ð0 {
- nvmem-cells = <&macaddr_factory_0>;
- nvmem-cell-names = "mac-address";
- phy-mode = "rgmii-id";
- status = "okay";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-
-/dts-v1/;
-
-#include "armada-3720-uDPU.dtsi"
-
-/ {
- model = "Methode uDPU Board";
- compatible = "methode,udpu", "marvell,armada3720", "marvell,armada3710";
-
- sfp_eth0: sfp-eth0 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c0>;
- los-gpio = <&gpiosb 2 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpiosb 3 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpiosb 4 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpiosb 5 GPIO_ACTIVE_HIGH>;
- maximum-power-milliwatt = <3000>;
- };
-};
-
-&pinctrl_nb {
- i2c1_recovery_pins: i2c1-recovery-pins {
- groups = "i2c1";
- function = "gpio";
- };
-};
-
-&i2c0 {
- status = "okay";
- pinctrl-names = "default", "recovery";
- pinctrl-0 = <&i2c1_pins>;
- pinctrl-1 = <&i2c1_recovery_pins>;
- /delete-property/mrvl,i2c-fast-mode;
- scl-gpios = <&gpionb 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- sda-gpios = <&gpionb 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-};
-
-ð0 {
- phy-mode = "2500base-x";
- sfp = <&sfp_eth0>;
-};
-
-ð1 {
- phy-mode = "2500base-x";
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Device tree for the uDPU board.
- * Based on Marvell Armada 3720 development board (DB-88F3720-DDR3)
- * Copyright (C) 2016 Marvell
- * Copyright (C) 2019 Methode Electronics
- * Copyright (C) 2019 Telus
- *
- * Vladimir Vid <vladimir.vid@sartura.hr>
- */
-
-/dts-v1/;
-
-#include <dt-bindings/gpio/gpio.h>
-#include "armada-372x.dtsi"
-
-/ {
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
- };
-
- aliases {
- ethernet0 = ð0;
- ethernet1 = ð1;
- };
-
- leds {
- compatible = "gpio-leds";
-
- led-power1 {
- label = "udpu:green:power";
- gpios = <&gpionb 11 GPIO_ACTIVE_LOW>;
- };
-
- led-power2 {
- label = "udpu:red:power";
- gpios = <&gpionb 12 GPIO_ACTIVE_LOW>;
- };
-
- led-network1 {
- label = "udpu:green:network";
- gpios = <&gpionb 13 GPIO_ACTIVE_LOW>;
- };
-
- led-network2 {
- label = "udpu:red:network";
- gpios = <&gpionb 14 GPIO_ACTIVE_LOW>;
- };
-
- led-alarm1 {
- label = "udpu:green:alarm";
- gpios = <&gpionb 15 GPIO_ACTIVE_LOW>;
- };
-
- led-alarm2 {
- label = "udpu:red:alarm";
- gpios = <&gpionb 16 GPIO_ACTIVE_LOW>;
- };
- };
-
- sfp_eth1: sfp-eth1 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c1>;
- los-gpio = <&gpiosb 7 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>;
- maximum-power-milliwatt = <3000>;
- };
-};
-
-&sdhci0 {
- status = "okay";
- bus-width = <8>;
- mmc-ddr-1_8v;
- mmc-hs400-1_8v;
- marvell,pad-type = "fixed-1-8v";
- non-removable;
- no-sd;
- no-sdio;
-};
-
-&spi0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&spi_quad_pins>;
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <54000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "firmware";
- reg = <0x0 0x180000>;
- };
-
- partition@180000 {
- label = "u-boot-env";
- reg = <0x180000 0x10000>;
- };
- };
- };
-};
-
-&pinctrl_nb {
- i2c2_recovery_pins: i2c2-recovery-pins {
- groups = "i2c2";
- function = "gpio";
- };
-};
-
-&i2c1 {
- status = "okay";
- pinctrl-names = "default", "recovery";
- pinctrl-0 = <&i2c2_pins>;
- pinctrl-1 = <&i2c2_recovery_pins>;
- /delete-property/mrvl,i2c-fast-mode;
- scl-gpios = <&gpionb 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
- sda-gpios = <&gpionb 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-
- temp-sensor@48 {
- compatible = "ti,tmp75c";
- reg = <0x48>;
- };
-
- temp-sensor@49 {
- compatible = "ti,tmp75c";
- reg = <0x49>;
- };
-};
-
-ð0 {
- status = "okay";
- managed = "in-band-status";
- phys = <&comphy1 0>;
-};
-
-ð1 {
- phy-mode = "sgmii";
- status = "okay";
- managed = "in-band-status";
- phys = <&comphy0 1>;
- sfp = <&sfp_eth1>;
-};
-
-&usb3 {
- status = "okay";
- phys = <&usb2_utmi_otg_phy>;
- phy-names = "usb2-utmi-otg-phy";
-};
-
-&uart0 {
- status = "okay";
-};
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-/*
- * Device Tree file for Globalscale MOCHAbin
- * Copyright (C) 2019 Globalscale technologies, Inc.
- * Copyright (C) 2021 Sartura Ltd.
- *
- */
-
-/dts-v1/;
-
-#include <dt-bindings/gpio/gpio.h>
-#include "armada-7040.dtsi"
-
-/ {
- model = "Globalscale MOCHAbin";
- compatible = "globalscale,mochabin", "marvell,armada7040",
- "marvell,armada-ap806-quad", "marvell,armada-ap806";
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- aliases {
- ethernet0 = &cp0_eth0;
- ethernet1 = &cp0_eth1;
- ethernet2 = &cp0_eth2;
- ethernet3 = &swport1;
- ethernet4 = &swport2;
- ethernet5 = &swport3;
- ethernet6 = &swport4;
- };
-
- /* SFP+ 10G */
- sfp_eth0: sfp-eth0 {
- compatible = "sff,sfp";
- i2c-bus = <&cp0_i2c1>;
- los-gpio = <&sfp_gpio 3 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&sfp_gpio 2 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&sfp_gpio 1 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&sfp_gpio 0 GPIO_ACTIVE_HIGH>;
- };
-
- /* SFP 1G */
- sfp_eth2: sfp-eth2 {
- compatible = "sff,sfp";
- i2c-bus = <&cp0_i2c0>;
- los-gpio = <&sfp_gpio 7 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&sfp_gpio 6 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&sfp_gpio 5 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&sfp_gpio 4 GPIO_ACTIVE_HIGH>;
- };
-};
-
-/* microUSB UART console */
-&uart0 {
- status = "okay";
-
- pinctrl-0 = <&uart0_pins>;
- pinctrl-names = "default";
-};
-
-/* eMMC */
-&ap_sdhci0 {
- status = "okay";
-
- bus-width = <4>;
- non-removable;
- /delete-property/ marvell,xenon-phy-slow-mode;
- no-1-8-v;
-};
-
-&cp0_pinctrl {
- cp0_uart0_pins: cp0-uart0-pins {
- marvell,pins = "mpp6", "mpp7";
- marvell,function = "uart0";
- };
-
- cp0_spi0_pins: cp0-spi0-pins {
- marvell,pins = "mpp56", "mpp57", "mpp58", "mpp59";
- marvell,function = "spi0";
- };
-
- cp0_spi1_pins: cp0-spi1-pins {
- marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
- marvell,function = "spi1";
- };
-
- cp0_i2c0_pins: cp0-i2c0-pins {
- marvell,pins = "mpp37", "mpp38";
- marvell,function = "i2c0";
- };
-
- cp0_i2c1_pins: cp0-i2c1-pins {
- marvell,pins = "mpp2", "mpp3";
- marvell,function = "i2c1";
- };
-
- pca9554_int_pins: pca9554-int-pins {
- marvell,pins = "mpp27";
- marvell,function = "gpio";
- };
-
- cp0_rgmii1_pins: cp0-rgmii1-pins {
- marvell,pins = "mpp44", "mpp45", "mpp46", "mpp47", "mpp48", "mpp49",
- "mpp50", "mpp51", "mpp52", "mpp53", "mpp54", "mpp55";
- marvell,function = "ge1";
- };
-
- is31_sdb_pins: is31-sdb-pins {
- marvell,pins = "mpp30";
- marvell,function = "gpio";
- };
-
- cp0_pcie_reset_pins: cp0-pcie-reset-pins {
- marvell,pins = "mpp9";
- marvell,function = "gpio";
- };
-
- cp0_switch_pins: cp0-switch-pins {
- marvell,pins = "mpp0", "mpp1";
- marvell,function = "gpio";
- };
-
- cp0_phy_pins: cp0-phy-pins {
- marvell,pins = "mpp12";
- marvell,function = "gpio";
- };
-};
-
-/* mikroBUS UART */
-&cp0_uart0 {
- status = "okay";
-
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_uart0_pins>;
-};
-
-/* mikroBUS SPI */
-&cp0_spi0 {
- status = "okay";
-
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_spi0_pins>;
-};
-
-/* SPI-NOR */
-&cp0_spi1{
- status = "okay";
-
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_spi1_pins>;
-
- spi-flash@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- 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 0x3e0000>;
- read-only;
- };
-
- partition@3e0000 {
- label = "hw-info";
- reg = <0x3e0000 0x10000>;
- read-only;
- };
-
- partition@3f0000 {
- label = "u-boot-env";
- reg = <0x3f0000 0x10000>;
- };
- };
- };
-};
-
-/* mikroBUS, 1G SFP and GPIO expander */
-&cp0_i2c0 {
- status = "okay";
-
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_i2c0_pins>;
- clock-frequency = <100000>;
-
- sfp_gpio: pca9554@39 {
- compatible = "nxp,pca9554";
- pinctrl-names = "default";
- pinctrl-0 = <&pca9554_int_pins>;
- reg = <0x39>;
-
- interrupt-parent = <&cp0_gpio1>;
- interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
- interrupt-controller;
- #interrupt-cells = <2>;
-
- gpio-controller;
- #gpio-cells = <2>;
-
- /*
- * IO0_0: SFP+_TX_FAULT
- * IO0_1: SFP+_TX_DISABLE
- * IO0_2: SFP+_PRSNT
- * IO0_3: SFP+_LOSS
- * IO0_4: SFP_TX_FAULT
- * IO0_5: SFP_TX_DISABLE
- * IO0_6: SFP_PRSNT
- * IO0_7: SFP_LOSS
- */
- };
-};
-
-/* IS31FL3199, mini-PCIe and 10G SFP+ */
-&cp0_i2c1 {
- status = "okay";
-
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_i2c1_pins>;
- clock-frequency = <100000>;
-
- leds@64 {
- compatible = "issi,is31fl3199";
- #address-cells = <1>;
- #size-cells = <0>;
- pinctrl-names = "default";
- pinctrl-0 = <&is31_sdb_pins>;
- shutdown-gpios = <&cp0_gpio1 30 GPIO_ACTIVE_HIGH>;
- reg = <0x64>;
-
- led1_red: led@1 {
- label = "red:led1";
- reg = <1>;
- led-max-microamp = <20000>;
- };
-
- led1_green: led@2 {
- label = "green:led1";
- reg = <2>;
- };
-
- led1_blue: led@3 {
- label = "blue:led1";
- reg = <3>;
- };
-
- led2_red: led@4 {
- label = "red:led2";
- reg = <4>;
- };
-
- led2_green: led@5 {
- label = "green:led2";
- reg = <5>;
- };
-
- led2_blue: led@6 {
- label = "blue:led2";
- reg = <6>;
- };
-
- led3_red: led@7 {
- label = "red:led3";
- reg = <7>;
- };
-
- led3_green: led@8 {
- label = "green:led3";
- reg = <8>;
- };
-
- led3_blue: led@9 {
- label = "blue:led3";
- reg = <9>;
- };
- };
-};
-
-&cp0_mdio {
- status = "okay";
-
- /* 88E1512 PHY */
- eth2phy: ethernet-phy@1 {
- reg = <1>;
- sfp = <&sfp_eth2>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_phy_pins>;
- reset-gpios = <&cp0_gpio1 12 GPIO_ACTIVE_LOW>;
- };
-
- /* 88E6141 Topaz switch */
- switch: switch@3 {
- compatible = "marvell,mv88e6085";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <3>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_switch_pins>;
- reset-gpios = <&cp0_gpio1 0 GPIO_ACTIVE_LOW>;
-
- interrupt-parent = <&cp0_gpio1>;
- interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- swport1: port@1 {
- reg = <1>;
- label = "lan0";
- phy-handle = <&swphy1>;
- };
-
- swport2: port@2 {
- reg = <2>;
- label = "lan1";
- phy-handle = <&swphy2>;
- };
-
- swport3: port@3 {
- reg = <3>;
- label = "lan2";
- phy-handle = <&swphy3>;
- };
-
- swport4: port@4 {
- reg = <4>;
- label = "lan3";
- phy-handle = <&swphy4>;
- };
-
- port@5 {
- reg = <5>;
- ethernet = <&cp0_eth1>;
- phy-mode = "2500base-x";
- managed = "in-band-status";
- };
- };
-
- mdio {
- #address-cells = <1>;
- #size-cells = <0>;
-
- swphy1: swphy1@17 {
- reg = <17>;
- };
-
- swphy2: swphy2@18 {
- reg = <18>;
- };
-
- swphy3: swphy3@19 {
- reg = <19>;
- };
-
- swphy4: swphy4@20 {
- reg = <20>;
- };
- };
- };
-};
-
-&cp0_ethernet {
- status = "okay";
-};
-
-/* 10G SFP+ */
-&cp0_eth0 {
- status = "okay";
-
- phy-mode = "10gbase-r";
- phys = <&cp0_comphy4 0>;
- managed = "in-band-status";
- sfp = <&sfp_eth0>;
-};
-
-/* Topaz switch uplink */
-&cp0_eth1 {
- status = "okay";
-
- phy-mode = "2500base-x";
- phys = <&cp0_comphy0 1>;
-
- fixed-link {
- speed = <2500>;
- full-duplex;
- };
-};
-
-/* 1G SFP or 1G RJ45 */
-&cp0_eth2 {
- status = "okay";
-
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_rgmii1_pins>;
-
- phy = <ð2phy>;
- phy-mode = "rgmii-id";
-};
-
-/* SMSC USB5434B hub */
-&cp0_usb3_0 {
- status = "okay";
-
- phys = <&cp0_comphy1 0>;
- phy-names = "cp0-usb3h0-comphy";
-};
-
-/* miniPCI-E USB */
-&cp0_usb3_1 {
- status = "okay";
-};
-
-&cp0_sata0 {
- status = "okay";
-
- /* 7 + 12 SATA connector (J24) */
- sata-port@0 {
- phys = <&cp0_comphy2 0>;
- phy-names = "cp0-sata0-0-phy";
- };
-
- /* M.2-2250 B-key (J39) */
- sata-port@1 {
- phys = <&cp0_comphy3 1>;
- phy-names = "cp0-sata0-1-phy";
- };
-};
-
-/* miniPCI-E (J5) */
-&cp0_pcie2 {
- status = "okay";
-
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_pcie_reset_pins>;
- phys = <&cp0_comphy5 2>;
- phy-names = "cp0-pcie2-x1-phy";
- reset-gpio = <&cp0_gpio1 9 GPIO_ACTIVE_LOW>;
- ranges = <0x82000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x8000000>;
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright SolidRun Ltd.
- * Copyright (C) 2024 Tobias Schramm <tobias@t-sys.eu>
- *
- * Device tree for the CN9130-based ClearFog Pro
- */
-
-#include "cn9130.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-
-/ {
- model = "SolidRun ClearFog Pro";
- compatible = "solidrun,clearfog-pro", "marvell,armada-ap807-quad",
- "marvell,armada-ap807";
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- aliases {
- gpio1 = &cp0_gpio1;
- gpio2 = &cp0_gpio2;
- i2c0 = &cp0_i2c0;
- ethernet0 = &cp0_eth0;
- ethernet1 = &cp0_eth1;
- ethernet2 = &cp0_eth2;
- spi1 = &cp0_spi1;
- };
-
- memory@00000000 {
- reg = <0x0 0x0 0x1 0x0>;
- device_type = "memory";
- };
-
- /* Virtual regulator, root of power tree */
- vin: regulator-vin {
- compatible = "regulator-fixed";
- regulator-name = "vin";
- regulator-always-on;
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- };
-
- /* Regulators supplied by vin */
- v_5v0: regulator-v_5v0 {
- compatible = "regulator-fixed";
- regulator-name = "v_5v0";
- regulator-always-on;
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- vin-supply = <&vin>;
- };
-
- v_3v3: regulator-v_3v3 {
- compatible = "regulator-fixed";
- regulator-name = "v_3v3";
- regulator-always-on;
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- vin-supply = <&vin>;
- };
-
- /* Regulators supplied by v_5v0 */
- v_1v8: regulator-v_1v8 {
- compatible = "regulator-fixed";
- regulator-name = "v_1v8";
- regulator-always-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- vin-supply = <&v_5v0>;
- };
-
- v_5v0_usb3_hst_vbus: regulator-v_5v0_usb3_hst_vbus {
- compatible = "regulator-fixed";
- regulator-name = "v_5v0_usb3_hst_vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&expander0 6 GPIO_ACTIVE_LOW>;
- vin-supply = <&v_5v0>;
- };
-
- /* Regulators internal to SOM */
- vqmmc: regulator-vqmmc {
- compatible = "regulator-fixed";
- regulator-name = "vqmmc";
- regulator-always-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- vin-supply = <&v_5v0>;
- };
-
- cp0_usb3_0_phy1: cp0_usb3_phy@1 {
- compatible = "usb-nop-xceiv";
- vbus-supply = <&v_5v0_usb3_hst_vbus>;
- };
-
- cp0_sfp_eth0: sfp-eth@0 {
- compatible = "sff,sfp";
- i2c-bus = <&cp0_i2c1>;
- los-gpio = <&expander0 12 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&expander0 15 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&expander0 14 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&expander0 13 GPIO_ACTIVE_HIGH>;
- maximum-power-milliwatt = <2000>;
- };
-
- keys {
- compatible = "gpio-keys";
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_button_pin>;
-
- reset {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&cp0_gpio2 0 GPIO_ACTIVE_LOW>;
- };
- };
-};
-
-&uart0 {
- status = "okay";
-};
-
-/* on-board eMMC */
-&ap_sdhci0 {
- bus-width = <8>;
- pinctrl-names = "default";
- vqmmc-supply = <&vqmmc>;
- status = "okay";
-};
-
-&cp0_crypto {
- status = "okay";
-};
-
-&cp0_ethernet {
- status = "okay";
-};
-
-&cp0_gpio1 {
- status = "okay";
-};
-
-&cp0_gpio2 {
- status = "okay";
-};
-
-&cp0_i2c0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_i2c0_pins>;
- clock-frequency = <100000>;
-
- /*
- * PCA9655 GPIO expander, up to 1MHz clock.
- * 0-CON3 CLKREQ#
- * 1-CON3 PERST#
- * 2-CON2 PERST#
- * 3-CON3 W_DISABLE
- * 4-CON2 CLKREQ#
- * 5-USB3 overcurrent
- * 6-USB3 power
- * 7-CON2 W_DISABLE
- * 8-JP4 P1
- * 9-JP4 P4
- * 10-JP4 P5
- * 11-m.2 DEVSLP
- * 12-SFP_LOS
- * 13-SFP_TX_FAULT
- * 14-SFP_TX_DISABLE
- * 15-SFP_MOD_DEF0
- */
- expander0: gpio-expander@20 {
- compatible = "nxp,pca9555";
- reg = <0x20>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- interrupt-parent = <&cp0_gpio1>;
- interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_expander0_pins>;
- vcc-supply = <&v_3v3>;
-
- pcie1_0_clkreq {
- gpio-hog;
- gpios = <0 GPIO_ACTIVE_LOW>;
- input;
- line-name = "pcie1.0-clkreq";
- };
-
- pcie1_0_w_disable {
- gpio-hog;
- gpios = <3 GPIO_ACTIVE_LOW>;
- output-low;
- line-name = "pcie1.0-w-disable";
- };
-
- pcie2_0_clkreq {
- gpio-hog;
- gpios = <4 GPIO_ACTIVE_LOW>;
- input;
- line-name = "pcie2.0-clkreq";
- };
-
- pcie2_0_w_disable {
- gpio-hog;
- gpios = <7 GPIO_ACTIVE_LOW>;
- output-low;
- line-name = "pcie2.0-w-disable";
- };
-
- usb3_ilimit {
- gpio-hog;
- gpios = <5 GPIO_ACTIVE_LOW>;
- input;
- line-name = "usb3-current-limit";
- };
-
- m2_devslp {
- gpio-hog;
- gpios = <11 GPIO_ACTIVE_HIGH>;
- output-low;
- line-name = "m.2 devslp";
- };
- };
-
- /* ADC only for mikroBUS connector */
- mcp3021@4c {
- compatible = "microchip,mcp3021";
- reg = <0x4c>;
- };
-
- /* EEPROM on the SOM */
- eeprom@53 {
- compatible = "atmel,24c02";
- reg = <0x53>;
- pagesize = <16>;
- read-only;
-
- nvmem-layout {
- compatible = "onie,tlv-layout";
-
- onie_tlv_macaddr: mac-address {
- #nvmem-cell-cells = <1>;
- };
- };
- };
-};
-
-/* SMBUS on mini PCIe sockets */
-&cp0_i2c1 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_i2c1_pins>;
- clock-frequency = <100000>;
-};
-
-&cp0_mdio {
- status = "okay";
-
- phy0: ethernet-phy@0 {
- reg = <0>;
- /* Green led blinks on activity, orange LED on link */
- marvell,reg-init = <3 16 0 0x0064>;
- };
-
- switch@4 {
- compatible = "marvell,mv88e6085";
- reg = <4>;
- interrupt-controller;
- #interrupt-cells = <2>;
- interrupt-parent = <&cp0_gpio1>;
- interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_dsa0_pins>;
- reset-gpios = <&cp0_gpio1 27 GPIO_ACTIVE_LOW>;
-
- mdio-external {
- compatible = "marvell,mv88e6xxx-mdio-external";
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* 88E1512 PHY */
- port6_phy: ethernet-phy@1 {
- reg = <1>;
- };
- };
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- label = "lan5";
- };
-
- 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>;
- ethernet = <&cp0_eth1>;
- label = "cpu";
- phy-mode = "rgmii-id";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
-
- port@6 {
- /* 88E1512 external phy */
- reg = <6>;
- label = "lan6";
- phy-handle = <&port6_phy>;
- phy-mode = "rgmii-id";
- };
- };
- };
-};
-
-/* SRDS #0 - SATA on bottom M.2 B-Key connector */
-&cp0_sata0 {
- status = "okay";
-
- sata-port@0 {
- status = "disabled";
- };
-
- sata-port@1 {
- phys = <&cp0_comphy0 1>;
- target-supply = <&v_3v3>;
- };
-};
-
-&cp0_utmi {
- status = "okay";
-};
-
-/* mini PCIe slot far from SOM, USB 2.0 only, SS lanes unused */
-&cp0_usb3_0 {
- status = "okay";
- phys = <&cp0_utmi0>;
- phy-names = "utmi";
- dr_mode = "host";
-};
-
-/* SRDS #1 - USB-A 3.0 host port */
-&cp0_usb3_1 {
- status = "okay";
- phys = <&cp0_utmi1>, <&cp0_comphy1 0>;
- phy-names = "utmi", "usb";
- usb-phy = <&cp0_usb3_0_phy1>;
- dr_mode = "host";
-};
-
-/* SRDS #2 - SFP+ 10GE */
-&cp0_eth0 {
- status = "okay";
- phy-mode = "10gbase-r";
- phys = <&cp0_comphy2 0>;
- managed = "in-band-status";
- nvmem-cells = <&onie_tlv_macaddr 0>;
- nvmem-cell-names = "mac-address";
- sfp = <&cp0_sfp_eth0>;
-};
-
-/* SRDS #3 - SGMII 1GE to L2 switch */
-&cp0_eth1 {
- status = "okay";
- phys = <&cp0_comphy3 1>;
- phy-mode = "sgmii";
- nvmem-cells = <&onie_tlv_macaddr 1>;
- nvmem-cell-names = "mac-address";
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
-};
-
-/* SRDS #4 - mini PCIe slot near SOM */
-&cp0_pcie1 {
- status = "okay";
- phys = <&cp0_comphy4 1>;
- num-lanes = <1>;
- reset-gpios = <&expander0 2 GPIO_ACTIVE_LOW>;
-};
-
-/* SRDS #5 - mini PCIe slot far from SOM */
-&cp0_pcie2 {
- status = "okay";
- phys = <&cp0_comphy5 2>;
- num-lanes = <1>;
- reset-gpios = <&expander0 1 GPIO_ACTIVE_LOW>;
-};
-
-/* GE PHY RGMII */
-&cp0_eth2 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_ge2_rgmii_pins>;
- phy = <&phy0>;
- phy-mode = "rgmii-id";
- nvmem-cells = <&onie_tlv_macaddr 2>;
- nvmem-cell-names = "mac-address";
-};
-
-/* micro SD card slot */
-&cp0_sdhci0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_sdhci_pins &cp0_sdhci_cd_pins>;
- bus-width = <4>;
- cd-gpios = <&cp0_gpio2 11 GPIO_ACTIVE_LOW>;
- no-1-8-v;
- vqmmc-supply = <&v_3v3>;
- vmmc-supply = <&v_3v3>;
-};
-
-&cp0_spi1 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_spi1_pins>;
-
- spi-flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0x0>;
- #address-cells = <0x1>;
- #size-cells = <0x1>;
- spi-max-frequency = <10000000>;
- };
-};
-
-&cp0_syscon0 {
- cp0_pinctrl: pinctrl {
- compatible = "marvell,cp115-standalone-pinctrl";
-
- cp0_i2c0_pins: cp0-i2c0-pins {
- marvell,pins = "mpp37", "mpp38";
- marvell,function = "i2c0";
- };
-
- cp0_i2c1_pins: cp0-i2c1-pins {
- marvell,pins = "mpp35", "mpp36";
- marvell,function = "i2c1";
- };
-
- cp0_ge2_rgmii_pins: cp0-ge2-rgmii-pins {
- marvell,pins = "mpp44", "mpp45", "mpp46",
- "mpp47", "mpp48", "mpp49",
- "mpp50", "mpp51", "mpp52",
- "mpp53", "mpp54", "mpp55";
- marvell,function = "ge1";
- };
-
- cp0_sdhci_cd_pins: cp0-sdhci-cd-pins {
- marvell,pins = "mpp43";
- marvell,function = "sdio";
- };
-
- cp0_sdhci_pins: cp0-sdhci-pins {
- marvell,pins = "mpp56", "mpp57", "mpp58",
- "mpp59", "mpp60", "mpp61";
- marvell,function = "sdio";
- };
-
- cp0_spi1_pins: cp0-spi1-pins {
- marvell,pins = "mpp12", "mpp13", "mpp14",
- "mpp15", "mpp16";
- marvell,function = "spi1";
- };
-
- cp0_dsa0_pins: cp0-dsa0-pins {
- marvell,pins = "mpp27", "mpp29";
- marvell,function = "gpio";
- };
-
- cp0_button_pin: cp0-button-pin {
- marvell,pins = "mpp32";
- marvell,function = "gpio";
- };
-
- cp0_expander0_pins: cp0-expander0-pins {
- marvell,pins = "mpp4";
- marvell,function = "gpio";
- };
- };
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
-/*
- * Copyright (C) 2019 Marvell International Ltd.
- *
- * Device tree for the CN9131-DB board.
- */
-
-#include "cn9130.dtsi"
-#include "puzzle-thermal.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-
-/ {
- model = "iEi Puzzle-M901";
- compatible = "iei,puzzle-m901",
- "marvell,armada-ap807-quad", "marvell,armada-ap807";
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- aliases {
- i2c0 = &cp1_i2c0;
- i2c1 = &cp0_i2c0;
- ethernet0 = &cp0_eth0;
- ethernet1 = &cp0_eth1;
- ethernet2 = &cp0_eth2;
- ethernet3 = &cp1_eth0;
- ethernet4 = &cp1_eth1;
- ethernet5 = &cp1_eth2;
- gpio1 = &cp0_gpio1;
- gpio2 = &cp0_gpio2;
- gpio3 = &cp1_gpio1;
- gpio4 = &cp1_gpio2;
- led-boot = &led_power;
- led-failsafe = &led_info;
- led-running = &led_power;
- led-upgrade = &led_info;
- };
-
- memory@00000000 {
- device_type = "memory";
- reg = <0x0 0x0 0x0 0x80000000>;
- };
-
- gpio_keys {
- compatible = "gpio-keys";
-
- reset {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&cp0_gpio2 4 GPIO_ACTIVE_LOW>;
- };
- };
-};
-
-&uart0 {
- status = "okay";
-};
-
-&cp0_uart0 {
- status = "okay";
-
- puzzle-mcu {
- compatible = "iei,wt61p803-puzzle";
- #address-cells = <1>;
- #size-cells = <1>;
- current-speed = <115200>;
- enable-beep;
- status = "okay";
-
- leds {
- compatible = "iei,wt61p803-puzzle-leds";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "okay";
-
- led@0 {
- reg = <0>;
- label = "white:network";
- active-low;
- };
-
- led@1 {
- reg = <1>;
- label = "green:cloud";
- active-low;
- };
-
- led_info: led@2 {
- reg = <2>;
- label = "orange:info";
- active-low;
- };
-
- led_power: led@3 {
- reg = <3>;
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_YELLOW>;
- active-low;
- default-state = "on";
- };
- };
-
- hwmon {
- compatible = "iei,wt61p803-puzzle-hwmon";
- #address-cells = <1>;
- #size-cells = <0>;
-
- chassis_fan_group0: fan-group@0 {
- #cooling-cells = <2>;
- reg = <0x00>;
- cooling-levels = <0 159 195 211 223 241 255>;
- };
- };
- };
-};
-
-&ap_thermal_ic {
- PUZZLE_FAN_THERMAL(ic, &chassis_fan_group0);
-};
-
-&cp0_thermal_ic {
- PUZZLE_FAN_THERMAL(cp0, &chassis_fan_group0);
-};
-
-/* on-board eMMC - U9 */
-&ap_sdhci0 {
- pinctrl-names = "default";
- bus-width = <8>;
- status = "okay";
- mmc-ddr-1_8v;
- mmc-hs400-1_8v;
-};
-
-&cp0_crypto {
- status = "okay";
-};
-
-&cp0_xmdio {
- status = "okay";
- cp0_nbaset_phy0: ethernet-phy@0 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <2>;
- };
- cp0_nbaset_phy1: ethernet-phy@1 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <0>;
- };
- cp0_nbaset_phy2: ethernet-phy@2 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <8>;
- };
-};
-
-&cp0_ethernet {
- status = "okay";
-};
-
-/* SLM-1521-V2, CON9 */
-&cp0_eth0 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp0_comphy2 0>;
- phy = <&cp0_nbaset_phy0>;
-};
-
-&cp0_eth1 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp0_comphy4 1>;
- phy = <&cp0_nbaset_phy1>;
-};
-
-&cp0_eth2 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp0_comphy5 2>;
- phy = <&cp0_nbaset_phy2>;
-};
-
-&cp0_gpio1 {
- status = "okay";
-};
-
-&cp0_gpio2 {
- status = "okay";
-};
-
-&cp0_i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_i2c0_pins>;
- status = "okay";
- clock-frequency = <100000>;
- rtc@32 {
- compatible = "epson,rx8130";
- reg = <0x32>;
- wakeup-source;
- };
-};
-
-/* SLM-1521-V2, CON6 */
-&cp0_pcie0 {
- status = "okay";
- num-lanes = <2>;
- num-viewport = <8>;
- phys = <&cp0_comphy0 0>, <&cp0_comphy1 0>;
-};
-
-/* U55 */
-&cp0_spi1 {
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_spi0_pins>;
- reg = <0x700680 0x50>, /* control */
- <0x2000000 0x1000000>; /* CS0 */
- status = "okay";
- spi-flash@0 {
- #address-cells = <0x1>;
- #size-cells = <0x1>;
- compatible = "jedec,spi-nor";
- reg = <0x0>;
- spi-max-frequency = <40000000>;
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "U-Boot";
- reg = <0x0 0x1f0000>;
- };
- partition@1f0000 {
- label = "U-Boot ENV Factory";
- reg = <0x1f0000 0x10000>;
- };
- partition@200000 {
- label = "Reserved";
- reg = <0x200000 0x1f0000>;
- };
- partition@3f0000 {
- label = "U-Boot ENV";
- reg = <0x3f0000 0x10000>;
- };
- };
- };
-};
-
-&cp0_rtc {
- status = "disabled";
-};
-
-&cp0_syscon0 {
- cp0_pinctrl: pinctrl {
- compatible = "marvell,cp115-standalone-pinctrl";
- cp0_i2c0_pins: cp0-i2c-pins-0 {
- marvell,pins = "mpp37", "mpp38";
- marvell,function = "i2c0";
- };
- cp0_i2c1_pins: cp0-i2c-pins-1 {
- marvell,pins = "mpp35", "mpp36";
- marvell,function = "i2c1";
- };
- cp0_ge1_rgmii_pins: cp0-ge-rgmii-pins-0 {
- marvell,pins = "mpp0", "mpp1", "mpp2",
- "mpp3", "mpp4", "mpp5",
- "mpp6", "mpp7", "mpp8",
- "mpp9", "mpp10", "mpp11";
- marvell,function = "ge0";
- };
- cp0_ge2_rgmii_pins: cp0-ge-rgmii-pins-1 {
- marvell,pins = "mpp44", "mpp45", "mpp46",
- "mpp47", "mpp48", "mpp49",
- "mpp50", "mpp51", "mpp52",
- "mpp53", "mpp54", "mpp55";
- marvell,function = "ge1";
- };
- cp0_spi0_pins: cp0-spi-pins-0 {
- marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
- marvell,function = "spi1";
- };
- };
-};
-
-/*
- * Instantiate the first connected CP115
- */
-
-#define CP11X_NAME cp1
-#define CP11X_BASE f6000000
-#define CP11X_PCIEx_MEM_BASE(iface) (0xe2000000 + (iface * 0x1000000))
-#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
-#define CP11X_PCIE0_BASE f6600000
-#define CP11X_PCIE1_BASE f6620000
-#define CP11X_PCIE2_BASE f6640000
-
-#include "armada-cp115.dtsi"
-
-#undef CP11X_NAME
-#undef CP11X_BASE
-#undef CP11X_PCIEx_MEM_BASE
-#undef CP11X_PCIEx_MEM_SIZE
-#undef CP11X_PCIE0_BASE
-#undef CP11X_PCIE1_BASE
-#undef CP11X_PCIE2_BASE
-
-&cp1_crypto {
- status = "okay";
-};
-
-&cp1_xmdio {
- status = "okay";
- cp1_nbaset_phy0: ethernet-phy@3 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <2>;
- };
- cp1_nbaset_phy1: ethernet-phy@4 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <0>;
- };
- cp1_nbaset_phy2: ethernet-phy@5 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <8>;
- };
-};
-
-&cp1_ethernet {
- status = "okay";
-};
-
-/* CON50 */
-&cp1_eth0 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp1_comphy2 0>;
- phy = <&cp1_nbaset_phy0>;
-};
-
-&cp1_eth1 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp1_comphy4 1>;
- phy = <&cp1_nbaset_phy1>;
-};
-
-&cp1_eth2 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp1_comphy5 2>;
- phy = <&cp1_nbaset_phy2>;
-};
-
-&cp1_sata0 {
- status = "okay";
- sata-port@1 {
- status = "okay";
- phys = <&cp1_comphy0 1>;
- };
-};
-
-&cp1_gpio1 {
- status = "okay";
-};
-
-&cp1_gpio2 {
- status = "okay";
-};
-
-&cp1_i2c0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&cp1_i2c0_pins>;
- clock-frequency = <100000>;
-};
-
-&cp1_rtc {
- status = "disabled";
-};
-
-&cp1_syscon0 {
- cp1_pinctrl: pinctrl {
- compatible = "marvell,cp115-standalone-pinctrl";
- cp1_i2c0_pins: cp1-i2c-pins-0 {
- marvell,pins = "mpp37", "mpp38";
- marvell,function = "i2c0";
- };
- cp1_spi0_pins: cp1-spi-pins-0 {
- marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
- marvell,function = "spi1";
- };
- cp1_xhci0_vbus_pins: cp1-xhci0-vbus-pins {
- marvell,pins = "mpp3";
- marvell,function = "gpio";
- };
- cp1_sfp_pins: sfp-pins {
- marvell,pins = "mpp8", "mpp9", "mpp10", "mpp11";
- marvell,function = "gpio";
- };
- };
-};
-
-&cp1_thermal_ic {
- PUZZLE_FAN_THERMAL(cp1, &chassis_fan_group0);
-};
-
-&cp1_usb3_1 {
- status = "okay";
- phys = <&cp1_comphy3 1>;
- phy-names = "usb";
-};
+++ /dev/null
-// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
-/*
- * Copyright (C) 2019 Marvell International Ltd.
- *
- * Device tree for the CN9132-DB board.
- */
-
-#include "cn9130.dtsi"
-#include "puzzle-thermal.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-
-/ {
- model = "iEi Puzzle-M902";
- compatible = "iei,puzzle-m902",
- "marvell,armada-ap807-quad", "marvell,armada-ap807";
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
- aliases {
- i2c0 = &cp1_i2c0;
- i2c1 = &cp0_i2c0;
- gpio1 = &cp0_gpio1;
- gpio2 = &cp0_gpio2;
- gpio3 = &cp1_gpio1;
- gpio4 = &cp1_gpio2;
- gpio5 = &cp2_gpio1;
- gpio6 = &cp2_gpio2;
- ethernet0 = &cp0_eth0;
- ethernet1 = &cp0_eth1;
- ethernet2 = &cp0_eth2;
- ethernet3 = &cp1_eth0;
- ethernet4 = &cp1_eth1;
- ethernet5 = &cp1_eth2;
- ethernet6 = &cp2_eth0;
- ethernet7 = &cp2_eth1;
- ethernet8 = &cp2_eth2;
- spi1 = &cp0_spi0;
- spi2 = &cp0_spi1;
- led-boot = &led_power;
- led-failsafe = &led_info;
- led-running = &led_power;
- led-upgrade = &led_info;
- };
-
- memory@00000000 {
- device_type = "memory";
- reg = <0x0 0x0 0x0 0x80000000>;
- };
-
- gpio_keys {
- compatible = "gpio-keys";
-
- reset {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&cp0_gpio2 4 GPIO_ACTIVE_LOW>;
- };
- };
-
- cp2_reg_usb3_vbus0: cp2_usb3_vbus@0 {
- compatible = "regulator-fixed";
- regulator-name = "cp2-xhci0-vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- gpio = <&cp2_gpio1 2 GPIO_ACTIVE_HIGH>;
- };
-
- cp2_usb3_0_phy0: cp2_usb3_phy0 {
- compatible = "usb-nop-xceiv";
- vcc-supply = <&cp2_reg_usb3_vbus0>;
- };
-
- cp2_reg_usb3_vbus1: cp2_usb3_vbus@1 {
- compatible = "regulator-fixed";
- regulator-name = "cp2-xhci1-vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- gpio = <&cp2_gpio1 3 GPIO_ACTIVE_HIGH>;
- };
-
- cp2_usb3_0_phy1: cp2_usb3_phy1 {
- compatible = "usb-nop-xceiv";
- vcc-supply = <&cp2_reg_usb3_vbus1>;
- };
-
- cp2_sfp_eth0: sfp-eth0 {
- compatible = "sff,sfp";
- i2c-bus = <&cp2_sfpp0_i2c>;
- los-gpio = <&cp2_module_expander1 11 GPIO_ACTIVE_HIGH>;
- mod-def0-gpio = <&cp2_module_expander1 10 GPIO_ACTIVE_LOW>;
- tx-disable-gpio = <&cp2_module_expander1 9 GPIO_ACTIVE_HIGH>;
- tx-fault-gpio = <&cp2_module_expander1 8 GPIO_ACTIVE_HIGH>;
- status = "disabled";
- };
-};
-
-&uart0 {
- status = "okay";
-};
-
-&cp0_uart0 {
- status = "okay";
-
- puzzle-mcu {
- compatible = "iei,wt61p803-puzzle";
- #address-cells = <1>;
- #size-cells = <1>;
- current-speed = <115200>;
- enable-beep;
- status = "okay";
-
- leds {
- compatible = "iei,wt61p803-puzzle-leds";
- #address-cells = <1>;
- #size-cells = <0>;
- status = "okay";
-
- led@0 {
- reg = <0>;
- label = "white:network";
- active-low;
- };
-
- led@1 {
- reg = <1>;
- label = "green:cloud";
- active-low;
- };
-
- led_info: led@2 {
- reg = <2>;
- label = "orange:info";
- active-low;
- };
-
- led_power: led@3 {
- reg = <3>;
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_YELLOW>;
- active-low;
- default-state = "on";
- };
- };
-
- hwmon {
- compatible = "iei,wt61p803-puzzle-hwmon";
- #address-cells = <1>;
- #size-cells = <0>;
-
- chassis_fan_group0: fan-group@0 {
- #cooling-cells = <2>;
- reg = <0x00>;
- cooling-levels = <0 159 195 211 223 241 255>;
- };
- };
- };
-};
-
-&ap_thermal_ic {
- PUZZLE_FAN_THERMAL(ic, &chassis_fan_group0);
-};
-
-&cp0_thermal_ic {
- PUZZLE_FAN_THERMAL(cp0, &chassis_fan_group0);
-};
-
-
-/* on-board eMMC - U9 */
-&ap_sdhci0 {
- pinctrl-names = "default";
- bus-width = <8>;
- status = "okay";
- mmc-ddr-1_8v;
- mmc-hs400-1_8v;
-};
-
-&cp0_crypto {
- status = "okay";
-};
-
-&cp0_xmdio {
- status = "okay";
- cp0_nbaset_phy0: ethernet-phy@0 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <2>;
- };
- cp0_nbaset_phy1: ethernet-phy@1 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <0>;
- };
- cp0_nbaset_phy2: ethernet-phy@2 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <8>;
- };
-};
-
-&cp0_ethernet {
- status = "okay";
-};
-
-/* SLM-1521-V2, CON9 */
-&cp0_eth0 {
- status = "okay";
- phy-mode = "10gbase-kr";
- phys = <&cp0_comphy2 0>;
- phy = <&cp0_nbaset_phy0>;
-};
-
-&cp0_eth1 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp0_comphy4 1>;
- phy = <&cp0_nbaset_phy1>;
-};
-
-&cp0_eth2 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp0_comphy1 2>;
- phy = <&cp0_nbaset_phy2>;
-};
-
-&cp0_gpio1 {
- status = "okay";
-};
-
-&cp0_gpio2 {
- status = "okay";
-};
-
-&cp0_i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_i2c0_pins>;
- status = "okay";
- clock-frequency = <100000>;
- rtc@32 {
- compatible = "epson,rx8130";
- reg = <0x32>;
- wakeup-source;
- };
-};
-
-&cp0_i2c1 {
- clock-frequency = <100000>;
-};
-
-/* SLM-1521-V2, CON6 */
-&cp0_sata0 {
- status = "okay";
- sata-port@1 {
- status = "okay";
- phys = <&cp0_comphy0 1>;
- };
-};
-
-&cp0_pcie2 {
- status = "okay";
- num-lanes = <1>;
- num-viewport = <8>;
- phys = <&cp0_comphy5 2>;
-};
-
-/* U55 */
-&cp0_spi1 {
- pinctrl-names = "default";
- pinctrl-0 = <&cp0_spi0_pins>;
- reg = <0x700680 0x50>, /* control */
- <0x2000000 0x1000000>; /* CS0 */
- status = "okay";
- spi-flash@0 {
- #address-cells = <0x1>;
- #size-cells = <0x1>;
- compatible = "jedec,spi-nor";
- reg = <0x0>;
- spi-max-frequency = <40000000>;
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
- partition@0 {
- label = "U-Boot";
- reg = <0x0 0x1f0000>;
- };
- partition@1f0000 {
- label = "U-Boot ENV Factory";
- reg = <0x1f0000 0x10000>;
- };
- partition@200000 {
- label = "Reserved";
- reg = <0x200000 0x1f0000>;
- };
- partition@3f0000 {
- label = "U-Boot ENV";
- reg = <0x3f0000 0x10000>;
- };
- };
- };
-};
-
-&cp0_rtc {
- status = "disabled";
-};
-
-&cp0_syscon0 {
- cp0_pinctrl: pinctrl {
- compatible = "marvell,cp115-standalone-pinctrl";
- cp0_i2c0_pins: cp0-i2c-pins-0 {
- marvell,pins = "mpp37", "mpp38";
- marvell,function = "i2c0";
- };
- cp0_i2c1_pins: cp0-i2c-pins-1 {
- marvell,pins = "mpp35", "mpp36";
- marvell,function = "i2c1";
- };
- cp0_ge1_rgmii_pins: cp0-ge-rgmii-pins-0 {
- marvell,pins = "mpp0", "mpp1", "mpp2",
- "mpp3", "mpp4", "mpp5",
- "mpp6", "mpp7", "mpp8",
- "mpp9", "mpp10", "mpp11";
- marvell,function = "ge0";
- };
- cp0_ge2_rgmii_pins: cp0-ge-rgmii-pins-1 {
- marvell,pins = "mpp44", "mpp45", "mpp46",
- "mpp47", "mpp48", "mpp49",
- "mpp50", "mpp51", "mpp52",
- "mpp53", "mpp54", "mpp55";
- marvell,function = "ge1";
- };
- cp0_spi0_pins: cp0-spi-pins-0 {
- marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
- marvell,function = "spi1";
- };
- };
-};
-
-&cp0_usb3_1 {
- status = "okay";
- phys = <&cp0_comphy3 1>;
- phy-names = "usb";
-};
-
-/*
- * Instantiate the first connected CP115
- */
-
-#define CP11X_NAME cp1
-#define CP11X_BASE f4000000
-#define CP11X_PCIEx_MEM_BASE(iface) (0xe2000000 + (iface * 0x1000000))
-#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
-#define CP11X_PCIE0_BASE f4600000
-#define CP11X_PCIE1_BASE f4620000
-#define CP11X_PCIE2_BASE f4640000
-
-#include "armada-cp115.dtsi"
-
-#undef CP11X_NAME
-#undef CP11X_BASE
-#undef CP11X_PCIEx_MEM_BASE
-#undef CP11X_PCIEx_MEM_SIZE
-#undef CP11X_PCIE0_BASE
-#undef CP11X_PCIE1_BASE
-#undef CP11X_PCIE2_BASE
-
-&cp1_crypto {
- status = "okay";
-};
-
-&cp1_xmdio {
- status = "okay";
- cp1_nbaset_phy0: ethernet-phy@3 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <2>;
- };
- cp1_nbaset_phy1: ethernet-phy@4 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <0>;
- };
- cp1_nbaset_phy2: ethernet-phy@5 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <8>;
- };
-};
-
-&cp1_ethernet {
- status = "okay";
-};
-
-/* CON50 */
-&cp1_eth0 {
- status = "okay";
- phy-mode = "10gbase-kr";
- phys = <&cp1_comphy2 0>;
- phy = <&cp1_nbaset_phy0>;
-};
-
-&cp1_eth1 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp1_comphy4 1>;
- phy = <&cp1_nbaset_phy1>;
-};
-
-&cp1_eth2 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp1_comphy1 2>;
- phy = <&cp1_nbaset_phy2>;
-};
-
-&cp1_gpio1 {
- status = "okay";
-};
-
-&cp1_gpio2 {
- status = "okay";
-};
-
-&cp1_i2c0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&cp1_i2c0_pins>;
- clock-frequency = <100000>;
-};
-
-&cp1_rtc {
- status = "disabled";
-};
-
-&cp1_syscon0 {
- cp1_pinctrl: pinctrl {
- compatible = "marvell,cp115-standalone-pinctrl";
- cp1_i2c0_pins: cp1-i2c-pins-0 {
- marvell,pins = "mpp37", "mpp38";
- marvell,function = "i2c0";
- };
- cp1_spi0_pins: cp1-spi-pins-0 {
- marvell,pins = "mpp13", "mpp14", "mpp15", "mpp16";
- marvell,function = "spi1";
- };
- cp1_xhci0_vbus_pins: cp1-xhci0-vbus-pins {
- marvell,pins = "mpp3";
- marvell,function = "gpio";
- };
- };
-};
-
-&cp1_thermal_ic {
- PUZZLE_FAN_THERMAL(cp1, &chassis_fan_group0);
-};
-
-/*
- * Instantiate the second connected CP115
- */
-
-#define CP11X_NAME cp2
-#define CP11X_BASE f6000000
-#define CP11X_PCIEx_MEM_BASE(iface) (0xe5000000 + (iface * 0x1000000))
-#define CP11X_PCIEx_MEM_SIZE(iface) 0xf00000
-#define CP11X_PCIE0_BASE f6600000
-#define CP11X_PCIE1_BASE f6620000
-#define CP11X_PCIE2_BASE f6640000
-
-#include "armada-cp115.dtsi"
-
-#undef CP11X_NAME
-#undef CP11X_BASE
-#undef CP11X_PCIEx_MEM_BASE
-#undef CP11X_PCIEx_MEM_SIZE
-#undef CP11X_PCIE0_BASE
-#undef CP11X_PCIE1_BASE
-#undef CP11X_PCIE2_BASE
-
-&cp2_crypto {
- status = "okay";
-};
-
-&cp2_ethernet {
- status = "okay";
-};
-
-&cp2_xmdio {
- status = "okay";
- cp2_nbaset_phy0: ethernet-phy@6 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <2>;
- };
- cp2_nbaset_phy1: ethernet-phy@7 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <0>;
- };
- cp2_nbaset_phy2: ethernet-phy@8 {
- compatible = "ethernet-phy-ieee802.3-c45";
- reg = <8>;
- };
-};
-
-/* SLM-1521-V2, CON9 */
-&cp2_eth0 {
- status = "okay";
- phy-mode = "10gbase-kr";
- phys = <&cp2_comphy2 0>;
- phy = <&cp2_nbaset_phy0>;
-};
-
-&cp2_eth1 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp2_comphy4 1>;
- phy = <&cp2_nbaset_phy1>;
-};
-
-&cp2_eth2 {
- status = "okay";
- phy-mode = "2500base-x";
- phys = <&cp2_comphy1 2>;
- phy = <&cp2_nbaset_phy2>;
-};
-
-&cp2_gpio1 {
- status = "okay";
-};
-
-&cp2_gpio2 {
- status = "okay";
-};
-
-&cp2_i2c0 {
- clock-frequency = <100000>;
- /* SLM-1521-V2 - U3 */
- i2c-mux@72 {
- compatible = "nxp,pca9544";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x72>;
- cp2_sfpp0_i2c: i2c@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0>;
- };
-
- i2c@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <1>;
- /* U12 */
- cp2_module_expander1: pca9555@21 {
- compatible = "nxp,pca9555";
- pinctrl-names = "default";
- gpio-controller;
- #gpio-cells = <2>;
- reg = <0x21>;
- };
- };
- };
-};
-
-&cp2_rtc {
- status = "disabled";
-};
-
-&cp2_syscon0 {
- cp2_pinctrl: pinctrl {
- compatible = "marvell,cp115-standalone-pinctrl";
- cp2_i2c0_pins: cp2-i2c-pins-0 {
- marvell,pins = "mpp37", "mpp38";
- marvell,function = "i2c0";
- };
- };
-};
-
-&cp2_thermal_ic {
- PUZZLE_FAN_THERMAL(cp2, &chassis_fan_group0);
-};
+++ /dev/null
-#define PUZZLE_FAN_THERMAL(_cname, _fan) \
- polling-delay-passive = <500>; \
- polling-delay = <1000>; \
- \
- trips { \
- cpu-hot { \
- temperature = <75000>; \
- hysteresis = <5000>; \
- type = "hot"; \
- }; \
- _cname##_active_full: cpu-active-full { \
- temperature = <70000>; \
- hysteresis = <5000>; \
- type = "active"; \
- }; \
- _cname##_active_high: cpu-active-high { \
- temperature = <65000>; \
- hysteresis = <5000>; \
- type = "active"; \
- }; \
- _cname##_active_med: cpu-active-med { \
- temperature = <62500>; \
- hysteresis = <3000>; \
- type = "active"; \
- }; \
- _cname##_active_low: cpu-active-low { \
- temperature = <60000>; \
- hysteresis = <3000>; \
- type = "active"; \
- }; \
- _cname##_active_min: cpu-active-min { \
- temperature = <55000>; \
- hysteresis = <5000>; \
- type = "active"; \
- }; \
- _cname##_active_idle: cpu-active-idle { \
- temperature = <50000>; \
- hysteresis = <5000>; \
- type = "active"; \
- }; \
- }; \
- cooling-maps { \
- cpu-active-full { \
- trip = <&_cname##_active_full>; \
- cooling-device = <_fan THERMAL_NO_LIMIT \
- THERMAL_NO_LIMIT>; \
- }; \
- cpu-active-high { \
- trip = <&_cname##_active_high>; \
- cooling-device = <_fan 4 5>; \
- }; \
- cpu-active-med { \
- trip = <&_cname##_active_med>; \
- cooling-device = <_fan 3 4>; \
- }; \
- cpu-active-low { \
- trip = <&_cname##_active_low>; \
- cooling-device = <_fan 2 3>; \
- }; \
- cpu-active-min { \
- trip = <&_cname##_active_min>; \
- cooling-device = <_fan 1 2>; \
- }; \
- cpu-active-idle { \
- trip = <&_cname##_active_idle>; \
- cooling-device = <_fan 0 0>; \
- }; \
- }
# Copyright (C) 2012-2016 OpenWrt.org
# Copyright (C) 2016 LEDE-project.org
-ifneq ($(KERNEL),6.1)
DTS_DIR := $(DTS_DIR)/marvell
-endif
define Build/fortigate-header
( \
+++ /dev/null
-From 8eec6e740b564ec5e1da59ab7070b89aa23c9973 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 16 Jun 2023 12:41:30 +0100
-Subject: [PATCH] cpufreq: armada-8k: add ap807 support
-
-Add support for the Armada AP807 die to armada-8k. This uses a
-different compatible for the CPU clock which needs to be added to
-the cpufreq driver.
-
-This commit takes a different approach to the WindRiver patch
-"cpufreq: armada: enable ap807-cpu-clk" in that rather than calling
-of_find_compatible_node() for each compatible, we use a table of
-IDs instead.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
----
- drivers/cpufreq/armada-8k-cpufreq.c | 16 +++++++++-------
- 1 file changed, 9 insertions(+), 7 deletions(-)
-
---- a/drivers/cpufreq/armada-8k-cpufreq.c
-+++ b/drivers/cpufreq/armada-8k-cpufreq.c
-@@ -21,6 +21,13 @@
- #include <linux/pm_opp.h>
- #include <linux/slab.h>
-
-+static const struct of_device_id __maybe_unused armada_8k_cpufreq_of_match[] = {
-+ { .compatible = "marvell,ap806-cpu-clock" },
-+ { .compatible = "marvell,ap807-cpu-clock" },
-+ { },
-+};
-+MODULE_DEVICE_TABLE(of, armada_8k_cpufreq_of_match);
-+
- /*
- * Setup the opps list with the divider for the max frequency, that
- * will be filled at runtime.
-@@ -127,7 +134,8 @@ static int __init armada_8k_cpufreq_init
- struct device_node *node;
- struct cpumask cpus;
-
-- node = of_find_compatible_node(NULL, NULL, "marvell,ap806-cpu-clock");
-+ node = of_find_matching_node_and_match(NULL, armada_8k_cpufreq_of_match,
-+ NULL);
- if (!node || !of_device_is_available(node)) {
- of_node_put(node);
- return -ENODEV;
-@@ -204,12 +212,6 @@ static void __exit armada_8k_cpufreq_exi
- }
- module_exit(armada_8k_cpufreq_exit);
-
--static const struct of_device_id __maybe_unused armada_8k_cpufreq_of_match[] = {
-- { .compatible = "marvell,ap806-cpu-clock" },
-- { },
--};
--MODULE_DEVICE_TABLE(of, armada_8k_cpufreq_of_match);
--
- MODULE_AUTHOR("Gregory Clement <gregory.clement@bootlin.com>");
- MODULE_DESCRIPTION("Armada 8K cpufreq driver");
- MODULE_LICENSE("GPL");
+++ /dev/null
-Subject: [PATCH v2] PCI: aardvark: Implement workaround for PCIe Completion Timeout
-Date: Tue, 2 Aug 2022 14:38:16 +0200
-Message-Id: <20220802123816.21817-1-pali@kernel.org>
-X-Mailer: git-send-email 2.20.1
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-Precedence: bulk
-List-ID: <linux-pci.vger.kernel.org>
-X-Mailing-List: linux-pci@vger.kernel.org
-
-Marvell Armada 3700 Functional Errata, Guidelines, and Restrictions
-document describes in erratum 3.12 PCIe Completion Timeout (Ref #: 251),
-that PCIe IP does not support a strong-ordered model for inbound posted vs.
-outbound completion.
-
-As a workaround for this erratum, DIS_ORD_CHK flag in Debug Mux Control
-register must be set. It disables the ordering check in the core between
-Completions and Posted requests received from the link.
-
-Marvell also suggests to do full memory barrier at the beginning of
-aardvark summary interrupt handler before calling interrupt handlers of
-endpoint drivers in order to minimize the risk for the race condition
-documented in the Erratum between the DMA done status reading and the
-completion of writing to the host memory.
-
-More details about this issue and suggested workarounds are in discussion:
-https://lore.kernel.org/linux-pci/BN9PR18MB425154FE5019DCAF2028A1D5DB8D9@BN9PR18MB4251.namprd18.prod.outlook.com/t/#u
-
-It was reported that enabling this workaround fixes instability issues and
-"Unhandled fault" errors when using 60 GHz WiFi 802.11ad card with Qualcomm
-QCA6335 chip under significant load which were caused by interrupt status
-stuck in the outbound CMPLT queue traced back to this erratum.
-
-This workaround fixes also kernel panic triggered after some minutes of
-usage 5 GHz WiFi 802.11ax card with Mediatek MT7915 chip:
-
- Internal error: synchronous external abort: 96000210 [#1] SMP
- Kernel panic - not syncing: Fatal exception in interrupt
-
-Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
-Signed-off-by: Pali Rohár <pali@kernel.org>
-Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver")
-Cc: stable@vger.kernel.org
----
- drivers/pci/controller/pci-aardvark.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/drivers/pci/controller/pci-aardvark.c
-+++ b/drivers/pci/controller/pci-aardvark.c
-@@ -212,6 +212,8 @@ enum {
- };
-
- #define VENDOR_ID_REG (LMI_BASE_ADDR + 0x44)
-+#define DEBUG_MUX_CTRL_REG (LMI_BASE_ADDR + 0x208)
-+#define DIS_ORD_CHK BIT(30)
-
- /* PCIe core controller registers */
- #define CTRL_CORE_BASE_ADDR 0x18000
-@@ -560,6 +562,11 @@ static void advk_pcie_setup_hw(struct ad
- PCIE_CORE_CTRL2_TD_ENABLE;
- advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
-
-+ /* Disable ordering checks, workaround for erratum 3.12 "PCIe completion timeout" */
-+ reg = advk_readl(pcie, DEBUG_MUX_CTRL_REG);
-+ reg |= DIS_ORD_CHK;
-+ advk_writel(pcie, reg, DEBUG_MUX_CTRL_REG);
-+
- /* Set lane X1 */
- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
- reg &= ~LANE_CNT_MSK;
-@@ -1661,6 +1668,9 @@ static irqreturn_t advk_pcie_irq_handler
- struct advk_pcie *pcie = arg;
- u32 status;
-
-+ /* Full memory barrier (ARM dsb sy), workaround for erratum 3.12 "PCIe completion timeout" */
-+ mb();
-+
- status = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG);
- if (!(status & PCIE_IRQ_CORE_INT))
- return IRQ_NONE;
+++ /dev/null
---- a/drivers/power/reset/linkstation-poweroff.c
-+++ b/drivers/power/reset/linkstation-poweroff.c
-@@ -142,6 +142,12 @@ static void linkstation_poweroff(void)
- }
-
- static const struct of_device_id ls_poweroff_of_match[] = {
-+ { .compatible = "buffalo,ls220d",
-+ .data = &linkstation_power_off_cfg,
-+ },
-+ { .compatible = "buffalo,ls220de",
-+ .data = &linkstation_power_off_cfg,
-+ },
- { .compatible = "buffalo,ls421d",
- .data = &linkstation_power_off_cfg,
- },
+++ /dev/null
-From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001
-From: Adrian Panella <ianchi74@outlook.com>
-Date: Thu, 9 Mar 2017 09:37:17 +0100
-Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments
-
-The command-line arguments provided by the boot loader will be
-appended to a new device tree property: bootloader-args.
-If there is a property "append-rootblock" in DT under /chosen
-and a root= option in bootloaders command line it will be parsed
-and added to DT bootargs with the form: <append-rootblock>XX.
-Only command line ATAG will be processed, the rest of the ATAGs
-sent by bootloader will be ignored.
-This is usefull in dual boot systems, to get the current root partition
-without afecting the rest of the system.
-
-Signed-off-by: Adrian Panella <ianchi74@outlook.com>
-
-This patch has been modified to be mvebu specific. The original patch
-did not pass the bootloader cmdline on if no append-rootblock stanza
-was found, resulting in blank cmdline and failure to boot.
-
-Signed-off-by: Michael Gray <michael.gray@lantisproject.com>
----
- arch/arm/Kconfig | 11 ++++
- arch/arm/boot/compressed/atags_to_fdt.c | 85 ++++++++++++++++++++++++-
- init/main.c | 16 +++++
- 3 files changed, 111 insertions(+), 1 deletion(-)
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -1587,6 +1587,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
- The command-line arguments provided by the boot loader will be
- appended to the the device tree bootargs property.
-
-+config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
-+ bool "Append rootblock parsing bootloader's kernel arguments"
-+ help
-+ The command-line arguments provided by the boot loader will be
-+ appended to a new device tree property: bootloader-args.
-+ If there is a property "append-rootblock" in DT under /chosen
-+ and a root= option in bootloaders command line it will be parsed
-+ and added to DT bootargs with the form: <append-rootblock>XX.
-+ Only command line ATAG will be processed, the rest of the ATAGs
-+ sent by bootloader will be ignored.
-+
- endchoice
-
- config CMDLINE
---- a/arch/arm/boot/compressed/atags_to_fdt.c
-+++ b/arch/arm/boot/compressed/atags_to_fdt.c
-@@ -5,6 +5,8 @@
-
- #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
- #define do_extend_cmdline 1
-+#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+#define do_extend_cmdline 1
- #else
- #define do_extend_cmdline 0
- #endif
-@@ -20,6 +22,7 @@ static int node_offset(void *fdt, const
- return offset;
- }
-
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
- static int setprop(void *fdt, const char *node_path, const char *property,
- void *val_array, int size)
- {
-@@ -28,6 +31,7 @@ static int setprop(void *fdt, const char
- return offset;
- return fdt_setprop(fdt, offset, property, val_array, size);
- }
-+#endif
-
- static int setprop_string(void *fdt, const char *node_path,
- const char *property, const char *string)
-@@ -38,6 +42,7 @@ static int setprop_string(void *fdt, con
- return fdt_setprop_string(fdt, offset, property, string);
- }
-
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
- static int setprop_cell(void *fdt, const char *node_path,
- const char *property, uint32_t val)
- {
-@@ -46,6 +51,7 @@ static int setprop_cell(void *fdt, const
- return offset;
- return fdt_setprop_cell(fdt, offset, property, val);
- }
-+#endif
-
- static const void *getprop(const void *fdt, const char *node_path,
- const char *property, int *len)
-@@ -58,6 +64,7 @@ static const void *getprop(const void *f
- return fdt_getprop(fdt, offset, property, len);
- }
-
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
- static uint32_t get_cell_size(const void *fdt)
- {
- int len;
-@@ -69,6 +76,74 @@ static uint32_t get_cell_size(const void
- return cell_size;
- }
-
-+#endif
-+
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+
-+static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
-+{
-+ const char *ptr, *end;
-+ const char *root="root=";
-+ int i, l;
-+ const char *rootblock;
-+
-+ //ARM doesn't have __HAVE_ARCH_STRSTR, so search manually
-+ ptr = str - 1;
-+
-+ do {
-+ //first find an 'r' at the begining or after a space
-+ do {
-+ ptr++;
-+ ptr = strchr(ptr, 'r');
-+ if (!ptr)
-+ goto no_append;
-+
-+ } while (ptr != str && *(ptr-1) != ' ');
-+
-+ //then check for the rest
-+ for(i = 1; i <= 4; i++)
-+ if(*(ptr+i) != *(root+i)) break;
-+
-+ } while (i != 5);
-+
-+ end = strchr(ptr, ' ');
-+ end = end ? (end - 1) : (strchr(ptr, 0) - 1);
-+
-+ //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX )
-+ for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
-+ ptr = end + 1;
-+
-+ /* if append-rootblock property is set use it to append to command line */
-+ rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
-+ if (rootblock == NULL)
-+ goto no_append;
-+
-+ if (*dest != ' ') {
-+ *dest = ' ';
-+ dest++;
-+ len++;
-+ }
-+
-+ if (len + l + i <= COMMAND_LINE_SIZE) {
-+ memcpy(dest, rootblock, l);
-+ dest += l - 1;
-+ memcpy(dest, ptr, i);
-+ dest += i;
-+ }
-+
-+ return dest;
-+
-+no_append:
-+ len = strlen(str);
-+ if (len + 1 < COMMAND_LINE_SIZE) {
-+ memcpy(dest, str, len);
-+ dest += len;
-+ }
-+
-+ return dest;
-+}
-+#endif
-+
- static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
- {
- char cmdline[COMMAND_LINE_SIZE];
-@@ -88,18 +163,28 @@ static void merge_fdt_bootargs(void *fdt
-
- /* and append the ATAG_CMDLINE */
- if (fdt_cmdline) {
-+
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+ //save original bootloader args
-+ //and append ubi.mtd with root partition number to current cmdline
-+ setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
-+ ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
-+
-+#else
- len = strlen(fdt_cmdline);
- if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
- *ptr++ = ' ';
- memcpy(ptr, fdt_cmdline, len);
- ptr += len;
- }
-+#endif
- }
- *ptr = '\0';
-
- setprop_string(fdt, "/chosen", "bootargs", cmdline);
- }
-
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
- static void hex_str(char *out, uint32_t value)
- {
- uint32_t digit;
-@@ -117,6 +202,7 @@ static void hex_str(char *out, uint32_t
- }
- *out = '\0';
- }
-+#endif
-
- /*
- * Convert and fold provided ATAGs into the provided FDT.
-@@ -131,9 +217,11 @@ int atags_to_fdt(void *atag_list, void *
- struct tag *atag = atag_list;
- /* In the case of 64 bits memory size, need to reserve 2 cells for
- * address and size for each bank */
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
- __be32 mem_reg_property[2 * 2 * NR_BANKS];
-- int memcount = 0;
-- int ret, memsize;
-+ int memsize, memcount = 0;
-+#endif
-+ int ret;
-
- /* make sure we've got an aligned pointer */
- if ((u32)atag_list & 0x3)
-@@ -168,7 +256,9 @@ int atags_to_fdt(void *atag_list, void *
- else
- setprop_string(fdt, "/chosen", "bootargs",
- atag->u.cmdline.cmdline);
-- } else if (atag->hdr.tag == ATAG_MEM) {
-+ }
-+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
-+ else if (atag->hdr.tag == ATAG_MEM) {
- if (memcount >= sizeof(mem_reg_property)/4)
- continue;
- if (!atag->u.mem.size)
-@@ -212,6 +302,10 @@ int atags_to_fdt(void *atag_list, void *
- setprop(fdt, "/memory", "reg", mem_reg_property,
- 4 * memcount * memsize);
- }
-+#else
-+
-+ }
-+#endif
-
- return fdt_pack(fdt);
- }
---- a/init/main.c
-+++ b/init/main.c
-@@ -113,6 +113,10 @@
-
- #include <kunit/test.h>
-
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+#include <linux/of.h>
-+#endif
-+
- static int kernel_init(void *);
-
- extern void init_IRQ(void);
-@@ -994,6 +998,18 @@ asmlinkage __visible void __init __no_sa
- page_alloc_init();
-
- pr_notice("Kernel command line: %s\n", saved_command_line);
-+
-+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
-+ //Show bootloader's original command line for reference
-+ if(of_chosen) {
-+ const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
-+ if(prop)
-+ pr_notice("Bootloader command line (ignored): %s\n", prop);
-+ else
-+ pr_notice("Bootloader command line not present\n");
-+ }
-+#endif
-+
- /* parameters may set static keys */
- jump_label_init();
- parse_early_param();
+++ /dev/null
---- a/arch/arm/mach-mvebu/Kconfig
-+++ b/arch/arm/mach-mvebu/Kconfig
-@@ -66,6 +66,7 @@ config MACH_ARMADA_38X
- select HAVE_ARM_TWD if SMP
- select MACH_MVEBU_V7
- select PINCTRL_ARMADA_38X
-+ select ARCH_WANT_LIBATA_LEDS
- help
- Say 'Y' here if you want your kernel to support boards based
- on the Marvell Armada 380/385 SoC with device tree.
+++ /dev/null
---- a/arch/arm/boot/dts/armada-385-linksys.dtsi
-+++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
-@@ -214,11 +214,19 @@
- &pcie1 {
- /* Marvell 88W8864, 5GHz-only */
- status = "okay";
-+
-+ mwlwifi {
-+ marvell,2ghz = <0>;
-+ };
- };
-
- &pcie2 {
- /* Marvell 88W8864, 2GHz-only */
- status = "okay";
-+
-+ mwlwifi {
-+ marvell,5ghz = <0>;
-+ };
- };
-
- &pinctrl {
---- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts
-+++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts
-@@ -142,3 +142,205 @@
- };
- };
- };
-+
-+&pcie1 {
-+ mwlwifi {
-+ marvell,chainmask = <2 2>;
-+ marvell,powertable {
-+ AU =
-+ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <100 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <104 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <108 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <112 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <116 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <120 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <124 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <128 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <132 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <136 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <140 0 0x17 0x17 0x17 0x17 0x17 0x17 0x17 0x15 0x17 0x17 0x17 0x14 0x17 0x17 0x17 0x14 0 0xf>,
-+ <149 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>,
-+ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>,
-+ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>,
-+ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>,
-+ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x1a 0x1a 0x17 0x14 0 0xf>;
-+ CA =
-+ <36 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>,
-+ <40 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>,
-+ <44 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>,
-+ <48 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0 0xf>,
-+ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <149 0 0x1a 0x1a 0x18 0x17 0x19 0x19 0x17 0x15 0x18 0x18 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
-+ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
-+ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
-+ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
-+ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>;
-+ CN =
-+ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <100 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <104 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <108 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <112 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <116 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <120 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <124 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <128 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <132 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <136 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <140 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <149 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x11 0x11 0x11 0x11 0 0xf>,
-+ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>,
-+ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>,
-+ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>,
-+ <165 0 0x15 0x15 0x15 0x15 0x16 0x16 0x16 0x15 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0 0xf>;
-+ ETSI =
-+ <36 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <40 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <44 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <48 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <52 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <56 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <60 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <64 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <100 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <104 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <108 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <112 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <116 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <120 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <124 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <128 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <132 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <136 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <140 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>,
-+ <149 0 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0 0xf>;
-+ FCC =
-+ <36 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <40 0 0x19 0x19 0x18 0x17 0x19 0x19 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>,
-+ <44 0 0x19 0x19 0x18 0x17 0x19 0x19 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>,
-+ <48 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x17 0x17 0x17 0x14 0x10 0x10 0x10 0x10 0 0xf>,
-+ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <149 0 0x1a 0x1a 0x18 0x17 0x19 0x19 0x17 0x15 0x18 0x18 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
-+ <153 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
-+ <157 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
-+ <161 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>,
-+ <165 0 0x1a 0x1a 0x18 0x17 0x1a 0x1a 0x17 0x15 0x1a 0x1a 0x17 0x14 0x15 0x15 0x15 0x14 0 0xf>;
-+ };
-+ };
-+};
-+
-+&pcie2 {
-+ mwlwifi {
-+ marvell,chainmask = <2 2>;
-+ marvell,powertable {
-+ AU =
-+ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>;
-+ CA =
-+ <1 0 0x19 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 0 0xf>,
-+ <2 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
-+ <3 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
-+ <4 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
-+ <5 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
-+ <6 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
-+ <7 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
-+ <8 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
-+ <9 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
-+ <10 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x00 0x00 0x00 0x00 0 0xf>,
-+ <11 0 0x19 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x00 0x00 0x00 0x00 0 0xf>;
-+ CN =
-+ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <12 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <13 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <14 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>;
-+ ETSI =
-+ <1 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <12 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>,
-+ <13 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0x0 0x0 0x0 0x0 0 0xf>;
-+ FCC =
-+ <1 0 0x19 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0x1a 0x19 0x18 0x17 0x19 0x19 0x17 0x16 0x14 0x14 0x14 0x14 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0x19 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x0 0x0 0x0 0x0 0 0xf>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts
-+++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts
-@@ -142,3 +142,205 @@
- };
- };
- };
-+
-+&pcie1 {
-+ mwlwifi {
-+ marvell,chainmask = <4 4>;
-+ marvell,powertable {
-+ AU =
-+ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <149 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
-+ <153 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
-+ <157 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
-+ <161 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
-+ <165 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>;
-+ CA =
-+ <36 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <40 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <44 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <48 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>;
-+ CN =
-+ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <149 0 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
-+ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
-+ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
-+ <165 0 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>;
-+ ETSI =
-+ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <149 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>;
-+ FCC =
-+ <36 0 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0 0xf>,
-+ <40 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
-+ <44 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
-+ <48 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
-+ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>;
-+ };
-+ };
-+};
-+
-+&pcie2 {
-+ mwlwifi {
-+ marvell,chainmask = <4 4>;
-+ marvell,powertable {
-+ AU =
-+ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
-+ CA =
-+ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>;
-+ CN =
-+ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <14 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
-+ ETSI =
-+ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
-+ FCC =
-+ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/armada-385-linksys-shelby.dts
-+++ b/arch/arm/boot/dts/armada-385-linksys-shelby.dts
-@@ -142,3 +142,205 @@
- };
- };
- };
-+
-+&pcie1 {
-+ mwlwifi {
-+ marvell,chainmask = <4 4>;
-+ marvell,powertable {
-+ AU =
-+ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <149 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
-+ <153 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
-+ <157 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
-+ <161 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>,
-+ <165 0 0x19 0x19 0x19 0x17 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0x19 0x19 0x16 0x15 0 0xf>;
-+ CA =
-+ <36 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <40 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <44 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <48 0 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>;
-+ CN =
-+ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <149 0 0x14 0x14 0x14 0x14 0x13 0x13 0x13 0x13 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
-+ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
-+ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>,
-+ <165 0 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x13 0x14 0x14 0x14 0x14 0x10 0x10 0x10 0x10 0 0xf>;
-+ ETSI =
-+ <36 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <40 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <44 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <48 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <52 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <56 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <60 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <64 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <100 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <104 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <108 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <112 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <116 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <120 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <124 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <128 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <132 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <136 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <140 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>,
-+ <149 0 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xd 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0xe 0 0xf>;
-+ FCC =
-+ <36 0 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0 0xf>,
-+ <40 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
-+ <44 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
-+ <48 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0xf 0xf 0xf 0xf 0 0xf>,
-+ <52 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <56 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <60 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <64 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <100 0 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <104 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x12 0x12 0x12 0x12 0x10 0x10 0x10 0x10 0 0xf>,
-+ <108 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <112 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <116 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <120 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <124 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <128 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <132 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <136 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <140 0 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0 0xf>,
-+ <149 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <153 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <157 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <161 0 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>,
-+ <165 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0 0xf>;
-+ };
-+ };
-+};
-+
-+&pcie2 {
-+ mwlwifi {
-+ marvell,chainmask = <4 4>;
-+ marvell,powertable {
-+ AU =
-+ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
-+ CA =
-+ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>;
-+ CN =
-+ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <14 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
-+ ETSI =
-+ <1 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <12 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>,
-+ <13 0 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0xa 0x0 0x0 0x0 0x0 0 0xf>;
-+ FCC =
-+ <1 0 0x17 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0xe 0xe 0xe 0xe 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0x18 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x11 0x11 0x11 0x11 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0x17 0x12 0x12 0x12 0x13 0x13 0x13 0x13 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/armada-385-linksys-rango.dts
-+++ b/arch/arm/boot/dts/armada-385-linksys-rango.dts
-@@ -157,6 +157,18 @@
- };
- };
-
-+&pcie1 {
-+ mwlwifi {
-+ marvell,chainmask = <4 4>;
-+ };
-+};
-+
-+&pcie2 {
-+ mwlwifi {
-+ marvell,chainmask = <4 4>;
-+ };
-+};
-+
- &sdhci {
- pinctrl-names = "default";
- pinctrl-0 = <&sdhci_pins>;
---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-@@ -223,12 +223,100 @@
- pcie@2,0 {
- /* Port 0, Lane 1 */
- status = "okay";
-+
-+ mwlwifi {
-+ marvell,5ghz = <0>;
-+ marvell,chainmask = <4 4>;
-+ marvell,powertable {
-+ FCC =
-+ <1 0 0x17 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0xf 0xf 0xf 0xf 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0x17 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x0 0x0 0x0 0x0 0 0xf>;
-+
-+ ETSI =
-+ <1 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <2 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <3 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <4 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <5 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <6 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <7 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <8 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <9 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <10 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <11 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <12 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>,
-+ <13 0 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0xb 0x0 0x0 0x0 0x0 0 0xf>;
-+ };
-+ };
- };
-
- /* Second mini-PCIe port */
- pcie@3,0 {
- /* Port 0, Lane 3 */
- status = "okay";
-+
-+ mwlwifi {
-+ marvell,2ghz = <0>;
-+ marvell,chainmask = <4 4>;
-+ marvell,powertable {
-+ FCC =
-+ <36 0 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <40 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <44 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <48 0 0x8 0x8 0x8 0x8 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0x9 0 0xf>,
-+ <52 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
-+ <56 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
-+ <60 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
-+ <64 0 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0xf 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0 0xf>,
-+ <100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0 0xf>,
-+ <149 0 0x16 0x16 0x16 0x16 0x14 0x14 0x14 0x14 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
-+ <153 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
-+ <157 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
-+ <161 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>,
-+ <165 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 0 0xf>;
-+
-+ ETSI =
-+ <36 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <40 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <44 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <48 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <52 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <56 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <60 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <64 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <100 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <104 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <108 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <112 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <116 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <120 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <124 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <128 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <132 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <136 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <140 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>,
-+ <149 0 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xc 0xd 0xd 0xd 0xd 0xc 0xc 0xc 0xc 0 0xf>;
-+ };
-+ };
- };
- };
-
+++ /dev/null
---- a/arch/arm/boot/dts/armada-xp.dtsi
-+++ b/arch/arm/boot/dts/armada-xp.dtsi
-@@ -237,12 +237,10 @@
- };
-
- &i2c0 {
-- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
- reg = <0x11000 0x100>;
- };
-
- &i2c1 {
-- compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
- reg = <0x11100 0x100>;
- };
-
+++ /dev/null
---- a/arch/arm/boot/dts/armada-388-rd.dts
-+++ b/arch/arm/boot/dts/armada-388-rd.dts
-@@ -103,6 +103,16 @@
- compatible = "st,m25p128", "jedec,spi-nor";
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <108000000>;
-+
-+ partition@0 {
-+ label = "uboot";
-+ reg = <0 0x400000>;
-+ };
-+
-+ partition@1 {
-+ label = "firmware";
-+ reg = <0x400000 0xc00000>;
-+ };
- };
- };
-
+++ /dev/null
-From 9861f93a59142a3131870df2521eb2deb73026d7 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard <maxime.ripard@free-electrons.com>
-Date: Tue, 13 Jan 2015 11:14:09 +0100
-Subject: [PATCH 2/2] ARM: mvebu: 385-ap: Add partitions
-
-Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
----
- arch/arm/boot/dts/armada-385-db-ap.dts | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/arch/arm/boot/dts/armada-385-db-ap.dts
-+++ b/arch/arm/boot/dts/armada-385-db-ap.dts
-@@ -218,19 +218,19 @@
- #size-cells = <1>;
-
- partition@0 {
-- label = "U-Boot";
-+ label = "u-boot";
- reg = <0x00000000 0x00800000>;
- read-only;
- };
-
- partition@800000 {
-- label = "uImage";
-+ label = "kernel";
- reg = <0x00800000 0x00400000>;
- read-only;
- };
-
- partition@c00000 {
-- label = "Root";
-+ label = "ubi";
- reg = <0x00c00000 0x3f400000>;
- };
- };
+++ /dev/null
---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-@@ -483,3 +483,7 @@
- };
- };
- };
-+
-+&coherencyfab {
-+ broken-idle;
-+};
+++ /dev/null
---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-@@ -385,7 +385,7 @@
-
- port@4 {
- reg = <4>;
-- label = "internet";
-+ label = "wan";
- };
-
- port@5 {
+++ /dev/null
---- a/arch/arm/boot/dts/armada-385-linksys.dtsi
-+++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
-@@ -14,6 +14,13 @@
- compatible = "linksys,armada385", "marvell,armada385",
- "marvell,armada380";
-
-+ aliases {
-+ led-boot = &led_power;
-+ led-failsafe = &led_power;
-+ led-running = &led_power;
-+ led-upgrade = &led_power;
-+ };
-+
- chosen {
- stdout-path = "serial0:115200n8";
- };
-@@ -71,7 +78,7 @@
- pinctrl-0 = <&gpio_leds_pins>;
- pinctrl-names = "default";
-
-- power {
-+ led_power: power {
- gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-@@ -26,6 +26,13 @@
- compatible = "linksys,mamba", "marvell,armadaxp-mv78230",
- "marvell,armadaxp", "marvell,armada-370-xp";
-
-+ aliases {
-+ led-boot = &led_power;
-+ led-failsafe = &led_power;
-+ led-running = &led_power;
-+ led-upgrade = &led_power;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = &uart0;
-@@ -195,7 +202,7 @@
- pinctrl-0 = <&power_led_pin>;
- pinctrl-names = "default";
-
-- power {
-+ led_power: power {
- label = "mamba:white:power";
- gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
- default-state = "on";
+++ /dev/null
---- a/arch/arm/boot/dts/armada-385-linksys.dtsi
-+++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
-@@ -116,7 +116,7 @@
- };
-
- ð2 {
-- status = "okay";
-+ status = "disabled";
- phy-mode = "sgmii";
- buffer-manager = <&bm>;
- bm,pool-long = <2>;
-@@ -200,10 +200,10 @@
- label = "wan";
- };
-
-- port@5 {
-- reg = <5>;
-+ port@6 {
-+ reg = <6>;
- label = "cpu";
-- ethernet = <ð2>;
-+ ethernet = <ð0>;
-
- fixed-link {
- speed = <1000>;
+++ /dev/null
---- a/arch/arm/boot/dts/armada-385-linksys-rango.dts
-+++ b/arch/arm/boot/dts/armada-385-linksys-rango.dts
-@@ -12,8 +12,8 @@
-
- / {
- model = "Linksys WRT3200ACM";
-- compatible = "linksys,rango", "linksys,armada385", "marvell,armada385",
-- "marvell,armada380";
-+ compatible = "linksys,wrt3200acm", "linksys,rango", "linksys,armada385",
-+ "marvell,armada385", "marvell,armada380";
- };
-
- &expander0 {
---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-@@ -22,9 +22,10 @@
- #include "armada-xp-mv78230.dtsi"
-
- / {
-- model = "Linksys WRT1900AC";
-- compatible = "linksys,mamba", "marvell,armadaxp-mv78230",
-- "marvell,armadaxp", "marvell,armada-370-xp";
-+ model = "Linksys WRT1900AC v1";
-+ compatible = "linksys,wrt1900ac-v1", "linksys,mamba",
-+ "marvell,armadaxp-mv78230", "marvell,armadaxp",
-+ "marvell,armada-370-xp";
-
- aliases {
- led-boot = &led_power;
---- a/arch/arm/boot/dts/armada-385-linksys-cobra.dts
-+++ b/arch/arm/boot/dts/armada-385-linksys-cobra.dts
-@@ -9,8 +9,9 @@
- #include "armada-385-linksys.dtsi"
-
- / {
-- model = "Linksys WRT1900ACv2";
-- compatible = "linksys,cobra", "linksys,armada385", "marvell,armada385",
-+ model = "Linksys WRT1900AC v2";
-+ compatible = "linksys,wrt1900ac-v2", "linksys,cobra",
-+ "linksys,armada385", "marvell,armada385",
- "marvell,armada380";
- };
-
---- a/arch/arm/boot/dts/armada-385-linksys-caiman.dts
-+++ b/arch/arm/boot/dts/armada-385-linksys-caiman.dts
-@@ -10,8 +10,8 @@
-
- / {
- model = "Linksys WRT1200AC";
-- compatible = "linksys,caiman", "linksys,armada385", "marvell,armada385",
-- "marvell,armada380";
-+ compatible = "linksys,wrt1200ac", "linksys,caiman", "linksys,armada385",
-+ "marvell,armada385", "marvell,armada380";
- };
-
- &expander0 {
---- a/arch/arm/boot/dts/armada-385-linksys-shelby.dts
-+++ b/arch/arm/boot/dts/armada-385-linksys-shelby.dts
-@@ -10,7 +10,8 @@
-
- / {
- model = "Linksys WRT1900ACS";
-- compatible = "linksys,shelby", "linksys,armada385", "marvell,armada385",
-+ compatible = "linksys,wrt1900acs", "linksys,shelby",
-+ "linksys,armada385", "marvell,armada385",
- "marvell,armada380";
- };
-
+++ /dev/null
-From 8137da20701c776ad3481115305a5e8e410871ba Mon Sep 17 00:00:00 2001
-From: Russell King <rmk+kernel@armlinux.org.uk>
-Date: Tue, 29 Nov 2016 10:15:45 +0000
-Subject: ARM: dts: armada388-clearfog: emmc on clearfog base
-
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
----
- .../arm/boot/dts/armada-388-clearfog-base.dts | 1 +
- .../armada-38x-solidrun-microsom-emmc.dtsi | 62 +++++++++++++++++++
- 2 files changed, 63 insertions(+)
- create mode 100644 arch/arm/boot/dts/armada-38x-solidrun-microsom-emmc.dtsi
-
---- a/arch/arm/boot/dts/armada-388-clearfog-base.dts
-+++ b/arch/arm/boot/dts/armada-388-clearfog-base.dts
-@@ -7,6 +7,7 @@
-
- /dts-v1/;
- #include "armada-388-clearfog.dtsi"
-+#include "armada-38x-solidrun-microsom-emmc.dtsi"
-
- / {
- model = "SolidRun Clearfog Base A1";
---- /dev/null
-+++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom-emmc.dtsi
-@@ -0,0 +1,62 @@
-+/*
-+ * Device Tree file for SolidRun Armada 38x Microsom add-on for eMMC
-+ *
-+ * Copyright (C) 2015 Russell King
-+ *
-+ * This board is in development; the contents of this file work with
-+ * the A1 rev 2.0 of the board, which does not represent final
-+ * production board. Things will change, don't expect this file to
-+ * remain compatible info the future.
-+ *
-+ * This file is dual-licensed: you can use it either under the terms
-+ * of the GPL or the X11 license, at your option. Note that this dual
-+ * licensing only applies to this file, and not this project as a
-+ * whole.
-+ *
-+ * a) This file is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ *
-+ * This file is distributed in the hope that it will be useful
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * Or, alternatively
-+ *
-+ * b) Permission is hereby granted, free of charge, to any person
-+ * obtaining a copy of this software and associated documentation
-+ * files (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use
-+ * copy, modify, merge, publish, distribute, sublicense, and/or
-+ * sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following
-+ * conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be
-+ * included in all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
-+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ */
-+/ {
-+ soc {
-+ internal-regs {
-+ sdhci@d8000 {
-+ bus-width = <4>;
-+ no-1-8-v;
-+ non-removable;
-+ pinctrl-0 = <µsom_sdhci_pins>;
-+ pinctrl-names = "default";
-+ status = "okay";
-+ wp-inverted;
-+ };
-+ };
-+ };
-+};
+++ /dev/null
---- a/arch/arm/boot/dts/armada-388-helios4.dts
-+++ b/arch/arm/boot/dts/armada-388-helios4.dts
-@@ -15,6 +15,13 @@
- model = "Helios4";
- compatible = "kobol,helios4", "marvell,armada388",
- "marvell,armada385", "marvell,armada380";
-+
-+ aliases {
-+ led-boot = &led_status;
-+ led-failsafe = &led_status;
-+ led-running = &led_status;
-+ led-upgrade = &led_status;
-+ };
-
- memory {
- device_type = "memory";
-@@ -73,10 +80,9 @@
- pinctrl-names = "default";
- pinctrl-0 = <&helios_system_led_pins>;
-
-- status-led {
-+ led_status: status-led {
- label = "helios4:green:status";
- gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
-- linux,default-trigger = "heartbeat";
- default-state = "on";
- };
-
+++ /dev/null
-From: Tomasz Maciej Nowak <tmn505@gmail.com>
-Date: Fri, 7 Jul 2023 19:06:05 +0200
-Subject: [PATCH] arm64: dts: marvell: enable heartbeat LED by default
-
-Some boards could be placed in an enclosure, so enable LED18 by default,
-since that'll be the only visible indicator that the board is operating.
-
-Signed-off-by: Tomasz Maciej Nowak <tmn505@gmail.com>
----
- arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts
-+++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin-singleshot.dts
-@@ -25,6 +25,7 @@
- function = LED_FUNCTION_HEARTBEAT;
- color = <LED_COLOR_ID_GREEN>;
- linux,default-trigger = "heartbeat";
-+ default-state = "on";
- };
- };
- };
+++ /dev/null
-From 258233f00bcd013050efee00c5d9128ef8cd62dd Mon Sep 17 00:00:00 2001
-From: Tad <tad@spotco.us>
-Date: Fri, 5 Feb 2021 22:32:11 -0500
-Subject: [PATCH] ARM: dts: armada-xp-linksys-mamba: Increase kernel
- partition to 4MB
-
-Signed-off-by: Tad Davanzo <tad@spotco.us>
----
- arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
-@@ -454,9 +454,9 @@
- reg = <0xa00000 0x2800000>; /* 40MB */
- };
-
-- partition@d00000 {
-+ partition@e00000 {
- label = "rootfs1";
-- reg = <0xd00000 0x2500000>; /* 37MB */
-+ reg = <0xe00000 0x2400000>; /* 36MB */
- };
-
- /* kernel2 overlaps with rootfs2 by design */
-@@ -465,9 +465,9 @@
- reg = <0x3200000 0x2800000>; /* 40MB */
- };
-
-- partition@3500000 {
-+ partition@3600000 {
- label = "rootfs2";
-- reg = <0x3500000 0x2500000>; /* 37MB */
-+ reg = <0x3600000 0x2400000>; /* 36MB */
- };
-
- /*
+++ /dev/null
---- a/arch/arm/boot/dts/armada-370.dtsi
-+++ b/arch/arm/boot/dts/armada-370.dtsi
-@@ -254,7 +254,7 @@
- clocks = <&gateclk 23>;
- clock-names = "cesa0";
- marvell,crypto-srams = <&crypto_sram>;
-- marvell,crypto-sram-size = <0x7e0>;
-+ marvell,crypto-sram-size = <0x800>;
- };
- };
-
-@@ -275,12 +275,17 @@
- * cpuidle workaround.
- */
- idle-sram@0 {
-+ status = "disabled";
- reg = <0x0 0x20>;
- };
- };
- };
- };
-
-+&coherencyfab {
-+ broken-idle;
-+};
-+
- /*
- * Default UART pinctrl setting without RTS/CTS, can be overwritten on
- * board level if a different configuration is used.
+++ /dev/null
---- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts
-+++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
-@@ -31,6 +31,7 @@
-
- chosen {
- stdout-path = "serial0:115200n8";
-+ append-rootblock = "nullparameter="; /* override the bootloader args */
- };
-
- memory@0 {
-@@ -94,6 +95,8 @@
- status = "okay";
- phy = <&phy1>;
- phy-mode = "sgmii";
-+ nvmem-cells = <&macaddr_vendor_0>;
-+ nvmem-cell-names = "mac-address";
- };
-
- sata@a0000 {
-@@ -175,6 +178,24 @@
- gpio = <&gpio1 30 GPIO_ACTIVE_HIGH>;
- };
- };
-+
-+ virtual_flash {
-+ compatible = "mtd-concat";
-+
-+ devices = <&mtd_kernel &mtd_gap &mtd_gap2>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ compatible = "openwrt,uimage", "denx,uimage";
-+ label = "firmware";
-+ reg = <0x0 0x0>;
-+ };
-+ };
-+ };
- };
-
- &mdio {
-@@ -265,48 +286,52 @@
- reg = <0>; /* Chip select 0 */
- spi-max-frequency = <20000000>;
-
-- /*
-- * Warning!
-- *
-- * Synology u-boot uses its compiled-in environment
-- * and it seems Synology did not care to change u-boot
-- * default configuration in order to allow saving a
-- * modified environment at a sensible location. So,
-- * if you do a 'saveenv' under u-boot, your modified
-- * environment will be saved at 1MB after the start
-- * of the flash, i.e. in the middle of the uImage.
-- * For that reason, it is strongly advised not to
-- * change the default environment, unless you know
-- * what you are doing.
-- */
-- partition@0 { /* u-boot */
-- label = "RedBoot";
-- reg = <0x00000000 0x000c0000>; /* 768KB */
-- };
-+ partitions {
-+ compatible = "fixed-partitions";
-
-- partition@c0000 { /* uImage */
-- label = "zImage";
-- reg = <0x000c0000 0x002d0000>; /* 2880KB */
-- };
-+ partition@0 { /* u-boot */
-+ label = "u-boot";
-+ reg = <0x00000000 0x000c0000>; /* 768KB */
-+ read-only;
-+ };
-
-- partition@390000 { /* uInitramfs */
-- label = "rd.gz";
-- reg = <0x00390000 0x00440000>; /* 4250KB */
-- };
-+ mtd_gap: partition@c0000 { /* gap */
-+ label = "gap";
-+ reg = <0x000c0000 0x00040000>; /* 256KB */
-+ };
-
-- partition@7d0000 { /* MAC address and serial number */
-- label = "vendor";
-- reg = <0x007d0000 0x00010000>; /* 64KB */
-- };
-+ partition@100000 { /* u-boot-env */
-+ label = "u-boot-env";
-+ reg = <0x00100000 0x00010000>; /* 64KB */
-+ };
-
-- partition@7e0000 {
-- label = "RedBoot config";
-- reg = <0x007e0000 0x00010000>; /* 64KB */
-- };
-+ mtd_kernel: partition@110000 {
-+ label = "kernel";
-+ reg = <0x00110000 0x006c0000>; /* 6912KB */
-+ };
-
-- partition@7f0000 {
-- label = "FIS directory";
-- reg = <0x007f0000 0x00010000>; /* 64KB */
-+ partition@7d0000 { /* MAC address and serial number */
-+ reg = <0x007d0000 0x00010000>; /* 64KB */
-+ label = "vendor";
-+ read-only;
-+
-+ compatible = "nvmem-cells";
-+
-+ nvmem-layout {
-+ compatible = "fixed-layout";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ macaddr_vendor_0: macaddr@0 {
-+ reg = <0x0 0x6>;
-+ };
-+ };
-+ };
-+
-+ mtd_gap2: partition@7e0000 {
-+ label = "gap2";
-+ reg = <0x007e0000 0x00020000>; /* 128KB */
-+ };
- };
- };
- };
+++ /dev/null
-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)
-@@ -48,6 +50,7 @@ static int parse_fixed_partitions(struct
- struct device_node *mtd_node;
- struct device_node *ofpart_node;
- const char *partname;
-+ const char *owrtpart = "ubi";
- struct device_node *pp;
- int nr_parts, i, ret = 0;
- bool dedicated = true;
-@@ -152,9 +155,13 @@ 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 +278,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);
+++ /dev/null
-From: Felix Fietkau <nbd@nbd.name>
-Subject: mvneta: tx queue workaround
-
-The hardware queue scheduling is apparently configured with fixed
-priorities, which creates a nasty fairness issue where traffic from one
-CPU can starve traffic from all other CPUs.
-
-Work around this issue by forcing all tx packets to go through one CPU,
-until this issue is fixed properly.
-
-Ref: https://github.com/openwrt/openwrt/issues/5411
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
---- a/drivers/net/ethernet/marvell/mvneta.c
-+++ b/drivers/net/ethernet/marvell/mvneta.c
-@@ -5233,6 +5233,16 @@ static int mvneta_setup_tc(struct net_de
- }
- }
-
-+#ifndef CONFIG_ARM64
-+static u16 mvneta_select_queue(struct net_device *dev, struct sk_buff *skb,
-+ struct net_device *sb_dev)
-+{
-+ /* XXX: hardware queue scheduling is broken,
-+ * use only one queue until it is fixed */
-+ return 0;
-+}
-+#endif
-+
- static const struct net_device_ops mvneta_netdev_ops = {
- .ndo_open = mvneta_open,
- .ndo_stop = mvneta_stop,
-@@ -5243,6 +5253,9 @@ static const struct net_device_ops mvnet
- .ndo_fix_features = mvneta_fix_features,
- .ndo_get_stats64 = mvneta_get_stats64,
- .ndo_eth_ioctl = mvneta_ioctl,
-+#ifndef CONFIG_ARM64
-+ .ndo_select_queue = mvneta_select_queue,
-+#endif
- .ndo_bpf = mvneta_xdp,
- .ndo_xdp_xmit = mvneta_xdp_xmit,
- .ndo_setup_tc = mvneta_setup_tc,
+++ /dev/null
-From: Tobias Schramm <tobias@t-sys.eu>
-Subject: mvpp2: support fetching mac address from nvmem
-
-The mvpp2 driver did not query nvmem for hardware mac addresses. This
-patch adds querying of mac addresses stored in nvmem cells as a further
-fallback option before assigning a random address.
-Purposely added separately to fwnode_get_mac_address() above to maintain
-existing behaviour with builtin adapter mac address still taking
-precedence.
-
-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
-@@ -6134,6 +6134,12 @@ static void mvpp2_port_copy_mac_addr(str
- }
- }
-
-+ if (!of_get_mac_address(to_of_node(fwnode), hw_mac_addr)) {
-+ *mac_from = "nvmem cell";
-+ eth_hw_addr_set(dev, hw_mac_addr);
-+ return;
-+ }
-+
- *mac_from = "random";
- eth_hw_addr_random(dev);
- }
+++ /dev/null
-From c28b2d367da8a471482e6a4aa8337ab6369a80c2 Mon Sep 17 00:00:00 2001
-From: Russell King <rmk+kernel@arm.linux.org.uk>
-Date: Sat, 3 Oct 2015 09:13:05 +0100
-Subject: cpuidle: mvebu: indicate failure to enter deeper sleep states
-
-The cpuidle ->enter method expects the return value to be the sleep
-state we entered. Returning negative numbers or other codes is not
-permissible since coupled CPU idle was merged.
-
-At least some of the mvebu_v7_cpu_suspend() implementations return the
-value from cpu_suspend(), which returns zero if the CPU vectors back
-into the kernel via cpu_resume() (the success case), or the non-zero
-return value of the suspend actor, or one (failure cases).
-
-We do not want to be returning the failure case value back to CPU idle
-as that indicates that we successfully entered one of the deeper idle
-states. Always return zero instead, indicating that we slept for the
-shortest amount of time.
-
-Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
----
- drivers/cpuidle/cpuidle-mvebu-v7.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/cpuidle/cpuidle-mvebu-v7.c
-+++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
-@@ -39,8 +39,12 @@ static int mvebu_v7_enter_idle(struct cp
- ret = mvebu_v7_cpu_suspend(deepidle);
- cpu_pm_exit();
-
-+ /*
-+ * If we failed to enter the desired state, indicate that we
-+ * slept lightly.
-+ */
- if (ret)
-- return ret;
-+ return 0;
-
- return index;
- }
+++ /dev/null
-From 287b9df160b6159f8d385424904f8bac501280c1 Mon Sep 17 00:00:00 2001
-From: Russell King <rmk+kernel@armlinux.org.uk>
-Date: Sat, 9 Jul 2016 10:58:16 +0100
-Subject: pci: mvebu: time out reset on link up
-
-If the port reports that the link is up while we are resetting, there's
-little point in waiting for the full duration.
-
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
----
- drivers/pci/controller/pci-mvebu.c | 20 ++++++++++++++------
- 1 file changed, 14 insertions(+), 6 deletions(-)
-
---- a/drivers/pci/controller/pci-mvebu.c
-+++ b/drivers/pci/controller/pci-mvebu.c
-@@ -1414,6 +1414,7 @@ static int mvebu_pcie_powerup(struct mve
-
- if (port->reset_gpio) {
- u32 reset_udelay = PCI_PM_D3COLD_WAIT * 1000;
-+ unsigned int i;
-
- of_property_read_u32(port->dn, "reset-delay-us",
- &reset_udelay);
-@@ -1421,7 +1422,13 @@ static int mvebu_pcie_powerup(struct mve
- udelay(100);
-
- gpiod_set_value_cansleep(port->reset_gpio, 0);
-- msleep(reset_udelay / 1000);
-+ for (i = 0; i < reset_udelay; i += 1000) {
-+ if (mvebu_pcie_link_up(port))
-+ break;
-+ msleep(1);
-+ }
-+
-+ printk("%s: reset completed in %dus\n", port->name, i);
- }
-
- return 0;
-@@ -1538,15 +1545,16 @@ static int mvebu_pcie_probe(struct platf
- if (!child)
- continue;
-
-- ret = mvebu_pcie_powerup(port);
-- if (ret < 0)
-- continue;
--
- port->base = mvebu_pcie_map_registers(pdev, child, port);
- if (IS_ERR(port->base)) {
- dev_err(dev, "%s: cannot map registers\n", port->name);
- port->base = NULL;
-- mvebu_pcie_powerdown(port);
-+ continue;
-+ }
-+
-+ ret = mvebu_pcie_powerup(port);
-+ if (ret < 0) {
-+ port->base = NULL;
- continue;
- }
-
+++ /dev/null
-From aa4a0ccc41997f2da172165c92803abace43bd1c Mon Sep 17 00:00:00 2001
-From: Luka Kovacic <luka.kovacic () sartura ! hr>
-Date: Tue, 24 Aug 2021 12:44:32 +0000
-Subject: [PATCH 1/7] dt-bindings: Add IEI vendor prefix and IEI WT61P803
- PUZZLE driver bindings
-
-Add the IEI WT61P803 PUZZLE Device Tree bindings for MFD, HWMON and LED
-drivers. A new vendor prefix is also added accordingly for
-IEI Integration Corp.
-
-Signed-off-by: Luka Kovacic <luka.kovacic@sartura.hr>
-Signed-off-by: Pavo Banicevic <pavo.banicevic@sartura.hr>
-Cc: Luka Perkov <luka.perkov@sartura.hr>
-Cc: Robert Marko <robert.marko@sartura.hr>
----
- .../hwmon/iei,wt61p803-puzzle-hwmon.yaml | 53 ++++++++++++
- .../leds/iei,wt61p803-puzzle-leds.yaml | 39 +++++++++
- .../bindings/mfd/iei,wt61p803-puzzle.yaml | 82 +++++++++++++++++++
- .../devicetree/bindings/vendor-prefixes.yaml | 2 +
- 4 files changed, 176 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/hwmon/iei,wt61p803-puzzle-hwmon.yaml
- create mode 100644 Documentation/devicetree/bindings/leds/iei,wt61p803-puzzle-leds.yaml
- create mode 100644 Documentation/devicetree/bindings/mfd/iei,wt61p803-puzzle.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/hwmon/iei,wt61p803-puzzle-hwmon.yaml
-@@ -0,0 +1,53 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/hwmon/iei,wt61p803-puzzle-hwmon.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: IEI WT61P803 PUZZLE MCU HWMON module from IEI Integration Corp.
-+
-+maintainers:
-+ - Luka Kovacic <luka.kovacic@sartura.hr>
-+
-+description: |
-+ This module is a part of the IEI WT61P803 PUZZLE MFD device. For more details
-+ see Documentation/devicetree/bindings/mfd/iei,wt61p803-puzzle.yaml.
-+
-+ The HWMON module is a sub-node of the MCU node in the Device Tree.
-+
-+properties:
-+ compatible:
-+ const: iei,wt61p803-puzzle-hwmon
-+
-+ "#address-cells":
-+ const: 1
-+
-+ "#size-cells":
-+ const: 0
-+
-+patternProperties:
-+ "^fan-group@[0-1]$":
-+ type: object
-+ properties:
-+ reg:
-+ minimum: 0
-+ maximum: 1
-+ description:
-+ Fan group ID
-+
-+ cooling-levels:
-+ minItems: 1
-+ maxItems: 255
-+ description:
-+ Cooling levels for the fans (PWM value mapping)
-+ description: |
-+ Properties for each fan group.
-+ required:
-+ - reg
-+
-+required:
-+ - compatible
-+ - "#address-cells"
-+ - "#size-cells"
-+
-+additionalProperties: false
---- /dev/null
-+++ b/Documentation/devicetree/bindings/leds/iei,wt61p803-puzzle-leds.yaml
-@@ -0,0 +1,39 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/leds/iei,wt61p803-puzzle-leds.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: IEI WT61P803 PUZZLE MCU LED module from IEI Integration Corp.
-+
-+maintainers:
-+ - Luka Kovacic <luka.kovacic@sartura.hr>
-+
-+description: |
-+ This module is a part of the IEI WT61P803 PUZZLE MFD device. For more details
-+ see Documentation/devicetree/bindings/mfd/iei,wt61p803-puzzle.yaml.
-+
-+ The LED module is a sub-node of the MCU node in the Device Tree.
-+
-+properties:
-+ compatible:
-+ const: iei,wt61p803-puzzle-leds
-+
-+ "#address-cells":
-+ const: 1
-+
-+ "#size-cells":
-+ const: 0
-+
-+ led@0:
-+ type: object
-+ $ref: common.yaml
-+ description: |
-+ Properties for a single LED.
-+
-+required:
-+ - compatible
-+ - "#address-cells"
-+ - "#size-cells"
-+
-+additionalProperties: false
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mfd/iei,wt61p803-puzzle.yaml
-@@ -0,0 +1,82 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/mfd/iei,wt61p803-puzzle.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: IEI WT61P803 PUZZLE MCU from IEI Integration Corp.
-+
-+maintainers:
-+ - Luka Kovacic <luka.kovacic@sartura.hr>
-+
-+description: |
-+ IEI WT61P803 PUZZLE MCU is embedded in some IEI Puzzle series boards.
-+ It's used for controlling system power states, fans, LEDs and temperature
-+ sensors.
-+
-+ For Device Tree bindings of other sub-modules (HWMON, LEDs) refer to the
-+ binding documents under the respective subsystem directories.
-+
-+properties:
-+ compatible:
-+ const: iei,wt61p803-puzzle
-+
-+ current-speed:
-+ description:
-+ Serial bus speed in bps
-+ maxItems: 1
-+
-+ enable-beep: true
-+
-+ hwmon:
-+ $ref: /schemas/hwmon/iei,wt61p803-puzzle-hwmon.yaml
-+
-+ leds:
-+ $ref: /schemas/leds/iei,wt61p803-puzzle-leds.yaml
-+
-+required:
-+ - compatible
-+ - current-speed
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/leds/common.h>
-+ serial {
-+ mcu {
-+ compatible = "iei,wt61p803-puzzle";
-+ current-speed = <115200>;
-+ enable-beep;
-+
-+ leds {
-+ compatible = "iei,wt61p803-puzzle-leds";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ led@0 {
-+ reg = <0>;
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_BLUE>;
-+ };
-+ };
-+
-+ hwmon {
-+ compatible = "iei,wt61p803-puzzle-hwmon";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ fan-group@0 {
-+ #cooling-cells = <2>;
-+ reg = <0x00>;
-+ cooling-levels = <64 102 170 230 250>;
-+ };
-+
-+ fan-group@1 {
-+ #cooling-cells = <2>;
-+ reg = <0x01>;
-+ cooling-levels = <64 102 170 230 250>;
-+ };
-+ };
-+ };
-+ };
---- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
-+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
-@@ -579,6 +579,8 @@ patternProperties:
- description: IC Plus Corp.
- "^idt,.*":
- description: Integrated Device Technologies, Inc.
-+ "^iei,.*":
-+ description: IEI Integration Corp.
- "^ifi,.*":
- description: Ingenieurburo Fur Ic-Technologie (I/F/I)
- "^ilitek,.*":
+++ /dev/null
-From 692cfa85272dd12995b427c0a7a585ced5d54f32 Mon Sep 17 00:00:00 2001
-From: Luka Kovacic <luka.kovacic () sartura ! hr>
-Date: Tue, 24 Aug 2021 12:44:33 +0000
-Subject: [PATCH 2/7] drivers: mfd: Add a driver for IEI WT61P803 PUZZLE MCU
-
-Add a driver for the IEI WT61P803 PUZZLE microcontroller, used in some
-IEI Puzzle series devices. The microcontroller controls system power,
-temperature sensors, fans and LEDs.
-
-This driver implements the core functionality for device communication
-over the system serial (serdev bus). It handles MCU messages and the
-internal MCU properties. Some properties can be managed over sysfs.
-
-Signed-off-by: Luka Kovacic <luka.kovacic@sartura.hr>
-Signed-off-by: Pavo Banicevic <pavo.banicevic@sartura.hr>
-Cc: Luka Perkov <luka.perkov@sartura.hr>
-Cc: Robert Marko <robert.marko@sartura.hr>
----
- drivers/mfd/Kconfig | 9 +
- drivers/mfd/Makefile | 1 +
- drivers/mfd/iei-wt61p803-puzzle.c | 908 ++++++++++++++++++++++++
- include/linux/mfd/iei-wt61p803-puzzle.h | 66 ++
- 4 files changed, 984 insertions(+)
- create mode 100644 drivers/mfd/iei-wt61p803-puzzle.c
- create mode 100644 include/linux/mfd/iei-wt61p803-puzzle.h
-
---- a/drivers/mfd/Kconfig
-+++ b/drivers/mfd/Kconfig
-@@ -2222,6 +2222,15 @@ config SGI_MFD_IOC3
- If you have an SGI Origin, Octane, or a PCI IOC3 card,
- then say Y. Otherwise say N.
-
-+config MFD_IEI_WT61P803_PUZZLE
-+ tristate "IEI WT61P803 PUZZLE MCU driver"
-+ depends on SERIAL_DEV_BUS
-+ select MFD_CORE
-+ help
-+ IEI WT61P803 PUZZLE is a system power management microcontroller
-+ used for fan control, temperature sensor reading, LED control
-+ and system identification.
-+
- config MFD_INTEL_M10_BMC
- tristate "Intel MAX 10 Board Management Controller"
- depends on SPI_MASTER
---- a/drivers/mfd/Makefile
-+++ b/drivers/mfd/Makefile
-@@ -244,6 +244,7 @@ obj-$(CONFIG_MFD_RT4831) += rt4831.o
- obj-$(CONFIG_MFD_RT5033) += rt5033.o
- obj-$(CONFIG_MFD_RT5120) += rt5120.o
- obj-$(CONFIG_MFD_SKY81452) += sky81452.o
-+obj-$(CONFIG_MFD_IEI_WT61P803_PUZZLE) += iei-wt61p803-puzzle.o
-
- obj-$(CONFIG_INTEL_SOC_PMIC) += intel_soc_pmic_crc.o
- obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
---- /dev/null
-+++ b/drivers/mfd/iei-wt61p803-puzzle.c
-@@ -0,0 +1,908 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* IEI WT61P803 PUZZLE MCU Driver
-+ * System management microcontroller for fan control, temperature sensor reading,
-+ * LED control and system identification on IEI Puzzle series ARM-based appliances.
-+ *
-+ * Copyright (C) 2020 Sartura Ltd.
-+ * Author: Luka Kovacic <luka.kovacic@sartura.hr>
-+ */
-+
-+#include <linux/atomic.h>
-+#include <linux/delay.h>
-+#include <linux/export.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/mfd/core.h>
-+#include <linux/mfd/iei-wt61p803-puzzle.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/property.h>
-+#include <linux/sched.h>
-+#include <linux/serdev.h>
-+#include <linux/slab.h>
-+#include <linux/sysfs.h>
-+#include <asm/unaligned.h>
-+
-+/* start, payload and XOR checksum at end */
-+#define IEI_WT61P803_PUZZLE_MAX_COMMAND_LENGTH (1 + 20 + 1)
-+#define IEI_WT61P803_PUZZLE_RESP_BUF_SIZE 512
-+
-+#define IEI_WT61P803_PUZZLE_MAC_LENGTH 17
-+#define IEI_WT61P803_PUZZLE_SN_LENGTH 36
-+#define IEI_WT61P803_PUZZLE_VERSION_LENGTH 6
-+#define IEI_WT61P803_PUZZLE_BUILD_INFO_LENGTH 16
-+#define IEI_WT61P803_PUZZLE_PROTOCOL_VERSION_LENGTH 8
-+#define IEI_WT61P803_PUZZLE_NB_MAC 8
-+
-+/* Use HZ as a timeout value throughout the driver */
-+#define IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT HZ
-+
-+enum iei_wt61p803_puzzle_attribute_type {
-+ IEI_WT61P803_PUZZLE_VERSION,
-+ IEI_WT61P803_PUZZLE_BUILD_INFO,
-+ IEI_WT61P803_PUZZLE_BOOTLOADER_MODE,
-+ IEI_WT61P803_PUZZLE_PROTOCOL_VERSION,
-+ IEI_WT61P803_PUZZLE_SERIAL_NUMBER,
-+ IEI_WT61P803_PUZZLE_MAC_ADDRESS,
-+ IEI_WT61P803_PUZZLE_AC_RECOVERY_STATUS,
-+ IEI_WT61P803_PUZZLE_POWER_LOSS_RECOVERY,
-+ IEI_WT61P803_PUZZLE_POWER_STATUS,
-+};
-+
-+struct iei_wt61p803_puzzle_device_attribute {
-+ struct device_attribute dev_attr;
-+ enum iei_wt61p803_puzzle_attribute_type type;
-+ u8 index;
-+};
-+
-+/**
-+ * struct iei_wt61p803_puzzle_mcu_status - MCU flags state
-+ * @ac_recovery_status_flag: AC Recovery Status Flag
-+ * @power_loss_recovery: System recovery after power loss
-+ * @power_status: System Power-on Method
-+ */
-+struct iei_wt61p803_puzzle_mcu_status {
-+ u8 ac_recovery_status_flag;
-+ u8 power_loss_recovery;
-+ u8 power_status;
-+};
-+
-+/**
-+ * struct iei_wt61p803_puzzle_reply - MCU reply
-+ * @size: Size of the MCU reply
-+ * @data: Full MCU reply buffer
-+ * @state: Current state of the packet
-+ * @received: Was the response fullfilled
-+ */
-+struct iei_wt61p803_puzzle_reply {
-+ size_t size;
-+ unsigned char data[IEI_WT61P803_PUZZLE_RESP_BUF_SIZE];
-+ struct completion received;
-+};
-+
-+/**
-+ * struct iei_wt61p803_puzzle_mcu_version - MCU version status
-+ * @version: Primary firmware version
-+ * @build_info: Build date and time
-+ * @bootloader_mode: Status of the MCU operation
-+ * @protocol_version: MCU communication protocol version
-+ * @serial_number: Device factory serial number
-+ * @mac_address: Device factory MAC addresses
-+ *
-+ * Last element of arrays is reserved for '\0'.
-+ */
-+struct iei_wt61p803_puzzle_mcu_version {
-+ char version[IEI_WT61P803_PUZZLE_VERSION_LENGTH + 1];
-+ char build_info[IEI_WT61P803_PUZZLE_BUILD_INFO_LENGTH + 1];
-+ bool bootloader_mode;
-+ char protocol_version[IEI_WT61P803_PUZZLE_PROTOCOL_VERSION_LENGTH + 1];
-+ char serial_number[IEI_WT61P803_PUZZLE_SN_LENGTH + 1];
-+ char mac_address[IEI_WT61P803_PUZZLE_NB_MAC][IEI_WT61P803_PUZZLE_MAC_LENGTH + 1];
-+};
-+
-+/**
-+ * struct iei_wt61p803_puzzle - IEI WT61P803 PUZZLE MCU Driver
-+ * @serdev: Pointer to underlying serdev device
-+ * @dev: Pointer to underlying dev device
-+ * @reply_lock: Reply mutex lock
-+ * @reply: Pointer to the iei_wt61p803_puzzle_reply struct
-+ * @version: MCU version related data
-+ * @status: MCU status related data
-+ * @response_buffer Command response buffer allocation
-+ * @lock General member mutex lock
-+ */
-+struct iei_wt61p803_puzzle {
-+ struct serdev_device *serdev;
-+ struct device *dev;
-+ struct mutex reply_lock; /* lock to prevent multiple firmware calls */
-+ struct iei_wt61p803_puzzle_reply *reply;
-+ struct iei_wt61p803_puzzle_mcu_version version;
-+ struct iei_wt61p803_puzzle_mcu_status status;
-+ unsigned char response_buffer[IEI_WT61P803_PUZZLE_BUF_SIZE];
-+ struct mutex lock; /* lock to protect response buffer */
-+};
-+
-+static unsigned char iei_wt61p803_puzzle_checksum(unsigned char *buf, size_t len)
-+{
-+ unsigned char checksum = 0;
-+ size_t i;
-+
-+ for (i = 0; i < len; i++)
-+ checksum ^= buf[i];
-+ return checksum;
-+}
-+
-+static int iei_wt61p803_puzzle_process_resp(struct iei_wt61p803_puzzle *mcu,
-+ const unsigned char *raw_resp_data, size_t size)
-+{
-+ unsigned char checksum;
-+
-+ /* Check the incoming frame header */
-+ if (!(raw_resp_data[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START ||
-+ raw_resp_data[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START_OTHER ||
-+ (raw_resp_data[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_EEPROM &&
-+ raw_resp_data[1] == IEI_WT61P803_PUZZLE_CMD_EEPROM_READ))) {
-+ if (mcu->reply->size + size >= sizeof(mcu->reply->data))
-+ return -EIO;
-+
-+ /* Append the frame to existing data */
-+ memcpy(mcu->reply->data + mcu->reply->size, raw_resp_data, size);
-+ mcu->reply->size += size;
-+ } else {
-+ if (size >= sizeof(mcu->reply->data))
-+ return -EIO;
-+
-+ /* Start processing a new frame */
-+ memcpy(mcu->reply->data, raw_resp_data, size);
-+ mcu->reply->size = size;
-+ }
-+
-+ checksum = iei_wt61p803_puzzle_checksum(mcu->reply->data, mcu->reply->size - 1);
-+ if (checksum != mcu->reply->data[mcu->reply->size - 1]) {
-+ /* The checksum isn't matched yet, wait for new frames */
-+ return size;
-+ }
-+
-+ /* Received all the data */
-+ complete(&mcu->reply->received);
-+
-+ return size;
-+}
-+
-+static int iei_wt61p803_puzzle_recv_buf(struct serdev_device *serdev,
-+ const unsigned char *data, size_t size)
-+{
-+ struct iei_wt61p803_puzzle *mcu = serdev_device_get_drvdata(serdev);
-+ int ret;
-+
-+ ret = iei_wt61p803_puzzle_process_resp(mcu, data, size);
-+ /* Return the number of processed bytes if function returns error,
-+ * discard the remaining incoming data, since the frame this data
-+ * belongs to is broken anyway
-+ */
-+ if (ret < 0)
-+ return size;
-+
-+ return ret;
-+}
-+
-+static const struct serdev_device_ops iei_wt61p803_puzzle_serdev_device_ops = {
-+ .receive_buf = iei_wt61p803_puzzle_recv_buf,
-+ .write_wakeup = serdev_device_write_wakeup,
-+};
-+
-+/**
-+ * iei_wt61p803_puzzle_write_command_watchdog() - Watchdog of the normal cmd
-+ * @mcu: Pointer to the iei_wt61p803_puzzle core MFD struct
-+ * @cmd: Pointer to the char array to send (size should be content + 1 (xor))
-+ * @size: Size of the cmd char array
-+ * @reply_data: Pointer to the reply/response data array (should be allocated)
-+ * @reply_size: Pointer to size_t (size of reply_data)
-+ * @retry_count: Number of times to retry sending the command to the MCU
-+ */
-+int iei_wt61p803_puzzle_write_command_watchdog(struct iei_wt61p803_puzzle *mcu,
-+ unsigned char *cmd, size_t size,
-+ unsigned char *reply_data,
-+ size_t *reply_size, int retry_count)
-+{
-+ struct device *dev = &mcu->serdev->dev;
-+ int ret, i;
-+
-+ for (i = 0; i < retry_count; i++) {
-+ ret = iei_wt61p803_puzzle_write_command(mcu, cmd, size,
-+ reply_data, reply_size);
-+ if (ret != -ETIMEDOUT)
-+ return ret;
-+ }
-+
-+ dev_err(dev, "Command response timed out. Retries: %d\n", retry_count);
-+
-+ return -ETIMEDOUT;
-+}
-+EXPORT_SYMBOL_GPL(iei_wt61p803_puzzle_write_command_watchdog);
-+
-+/**
-+ * iei_wt61p803_puzzle_write_command() - Send a structured command to the MCU
-+ * @mcu: Pointer to the iei_wt61p803_puzzle core MFD struct
-+ * @cmd: Pointer to the char array to send (size should be content + 1 (xor))
-+ * @size: Size of the cmd char array
-+ * @reply_data: Pointer to the reply/response data array (should be allocated)
-+ *
-+ * Sends a structured command to the MCU.
-+ */
-+int iei_wt61p803_puzzle_write_command(struct iei_wt61p803_puzzle *mcu,
-+ unsigned char *cmd, size_t size,
-+ unsigned char *reply_data,
-+ size_t *reply_size)
-+{
-+ struct device *dev = &mcu->serdev->dev;
-+ int ret;
-+
-+ if (size <= 1 || size > IEI_WT61P803_PUZZLE_MAX_COMMAND_LENGTH)
-+ return -EINVAL;
-+
-+ mutex_lock(&mcu->reply_lock);
-+
-+ cmd[size - 1] = iei_wt61p803_puzzle_checksum(cmd, size - 1);
-+
-+ /* Initialize reply struct */
-+ reinit_completion(&mcu->reply->received);
-+ mcu->reply->size = 0;
-+ usleep_range(2000, 10000);
-+ serdev_device_write_flush(mcu->serdev);
-+ ret = serdev_device_write_buf(mcu->serdev, cmd, size);
-+ if (ret < 0)
-+ goto exit;
-+
-+ serdev_device_wait_until_sent(mcu->serdev, IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
-+ ret = wait_for_completion_timeout(&mcu->reply->received,
-+ IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
-+ if (ret == 0) {
-+ dev_err(dev, "Command reply receive timeout\n");
-+ ret = -ETIMEDOUT;
-+ goto exit;
-+ }
-+
-+ *reply_size = mcu->reply->size;
-+ /* Copy the received data, as it will not be available after a new frame is received */
-+ memcpy(reply_data, mcu->reply->data, mcu->reply->size);
-+ ret = 0;
-+exit:
-+ mutex_unlock(&mcu->reply_lock);
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(iei_wt61p803_puzzle_write_command);
-+
-+static int iei_wt61p803_puzzle_buzzer(struct iei_wt61p803_puzzle *mcu, bool long_beep)
-+{
-+ unsigned char *resp_buf = mcu->response_buffer;
-+ unsigned char buzzer_cmd[4] = {};
-+ size_t reply_size;
-+ int ret;
-+
-+ buzzer_cmd[0] = IEI_WT61P803_PUZZLE_CMD_HEADER_START;
-+ buzzer_cmd[1] = IEI_WT61P803_PUZZLE_CMD_FUNCTION_SINGLE;
-+ buzzer_cmd[2] = long_beep ? '3' : '2'; /* Buzzer 1.5 / 0.5 second beep */
-+
-+ mutex_lock(&mcu->lock);
-+ ret = iei_wt61p803_puzzle_write_command(mcu, buzzer_cmd, sizeof(buzzer_cmd),
-+ resp_buf, &reply_size);
-+ if (ret)
-+ goto exit;
-+
-+ if (reply_size != 3) {
-+ ret = -EIO;
-+ goto exit;
-+ }
-+
-+ if (!(resp_buf[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
-+ resp_buf[1] == IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK &&
-+ resp_buf[2] == IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK)) {
-+ ret = -EPROTO;
-+ goto exit;
-+ }
-+exit:
-+ mutex_unlock(&mcu->lock);
-+ return ret;
-+}
-+
-+static int iei_wt61p803_puzzle_get_version(struct iei_wt61p803_puzzle *mcu)
-+{
-+ unsigned char version_cmd[3] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_START_OTHER,
-+ IEI_WT61P803_PUZZLE_CMD_OTHER_VERSION,
-+ };
-+ unsigned char build_info_cmd[3] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_START_OTHER,
-+ IEI_WT61P803_PUZZLE_CMD_OTHER_BUILD,
-+ };
-+ unsigned char bootloader_mode_cmd[3] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_START_OTHER,
-+ IEI_WT61P803_PUZZLE_CMD_OTHER_BOOTLOADER_MODE,
-+ };
-+ unsigned char protocol_version_cmd[3] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_START_OTHER,
-+ IEI_WT61P803_PUZZLE_CMD_OTHER_PROTOCOL_VERSION,
-+ };
-+ unsigned char *rb = mcu->response_buffer;
-+ size_t reply_size;
-+ int ret;
-+
-+ mutex_lock(&mcu->lock);
-+
-+ ret = iei_wt61p803_puzzle_write_command(mcu, version_cmd, sizeof(version_cmd),
-+ rb, &reply_size);
-+ if (ret)
-+ goto err;
-+ if (reply_size < 7) {
-+ ret = -EIO;
-+ goto err;
-+ }
-+ sprintf(mcu->version.version, "v%c.%.3s", rb[2], &rb[3]);
-+
-+ ret = iei_wt61p803_puzzle_write_command(mcu, build_info_cmd,
-+ sizeof(build_info_cmd), rb,
-+ &reply_size);
-+ if (ret)
-+ goto err;
-+ if (reply_size < 15) {
-+ ret = -EIO;
-+ goto err;
-+ }
-+ sprintf(mcu->version.build_info, "%c%c/%c%c/%.4s %c%c:%c%c",
-+ rb[8], rb[9], rb[6], rb[7], &rb[2], rb[10], rb[11],
-+ rb[12], rb[13]);
-+
-+ ret = iei_wt61p803_puzzle_write_command(mcu, bootloader_mode_cmd,
-+ sizeof(bootloader_mode_cmd), rb,
-+ &reply_size);
-+ if (ret)
-+ goto err;
-+ if (reply_size < 4) {
-+ ret = -EIO;
-+ goto err;
-+ }
-+ if (rb[2] == IEI_WT61P803_PUZZLE_CMD_OTHER_MODE_APPS)
-+ mcu->version.bootloader_mode = false;
-+ else if (rb[2] == IEI_WT61P803_PUZZLE_CMD_OTHER_MODE_BOOTLOADER)
-+ mcu->version.bootloader_mode = true;
-+
-+ ret = iei_wt61p803_puzzle_write_command(mcu, protocol_version_cmd,
-+ sizeof(protocol_version_cmd), rb,
-+ &reply_size);
-+ if (ret)
-+ goto err;
-+ if (reply_size < 9) {
-+ ret = -EIO;
-+ goto err;
-+ }
-+ sprintf(mcu->version.protocol_version, "v%c.%c%c%c%c%c",
-+ rb[7], rb[6], rb[5], rb[4], rb[3], rb[2]);
-+err:
-+ mutex_unlock(&mcu->lock);
-+ return ret;
-+}
-+
-+static int iei_wt61p803_puzzle_get_mcu_status(struct iei_wt61p803_puzzle *mcu)
-+{
-+ unsigned char mcu_status_cmd[5] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_START,
-+ IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER,
-+ IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER_STATUS,
-+ IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER_STATUS,
-+ };
-+ unsigned char *resp_buf = mcu->response_buffer;
-+ size_t reply_size;
-+ int ret;
-+
-+ mutex_lock(&mcu->lock);
-+ ret = iei_wt61p803_puzzle_write_command(mcu, mcu_status_cmd, sizeof(mcu_status_cmd),
-+ resp_buf, &reply_size);
-+ if (ret)
-+ goto exit;
-+ if (reply_size < 20) {
-+ ret = -EIO;
-+ goto exit;
-+ }
-+
-+ /* Response format:
-+ * (IDX RESPONSE)
-+ * 0 @
-+ * 1 O
-+ * 2 S
-+ * 3 S
-+ * ...
-+ * 5 AC Recovery Status Flag
-+ * ...
-+ * 10 Power Loss Recovery
-+ * ...
-+ * 19 Power Status (system power on method)
-+ * 20 XOR checksum
-+ */
-+ if (resp_buf[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
-+ resp_buf[1] == IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER &&
-+ resp_buf[2] == IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER_STATUS &&
-+ resp_buf[3] == IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER_STATUS) {
-+ mcu->status.ac_recovery_status_flag = resp_buf[5];
-+ mcu->status.power_loss_recovery = resp_buf[10];
-+ mcu->status.power_status = resp_buf[19];
-+ }
-+exit:
-+ mutex_unlock(&mcu->lock);
-+ return ret;
-+}
-+
-+static int iei_wt61p803_puzzle_get_serial_number(struct iei_wt61p803_puzzle *mcu)
-+{
-+ unsigned char *resp_buf = mcu->response_buffer;
-+ unsigned char serial_number_cmd[5] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_EEPROM,
-+ IEI_WT61P803_PUZZLE_CMD_EEPROM_READ,
-+ 0x00, /* EEPROM read address */
-+ 0x24, /* Data length */
-+ };
-+ size_t reply_size;
-+ int ret;
-+
-+ mutex_lock(&mcu->lock);
-+ ret = iei_wt61p803_puzzle_write_command(mcu, serial_number_cmd,
-+ sizeof(serial_number_cmd),
-+ resp_buf, &reply_size);
-+ if (ret)
-+ goto err;
-+
-+ if (reply_size < IEI_WT61P803_PUZZLE_SN_LENGTH + 4) {
-+ ret = -EIO;
-+ goto err;
-+ }
-+
-+ sprintf(mcu->version.serial_number, "%.*s",
-+ IEI_WT61P803_PUZZLE_SN_LENGTH, resp_buf + 4);
-+err:
-+ mutex_unlock(&mcu->lock);
-+ return ret;
-+}
-+
-+static int iei_wt61p803_puzzle_write_serial_number(struct iei_wt61p803_puzzle *mcu,
-+ unsigned char serial_number[36])
-+{
-+ unsigned char *resp_buf = mcu->response_buffer;
-+ unsigned char serial_number_header[4] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_EEPROM,
-+ IEI_WT61P803_PUZZLE_CMD_EEPROM_WRITE,
-+ 0x00, /* EEPROM write address */
-+ 0xC, /* Data length */
-+ };
-+ unsigned char serial_number_cmd[4 + 12 + 1]; /* header, serial number, XOR checksum */
-+ int ret, sn_counter;
-+ size_t reply_size;
-+
-+ /* The MCU can only handle 22 byte messages, send the S/N in 12 byte chunks */
-+ mutex_lock(&mcu->lock);
-+ for (sn_counter = 0; sn_counter < 3; sn_counter++) {
-+ serial_number_header[2] = 0x0 + 0xC * sn_counter;
-+
-+ memcpy(serial_number_cmd, serial_number_header, sizeof(serial_number_header));
-+ memcpy(serial_number_cmd + sizeof(serial_number_header),
-+ serial_number + 0xC * sn_counter, 0xC);
-+
-+ ret = iei_wt61p803_puzzle_write_command(mcu, serial_number_cmd,
-+ sizeof(serial_number_cmd),
-+ resp_buf, &reply_size);
-+ if (ret)
-+ goto err;
-+ if (reply_size != 3) {
-+ ret = -EIO;
-+ goto err;
-+ }
-+ if (!(resp_buf[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
-+ resp_buf[1] == IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK &&
-+ resp_buf[2] == IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK)) {
-+ ret = -EPROTO;
-+ goto err;
-+ }
-+ }
-+
-+ sprintf(mcu->version.serial_number, "%.*s",
-+ IEI_WT61P803_PUZZLE_SN_LENGTH, serial_number);
-+err:
-+ mutex_unlock(&mcu->lock);
-+ return ret;
-+}
-+
-+static int iei_wt61p803_puzzle_get_mac_address(struct iei_wt61p803_puzzle *mcu, int index)
-+{
-+ unsigned char *resp_buf = mcu->response_buffer;
-+ unsigned char mac_address_cmd[5] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_EEPROM,
-+ IEI_WT61P803_PUZZLE_CMD_EEPROM_READ,
-+ 0x00, /* EEPROM read address */
-+ 0x11, /* Data length */
-+ };
-+ size_t reply_size;
-+ int ret;
-+
-+ mutex_lock(&mcu->lock);
-+ mac_address_cmd[2] = 0x24 + 0x11 * index;
-+
-+ ret = iei_wt61p803_puzzle_write_command(mcu, mac_address_cmd,
-+ sizeof(mac_address_cmd),
-+ resp_buf, &reply_size);
-+ if (ret)
-+ goto err;
-+
-+ if (reply_size < 22) {
-+ ret = -EIO;
-+ goto err;
-+ }
-+
-+ sprintf(mcu->version.mac_address[index], "%.*s",
-+ IEI_WT61P803_PUZZLE_MAC_LENGTH, resp_buf + 4);
-+err:
-+ mutex_unlock(&mcu->lock);
-+ return ret;
-+}
-+
-+static int
-+iei_wt61p803_puzzle_write_mac_address(struct iei_wt61p803_puzzle *mcu,
-+ unsigned char mac_address[IEI_WT61P803_PUZZLE_MAC_LENGTH],
-+ int mac_address_idx)
-+{
-+ unsigned char mac_address_cmd[4 + IEI_WT61P803_PUZZLE_MAC_LENGTH + 1];
-+ unsigned char *resp_buf = mcu->response_buffer;
-+ unsigned char mac_address_header[4] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_EEPROM,
-+ IEI_WT61P803_PUZZLE_CMD_EEPROM_WRITE,
-+ 0x00, /* EEPROM write address */
-+ 0x11, /* Data length */
-+ };
-+ size_t reply_size;
-+ int ret;
-+
-+ if (mac_address_idx < 0 || mac_address_idx >= IEI_WT61P803_PUZZLE_NB_MAC)
-+ return -EINVAL;
-+
-+ mac_address_header[2] = 0x24 + 0x11 * mac_address_idx;
-+
-+ /* Concat mac_address_header, mac_address to mac_address_cmd */
-+ memcpy(mac_address_cmd, mac_address_header, sizeof(mac_address_header));
-+ memcpy(mac_address_cmd + sizeof(mac_address_header), mac_address,
-+ IEI_WT61P803_PUZZLE_MAC_LENGTH);
-+
-+ mutex_lock(&mcu->lock);
-+ ret = iei_wt61p803_puzzle_write_command(mcu, mac_address_cmd,
-+ sizeof(mac_address_cmd),
-+ resp_buf, &reply_size);
-+ if (ret)
-+ goto err;
-+ if (reply_size != 3) {
-+ ret = -EIO;
-+ goto err;
-+ }
-+ if (!(resp_buf[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
-+ resp_buf[1] == IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK &&
-+ resp_buf[2] == IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK)) {
-+ ret = -EPROTO;
-+ goto err;
-+ }
-+
-+ sprintf(mcu->version.mac_address[mac_address_idx], "%.*s",
-+ IEI_WT61P803_PUZZLE_MAC_LENGTH, mac_address);
-+err:
-+ mutex_unlock(&mcu->lock);
-+ return ret;
-+}
-+
-+static int iei_wt61p803_puzzle_write_power_loss_recovery(struct iei_wt61p803_puzzle *mcu,
-+ int power_loss_recovery_action)
-+{
-+ unsigned char *resp_buf = mcu->response_buffer;
-+ unsigned char power_loss_recovery_cmd[5] = {};
-+ size_t reply_size;
-+ int ret;
-+
-+ if (power_loss_recovery_action < 0 || power_loss_recovery_action > 4)
-+ return -EINVAL;
-+
-+ power_loss_recovery_cmd[0] = IEI_WT61P803_PUZZLE_CMD_HEADER_START;
-+ power_loss_recovery_cmd[1] = IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER;
-+ power_loss_recovery_cmd[2] = IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER_POWER_LOSS;
-+ power_loss_recovery_cmd[3] = hex_asc[power_loss_recovery_action];
-+
-+ mutex_lock(&mcu->lock);
-+ ret = iei_wt61p803_puzzle_write_command(mcu, power_loss_recovery_cmd,
-+ sizeof(power_loss_recovery_cmd),
-+ resp_buf, &reply_size);
-+ if (ret)
-+ goto exit;
-+ mcu->status.power_loss_recovery = power_loss_recovery_action;
-+exit:
-+ mutex_unlock(&mcu->lock);
-+ return ret;
-+}
-+
-+#define to_puzzle_dev_attr(_attr) \
-+ container_of(_attr, struct iei_wt61p803_puzzle_device_attribute, dev_attr)
-+
-+static ssize_t show_output(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct iei_wt61p803_puzzle *mcu = dev_get_drvdata(dev);
-+ struct iei_wt61p803_puzzle_device_attribute *pattr = to_puzzle_dev_attr(attr);
-+ int ret;
-+
-+ switch (pattr->type) {
-+ case IEI_WT61P803_PUZZLE_VERSION:
-+ return scnprintf(buf, PAGE_SIZE, "%s\n", mcu->version.version);
-+ case IEI_WT61P803_PUZZLE_BUILD_INFO:
-+ return scnprintf(buf, PAGE_SIZE, "%s\n", mcu->version.build_info);
-+ case IEI_WT61P803_PUZZLE_BOOTLOADER_MODE:
-+ return scnprintf(buf, PAGE_SIZE, "%d\n", mcu->version.bootloader_mode);
-+ case IEI_WT61P803_PUZZLE_PROTOCOL_VERSION:
-+ return scnprintf(buf, PAGE_SIZE, "%s\n", mcu->version.protocol_version);
-+ case IEI_WT61P803_PUZZLE_SERIAL_NUMBER:
-+ ret = iei_wt61p803_puzzle_get_serial_number(mcu);
-+ if (!ret)
-+ ret = scnprintf(buf, PAGE_SIZE, "%s\n", mcu->version.serial_number);
-+ else
-+ ret = 0;
-+ return ret;
-+ case IEI_WT61P803_PUZZLE_MAC_ADDRESS:
-+ ret = iei_wt61p803_puzzle_get_mac_address(mcu, pattr->index);
-+ if (!ret)
-+ ret = scnprintf(buf, PAGE_SIZE, "%s\n",
-+ mcu->version.mac_address[pattr->index]);
-+ else
-+ ret = 0;
-+ return ret;
-+ case IEI_WT61P803_PUZZLE_AC_RECOVERY_STATUS:
-+ case IEI_WT61P803_PUZZLE_POWER_LOSS_RECOVERY:
-+ case IEI_WT61P803_PUZZLE_POWER_STATUS:
-+ ret = iei_wt61p803_puzzle_get_mcu_status(mcu);
-+ if (ret)
-+ return ret;
-+
-+ mutex_lock(&mcu->lock);
-+ switch (pattr->type) {
-+ case IEI_WT61P803_PUZZLE_AC_RECOVERY_STATUS:
-+ ret = scnprintf(buf, PAGE_SIZE, "%x\n",
-+ mcu->status.ac_recovery_status_flag);
-+ break;
-+ case IEI_WT61P803_PUZZLE_POWER_LOSS_RECOVERY:
-+ ret = scnprintf(buf, PAGE_SIZE, "%x\n", mcu->status.power_loss_recovery);
-+ break;
-+ case IEI_WT61P803_PUZZLE_POWER_STATUS:
-+ ret = scnprintf(buf, PAGE_SIZE, "%x\n", mcu->status.power_status);
-+ break;
-+ default:
-+ ret = 0;
-+ break;
-+ }
-+ mutex_unlock(&mcu->lock);
-+ return ret;
-+ default:
-+ return 0;
-+ }
-+
-+ return 0;
-+}
-+
-+static ssize_t store_output(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t len)
-+{
-+ unsigned char serial_number[IEI_WT61P803_PUZZLE_SN_LENGTH];
-+ unsigned char mac_address[IEI_WT61P803_PUZZLE_MAC_LENGTH];
-+ struct iei_wt61p803_puzzle *mcu = dev_get_drvdata(dev);
-+ struct iei_wt61p803_puzzle_device_attribute *pattr = to_puzzle_dev_attr(attr);
-+ int power_loss_recovery_action = 0;
-+ int ret;
-+
-+ switch (pattr->type) {
-+ case IEI_WT61P803_PUZZLE_SERIAL_NUMBER:
-+ if (len != (size_t)(IEI_WT61P803_PUZZLE_SN_LENGTH + 1))
-+ return -EINVAL;
-+ memcpy(serial_number, buf, sizeof(serial_number));
-+ ret = iei_wt61p803_puzzle_write_serial_number(mcu, serial_number);
-+ if (ret)
-+ return ret;
-+ return len;
-+ case IEI_WT61P803_PUZZLE_MAC_ADDRESS:
-+ if (len != (size_t)(IEI_WT61P803_PUZZLE_MAC_LENGTH + 1))
-+ return -EINVAL;
-+
-+ memcpy(mac_address, buf, sizeof(mac_address));
-+
-+ if (strlen(attr->attr.name) != 13)
-+ return -EIO;
-+
-+ ret = iei_wt61p803_puzzle_write_mac_address(mcu, mac_address, pattr->index);
-+ if (ret)
-+ return ret;
-+ return len;
-+ case IEI_WT61P803_PUZZLE_POWER_LOSS_RECOVERY:
-+ ret = kstrtoint(buf, 10, &power_loss_recovery_action);
-+ if (ret)
-+ return ret;
-+ ret = iei_wt61p803_puzzle_write_power_loss_recovery(mcu,
-+ power_loss_recovery_action);
-+ if (ret)
-+ return ret;
-+ return len;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+#define IEI_WT61P803_PUZZLE_ATTR(_name, _mode, _show, _store, _type, _index) \
-+ struct iei_wt61p803_puzzle_device_attribute dev_attr_##_name = \
-+ { .dev_attr = __ATTR(_name, _mode, _show, _store), \
-+ .type = _type, \
-+ .index = _index }
-+
-+#define IEI_WT61P803_PUZZLE_ATTR_RO(_name, _type, _id) \
-+ IEI_WT61P803_PUZZLE_ATTR(_name, 0444, show_output, NULL, _type, _id)
-+
-+#define IEI_WT61P803_PUZZLE_ATTR_RW(_name, _type, _id) \
-+ IEI_WT61P803_PUZZLE_ATTR(_name, 0644, show_output, store_output, _type, _id)
-+
-+static IEI_WT61P803_PUZZLE_ATTR_RO(version, IEI_WT61P803_PUZZLE_VERSION, 0);
-+static IEI_WT61P803_PUZZLE_ATTR_RO(build_info, IEI_WT61P803_PUZZLE_BUILD_INFO, 0);
-+static IEI_WT61P803_PUZZLE_ATTR_RO(bootloader_mode, IEI_WT61P803_PUZZLE_BOOTLOADER_MODE, 0);
-+static IEI_WT61P803_PUZZLE_ATTR_RO(protocol_version, IEI_WT61P803_PUZZLE_PROTOCOL_VERSION, 0);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(serial_number, IEI_WT61P803_PUZZLE_SERIAL_NUMBER, 0);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(mac_address_0, IEI_WT61P803_PUZZLE_MAC_ADDRESS, 0);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(mac_address_1, IEI_WT61P803_PUZZLE_MAC_ADDRESS, 1);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(mac_address_2, IEI_WT61P803_PUZZLE_MAC_ADDRESS, 2);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(mac_address_3, IEI_WT61P803_PUZZLE_MAC_ADDRESS, 3);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(mac_address_4, IEI_WT61P803_PUZZLE_MAC_ADDRESS, 4);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(mac_address_5, IEI_WT61P803_PUZZLE_MAC_ADDRESS, 5);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(mac_address_6, IEI_WT61P803_PUZZLE_MAC_ADDRESS, 6);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(mac_address_7, IEI_WT61P803_PUZZLE_MAC_ADDRESS, 7);
-+static IEI_WT61P803_PUZZLE_ATTR_RO(ac_recovery_status, IEI_WT61P803_PUZZLE_AC_RECOVERY_STATUS, 0);
-+static IEI_WT61P803_PUZZLE_ATTR_RW(power_loss_recovery, IEI_WT61P803_PUZZLE_POWER_LOSS_RECOVERY, 0);
-+static IEI_WT61P803_PUZZLE_ATTR_RO(power_status, IEI_WT61P803_PUZZLE_POWER_STATUS, 0);
-+
-+static struct attribute *iei_wt61p803_puzzle_attrs[] = {
-+ &dev_attr_version.dev_attr.attr,
-+ &dev_attr_build_info.dev_attr.attr,
-+ &dev_attr_bootloader_mode.dev_attr.attr,
-+ &dev_attr_protocol_version.dev_attr.attr,
-+ &dev_attr_serial_number.dev_attr.attr,
-+ &dev_attr_mac_address_0.dev_attr.attr,
-+ &dev_attr_mac_address_1.dev_attr.attr,
-+ &dev_attr_mac_address_2.dev_attr.attr,
-+ &dev_attr_mac_address_3.dev_attr.attr,
-+ &dev_attr_mac_address_4.dev_attr.attr,
-+ &dev_attr_mac_address_5.dev_attr.attr,
-+ &dev_attr_mac_address_6.dev_attr.attr,
-+ &dev_attr_mac_address_7.dev_attr.attr,
-+ &dev_attr_ac_recovery_status.dev_attr.attr,
-+ &dev_attr_power_loss_recovery.dev_attr.attr,
-+ &dev_attr_power_status.dev_attr.attr,
-+ NULL
-+};
-+ATTRIBUTE_GROUPS(iei_wt61p803_puzzle);
-+
-+static int iei_wt61p803_puzzle_sysfs_create(struct device *dev,
-+ struct iei_wt61p803_puzzle *mcu)
-+{
-+ int ret;
-+
-+ ret = sysfs_create_groups(&mcu->dev->kobj, iei_wt61p803_puzzle_groups);
-+ if (ret)
-+ mfd_remove_devices(mcu->dev);
-+
-+ return ret;
-+}
-+
-+static int iei_wt61p803_puzzle_sysfs_remove(struct device *dev,
-+ struct iei_wt61p803_puzzle *mcu)
-+{
-+ /* Remove sysfs groups */
-+ sysfs_remove_groups(&mcu->dev->kobj, iei_wt61p803_puzzle_groups);
-+ mfd_remove_devices(mcu->dev);
-+
-+ return 0;
-+}
-+
-+static int iei_wt61p803_puzzle_probe(struct serdev_device *serdev)
-+{
-+ struct device *dev = &serdev->dev;
-+ struct iei_wt61p803_puzzle *mcu;
-+ u32 baud;
-+ int ret;
-+
-+ /* Read the baud rate from 'current-speed', because the MCU supports different rates */
-+ if (device_property_read_u32(dev, "current-speed", &baud)) {
-+ dev_err(dev,
-+ "'current-speed' is not specified in device node\n");
-+ return -EINVAL;
-+ }
-+ dev_dbg(dev, "Driver baud rate: %d\n", baud);
-+
-+ /* Allocate the memory */
-+ mcu = devm_kzalloc(dev, sizeof(*mcu), GFP_KERNEL);
-+ if (!mcu)
-+ return -ENOMEM;
-+
-+ mcu->reply = devm_kzalloc(dev, sizeof(*mcu->reply), GFP_KERNEL);
-+ if (!mcu->reply)
-+ return -ENOMEM;
-+
-+ /* Initialize device struct data */
-+ mcu->serdev = serdev;
-+ mcu->dev = dev;
-+ init_completion(&mcu->reply->received);
-+ mutex_init(&mcu->reply_lock);
-+ mutex_init(&mcu->lock);
-+
-+ /* Setup UART interface */
-+ serdev_device_set_drvdata(serdev, mcu);
-+ serdev_device_set_client_ops(serdev, &iei_wt61p803_puzzle_serdev_device_ops);
-+ ret = devm_serdev_device_open(dev, serdev);
-+ if (ret)
-+ return ret;
-+ serdev_device_set_baudrate(serdev, baud);
-+ serdev_device_set_flow_control(serdev, false);
-+ ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE);
-+ if (ret) {
-+ dev_err(dev, "Failed to set parity\n");
-+ return ret;
-+ }
-+
-+ ret = iei_wt61p803_puzzle_get_version(mcu);
-+ if (ret)
-+ return ret;
-+
-+ dev_dbg(dev, "MCU version: %s\n", mcu->version.version);
-+ dev_dbg(dev, "MCU firmware build info: %s\n", mcu->version.build_info);
-+ dev_dbg(dev, "MCU in bootloader mode: %s\n",
-+ mcu->version.bootloader_mode ? "true" : "false");
-+ dev_dbg(dev, "MCU protocol version: %s\n", mcu->version.protocol_version);
-+
-+ if (device_property_read_bool(dev, "enable-beep")) {
-+ ret = iei_wt61p803_puzzle_buzzer(mcu, false);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ ret = iei_wt61p803_puzzle_sysfs_create(dev, mcu);
-+ if (ret)
-+ return ret;
-+
-+ return devm_of_platform_populate(dev);
-+}
-+
-+static void iei_wt61p803_puzzle_remove(struct serdev_device *serdev)
-+{
-+ struct device *dev = &serdev->dev;
-+ struct iei_wt61p803_puzzle *mcu = dev_get_drvdata(dev);
-+
-+ iei_wt61p803_puzzle_sysfs_remove(dev, mcu);
-+}
-+
-+static const struct of_device_id iei_wt61p803_puzzle_dt_ids[] = {
-+ { .compatible = "iei,wt61p803-puzzle" },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(of, iei_wt61p803_puzzle_dt_ids);
-+
-+static struct serdev_device_driver iei_wt61p803_puzzle_drv = {
-+ .probe = iei_wt61p803_puzzle_probe,
-+ .remove = iei_wt61p803_puzzle_remove,
-+ .driver = {
-+ .name = "iei-wt61p803-puzzle",
-+ .of_match_table = iei_wt61p803_puzzle_dt_ids,
-+ },
-+};
-+
-+module_serdev_device_driver(iei_wt61p803_puzzle_drv);
-+
-+MODULE_LICENSE("GPL v2");
-+MODULE_AUTHOR("Luka Kovacic <luka.kovacic@sartura.hr>");
-+MODULE_DESCRIPTION("IEI WT61P803 PUZZLE MCU Driver");
---- /dev/null
-+++ b/include/linux/mfd/iei-wt61p803-puzzle.h
-@@ -0,0 +1,66 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/* IEI WT61P803 PUZZLE MCU Driver
-+ * System management microcontroller for fan control, temperature sensor reading,
-+ * LED control and system identification on IEI Puzzle series ARM-based appliances.
-+ *
-+ * Copyright (C) 2020 Sartura Ltd.
-+ * Author: Luka Kovacic <luka.kovacic@sartura.hr>
-+ */
-+
-+#ifndef _MFD_IEI_WT61P803_PUZZLE_H_
-+#define _MFD_IEI_WT61P803_PUZZLE_H_
-+
-+#define IEI_WT61P803_PUZZLE_BUF_SIZE 512
-+
-+/* Command magic numbers */
-+#define IEI_WT61P803_PUZZLE_CMD_HEADER_START 0x40 /* @ */
-+#define IEI_WT61P803_PUZZLE_CMD_HEADER_START_OTHER 0x25 /* % */
-+#define IEI_WT61P803_PUZZLE_CMD_HEADER_EEPROM 0xF7
-+
-+#define IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK 0x30 /* 0 */
-+#define IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK 0x70
-+
-+#define IEI_WT61P803_PUZZLE_CMD_EEPROM_READ 0xA1
-+#define IEI_WT61P803_PUZZLE_CMD_EEPROM_WRITE 0xA0
-+
-+#define IEI_WT61P803_PUZZLE_CMD_OTHER_VERSION 0x56 /* V */
-+#define IEI_WT61P803_PUZZLE_CMD_OTHER_BUILD 0x42 /* B */
-+#define IEI_WT61P803_PUZZLE_CMD_OTHER_BOOTLOADER_MODE 0x4D /* M */
-+#define IEI_WT61P803_PUZZLE_CMD_OTHER_MODE_BOOTLOADER 0x30
-+#define IEI_WT61P803_PUZZLE_CMD_OTHER_MODE_APPS 0x31
-+#define IEI_WT61P803_PUZZLE_CMD_OTHER_PROTOCOL_VERSION 0x50 /* P */
-+
-+#define IEI_WT61P803_PUZZLE_CMD_FUNCTION_SINGLE 0x43 /* C */
-+#define IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER 0x4F /* O */
-+#define IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER_STATUS 0x53 /* S */
-+#define IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER_POWER_LOSS 0x41 /* A */
-+
-+#define IEI_WT61P803_PUZZLE_CMD_LED 0x52 /* R */
-+#define IEI_WT61P803_PUZZLE_CMD_LED_POWER 0x31 /* 1 */
-+
-+#define IEI_WT61P803_PUZZLE_CMD_TEMP 0x54 /* T */
-+#define IEI_WT61P803_PUZZLE_CMD_TEMP_ALL 0x41 /* A */
-+
-+#define IEI_WT61P803_PUZZLE_CMD_FAN 0x46 /* F */
-+#define IEI_WT61P803_PUZZLE_CMD_FAN_PWM_READ 0x5A /* Z */
-+#define IEI_WT61P803_PUZZLE_CMD_FAN_PWM_WRITE 0x57 /* W */
-+#define IEI_WT61P803_PUZZLE_CMD_FAN_PWM_BASE 0x30
-+#define IEI_WT61P803_PUZZLE_CMD_FAN_RPM_BASE 0x41 /* A */
-+
-+#define IEI_WT61P803_PUZZLE_CMD_FAN_PWM(x) (IEI_WT61P803_PUZZLE_CMD_FAN_PWM_BASE + (x)) /* 0 - 1 */
-+#define IEI_WT61P803_PUZZLE_CMD_FAN_RPM(x) (IEI_WT61P803_PUZZLE_CMD_FAN_RPM_BASE + (x)) /* 0 - 5 */
-+
-+struct iei_wt61p803_puzzle_mcu_version;
-+struct iei_wt61p803_puzzle_reply;
-+struct iei_wt61p803_puzzle;
-+
-+int iei_wt61p803_puzzle_write_command_watchdog(struct iei_wt61p803_puzzle *mcu,
-+ unsigned char *cmd, size_t size,
-+ unsigned char *reply_data, size_t *reply_size,
-+ int retry_count);
-+
-+int iei_wt61p803_puzzle_write_command(struct iei_wt61p803_puzzle *mcu,
-+ unsigned char *cmd, size_t size,
-+ unsigned char *reply_data, size_t *reply_size);
-+
-+#endif /* _MFD_IEI_WT61P803_PUZZLE_H_ */
+++ /dev/null
-From e3310a638cd310bfd93dbbc6d2732ab6aea18dd2 Mon Sep 17 00:00:00 2001
-From: Luka Kovacic <luka.kovacic () sartura ! hr>
-Date: Tue, 24 Aug 2021 12:44:34 +0000
-Subject: [PATCH 3/7] drivers: hwmon: Add the IEI WT61P803 PUZZLE HWMON driver
-
-Add the IEI WT61P803 PUZZLE HWMON driver, that handles the fan speed
-control via PWM, reading fan speed and reading on-board temperature
-sensors.
-
-The driver registers a HWMON device and a simple thermal cooling device to
-enable in-kernel fan management.
-
-This driver depends on the IEI WT61P803 PUZZLE MFD driver.
-
-Signed-off-by: Luka Kovacic <luka.kovacic@sartura.hr>
-Signed-off-by: Pavo Banicevic <pavo.banicevic@sartura.hr>
-Acked-by: Guenter Roeck <linux@roeck-us.net>
-Cc: Luka Perkov <luka.perkov@sartura.hr>
-Cc: Robert Marko <robert.marko@sartura.hr>
----
- drivers/hwmon/Kconfig | 8 +
- drivers/hwmon/Makefile | 1 +
- drivers/hwmon/iei-wt61p803-puzzle-hwmon.c | 445 ++++++++++++++++++++++
- 3 files changed, 454 insertions(+)
- create mode 100644 drivers/hwmon/iei-wt61p803-puzzle-hwmon.c
-
---- a/drivers/hwmon/Kconfig
-+++ b/drivers/hwmon/Kconfig
-@@ -755,6 +755,14 @@ config SENSORS_IBMPOWERNV
- This driver can also be built as a module. If so, the module
- will be called ibmpowernv.
-
-+config SENSORS_IEI_WT61P803_PUZZLE_HWMON
-+ tristate "IEI WT61P803 PUZZLE MFD HWMON Driver"
-+ depends on MFD_IEI_WT61P803_PUZZLE
-+ help
-+ The IEI WT61P803 PUZZLE MFD HWMON Driver handles reading fan speed
-+ and writing fan PWM values. It also supports reading on-board
-+ temperature sensors.
-+
- config SENSORS_IIO_HWMON
- tristate "Hwmon driver that uses channels specified via iio maps"
- depends on IIO
---- a/drivers/hwmon/Makefile
-+++ b/drivers/hwmon/Makefile
-@@ -87,6 +87,7 @@ obj-$(CONFIG_SENSORS_HIH6130) += hih6130
- obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
- obj-$(CONFIG_SENSORS_I5500) += i5500_temp.o
- obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
-+obj-$(CONFIG_SENSORS_IEI_WT61P803_PUZZLE_HWMON) += iei-wt61p803-puzzle-hwmon.o
- obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
- obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
- obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o
---- /dev/null
-+++ b/drivers/hwmon/iei-wt61p803-puzzle-hwmon.c
-@@ -0,0 +1,445 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* IEI WT61P803 PUZZLE MCU HWMON Driver
-+ *
-+ * Copyright (C) 2020 Sartura Ltd.
-+ * Author: Luka Kovacic <luka.kovacic@sartura.hr>
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/hwmon.h>
-+#include <linux/interrupt.h>
-+#include <linux/irq.h>
-+#include <linux/math64.h>
-+#include <linux/mfd/iei-wt61p803-puzzle.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/property.h>
-+#include <linux/slab.h>
-+#include <linux/thermal.h>
-+
-+#define IEI_WT61P803_PUZZLE_HWMON_MAX_PWM 2
-+#define IEI_WT61P803_PUZZLE_HWMON_MAX_PWM_VAL 255
-+
-+/**
-+ * struct iei_wt61p803_puzzle_thermal_cooling_device - Thermal cooling device instance
-+ * @mcu_hwmon: Parent driver struct pointer
-+ * @tcdev: Thermal cooling device pointer
-+ * @name: Thermal cooling device name
-+ * @pwm_channel: Controlled PWM channel (0 or 1)
-+ * @cooling_levels: Thermal cooling device cooling levels (DT)
-+ * @cur_level: Current cooling level
-+ * @num_levels: Number of cooling levels
-+ */
-+struct iei_wt61p803_puzzle_thermal_cooling_device {
-+ struct iei_wt61p803_puzzle_hwmon *mcu_hwmon;
-+ struct thermal_cooling_device *tcdev;
-+ char name[THERMAL_NAME_LENGTH];
-+ int pwm_channel;
-+ u32 *cooling_levels;
-+ int cur_level;
-+ u8 num_levels;
-+};
-+
-+/**
-+ * struct iei_wt61p803_puzzle_hwmon - MCU HWMON Driver
-+ * @mcu: MCU struct pointer
-+ * @response_buffer Global MCU response buffer
-+ * @thermal_cooling_dev_present: Per-channel thermal cooling device control indicator
-+ * @cdev: Per-channel thermal cooling device private structure
-+ */
-+struct iei_wt61p803_puzzle_hwmon {
-+ struct iei_wt61p803_puzzle *mcu;
-+ unsigned char response_buffer[IEI_WT61P803_PUZZLE_BUF_SIZE];
-+ bool thermal_cooling_dev_present[IEI_WT61P803_PUZZLE_HWMON_MAX_PWM];
-+ struct iei_wt61p803_puzzle_thermal_cooling_device
-+ *cdev[IEI_WT61P803_PUZZLE_HWMON_MAX_PWM];
-+ struct mutex lock; /* mutex to protect response_buffer array */
-+};
-+
-+#define raw_temp_to_milidegree_celsius(x) (((x) - 0x80) * 1000)
-+static int iei_wt61p803_puzzle_read_temp_sensor(struct iei_wt61p803_puzzle_hwmon *mcu_hwmon,
-+ int channel, long *value)
-+{
-+ unsigned char *resp_buf = mcu_hwmon->response_buffer;
-+ unsigned char temp_sensor_ntc_cmd[4] = {
-+ IEI_WT61P803_PUZZLE_CMD_HEADER_START,
-+ IEI_WT61P803_PUZZLE_CMD_TEMP,
-+ IEI_WT61P803_PUZZLE_CMD_TEMP_ALL,
-+ };
-+ size_t reply_size;
-+ int ret;
-+
-+ mutex_lock(&mcu_hwmon->lock);
-+ ret = iei_wt61p803_puzzle_write_command(mcu_hwmon->mcu, temp_sensor_ntc_cmd,
-+ sizeof(temp_sensor_ntc_cmd), resp_buf,
-+ &reply_size);
-+ if (ret)
-+ goto exit;
-+
-+ if (reply_size != 7) {
-+ ret = -EIO;
-+ goto exit;
-+ }
-+
-+ /* Check the number of NTC values */
-+ if (resp_buf[3] != '2') {
-+ ret = -EIO;
-+ goto exit;
-+ }
-+
-+ *value = raw_temp_to_milidegree_celsius(resp_buf[4 + channel]);
-+exit:
-+ mutex_unlock(&mcu_hwmon->lock);
-+ return ret;
-+}
-+
-+#define raw_fan_val_to_rpm(x, y) ((((x) << 8 | (y)) / 2) * 60)
-+static int iei_wt61p803_puzzle_read_fan_speed(struct iei_wt61p803_puzzle_hwmon *mcu_hwmon,
-+ int channel, long *value)
-+{
-+ unsigned char *resp_buf = mcu_hwmon->response_buffer;
-+ unsigned char fan_speed_cmd[4] = {};
-+ size_t reply_size;
-+ int ret;
-+
-+ fan_speed_cmd[0] = IEI_WT61P803_PUZZLE_CMD_HEADER_START;
-+ fan_speed_cmd[1] = IEI_WT61P803_PUZZLE_CMD_FAN;
-+ fan_speed_cmd[2] = IEI_WT61P803_PUZZLE_CMD_FAN_RPM(channel);
-+
-+ mutex_lock(&mcu_hwmon->lock);
-+ ret = iei_wt61p803_puzzle_write_command(mcu_hwmon->mcu, fan_speed_cmd,
-+ sizeof(fan_speed_cmd), resp_buf,
-+ &reply_size);
-+ if (ret)
-+ goto exit;
-+
-+ if (reply_size != 7) {
-+ ret = -EIO;
-+ goto exit;
-+ }
-+
-+ *value = raw_fan_val_to_rpm(resp_buf[3], resp_buf[4]);
-+exit:
-+ mutex_unlock(&mcu_hwmon->lock);
-+ return ret;
-+}
-+
-+static int iei_wt61p803_puzzle_write_pwm_channel(struct iei_wt61p803_puzzle_hwmon *mcu_hwmon,
-+ int channel, long pwm_set_val)
-+{
-+ unsigned char *resp_buf = mcu_hwmon->response_buffer;
-+ unsigned char pwm_set_cmd[6] = {};
-+ size_t reply_size;
-+ int ret;
-+
-+ pwm_set_cmd[0] = IEI_WT61P803_PUZZLE_CMD_HEADER_START;
-+ pwm_set_cmd[1] = IEI_WT61P803_PUZZLE_CMD_FAN;
-+ pwm_set_cmd[2] = IEI_WT61P803_PUZZLE_CMD_FAN_PWM_WRITE;
-+ pwm_set_cmd[3] = IEI_WT61P803_PUZZLE_CMD_FAN_PWM(channel);
-+ pwm_set_cmd[4] = pwm_set_val;
-+
-+ mutex_lock(&mcu_hwmon->lock);
-+ ret = iei_wt61p803_puzzle_write_command(mcu_hwmon->mcu, pwm_set_cmd,
-+ sizeof(pwm_set_cmd), resp_buf,
-+ &reply_size);
-+ if (ret)
-+ goto exit;
-+
-+ if (reply_size != 3) {
-+ ret = -EIO;
-+ goto exit;
-+ }
-+
-+ if (!(resp_buf[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
-+ resp_buf[1] == IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK &&
-+ resp_buf[2] == IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK)) {
-+ ret = -EIO;
-+ goto exit;
-+ }
-+exit:
-+ mutex_unlock(&mcu_hwmon->lock);
-+ return ret;
-+}
-+
-+static int iei_wt61p803_puzzle_read_pwm_channel(struct iei_wt61p803_puzzle_hwmon *mcu_hwmon,
-+ int channel, long *value)
-+{
-+ unsigned char *resp_buf = mcu_hwmon->response_buffer;
-+ unsigned char pwm_get_cmd[5] = {};
-+ size_t reply_size;
-+ int ret;
-+
-+ pwm_get_cmd[0] = IEI_WT61P803_PUZZLE_CMD_HEADER_START;
-+ pwm_get_cmd[1] = IEI_WT61P803_PUZZLE_CMD_FAN;
-+ pwm_get_cmd[2] = IEI_WT61P803_PUZZLE_CMD_FAN_PWM_READ;
-+ pwm_get_cmd[3] = IEI_WT61P803_PUZZLE_CMD_FAN_PWM(channel);
-+
-+ ret = iei_wt61p803_puzzle_write_command(mcu_hwmon->mcu, pwm_get_cmd,
-+ sizeof(pwm_get_cmd), resp_buf,
-+ &reply_size);
-+ if (ret)
-+ return ret;
-+
-+ if (reply_size != 5)
-+ return -EIO;
-+
-+ if (resp_buf[2] != IEI_WT61P803_PUZZLE_CMD_FAN_PWM_READ)
-+ return -EIO;
-+
-+ *value = resp_buf[3];
-+
-+ return 0;
-+}
-+
-+static int iei_wt61p803_puzzle_read(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long *val)
-+{
-+ struct iei_wt61p803_puzzle_hwmon *mcu_hwmon = dev_get_drvdata(dev->parent);
-+
-+ switch (type) {
-+ case hwmon_pwm:
-+ return iei_wt61p803_puzzle_read_pwm_channel(mcu_hwmon, channel, val);
-+ case hwmon_fan:
-+ return iei_wt61p803_puzzle_read_fan_speed(mcu_hwmon, channel, val);
-+ case hwmon_temp:
-+ return iei_wt61p803_puzzle_read_temp_sensor(mcu_hwmon, channel, val);
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static int iei_wt61p803_puzzle_write(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long val)
-+{
-+ struct iei_wt61p803_puzzle_hwmon *mcu_hwmon = dev_get_drvdata(dev->parent);
-+
-+ return iei_wt61p803_puzzle_write_pwm_channel(mcu_hwmon, channel, val);
-+}
-+
-+static umode_t iei_wt61p803_puzzle_is_visible(const void *data, enum hwmon_sensor_types type,
-+ u32 attr, int channel)
-+{
-+ const struct iei_wt61p803_puzzle_hwmon *mcu_hwmon = data;
-+
-+ switch (type) {
-+ case hwmon_pwm:
-+ if (mcu_hwmon->thermal_cooling_dev_present[channel])
-+ return 0444;
-+ if (attr == hwmon_pwm_input)
-+ return 0644;
-+ break;
-+ case hwmon_fan:
-+ if (attr == hwmon_fan_input)
-+ return 0444;
-+ break;
-+ case hwmon_temp:
-+ if (attr == hwmon_temp_input)
-+ return 0444;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct hwmon_ops iei_wt61p803_puzzle_hwmon_ops = {
-+ .is_visible = iei_wt61p803_puzzle_is_visible,
-+ .read = iei_wt61p803_puzzle_read,
-+ .write = iei_wt61p803_puzzle_write,
-+};
-+
-+static const struct hwmon_channel_info *iei_wt61p803_puzzle_info[] = {
-+ HWMON_CHANNEL_INFO(pwm,
-+ HWMON_PWM_INPUT,
-+ HWMON_PWM_INPUT),
-+ HWMON_CHANNEL_INFO(fan,
-+ HWMON_F_INPUT,
-+ HWMON_F_INPUT,
-+ HWMON_F_INPUT,
-+ HWMON_F_INPUT,
-+ HWMON_F_INPUT),
-+ HWMON_CHANNEL_INFO(temp,
-+ HWMON_T_INPUT,
-+ HWMON_T_INPUT),
-+ NULL
-+};
-+
-+static const struct hwmon_chip_info iei_wt61p803_puzzle_chip_info = {
-+ .ops = &iei_wt61p803_puzzle_hwmon_ops,
-+ .info = iei_wt61p803_puzzle_info,
-+};
-+
-+static int iei_wt61p803_puzzle_get_max_state(struct thermal_cooling_device *tcdev,
-+ unsigned long *state)
-+{
-+ struct iei_wt61p803_puzzle_thermal_cooling_device *cdev = tcdev->devdata;
-+
-+ if (!cdev)
-+ return -EINVAL;
-+
-+ *state = cdev->num_levels - 1;
-+ return 0;
-+}
-+
-+static int iei_wt61p803_puzzle_get_cur_state(struct thermal_cooling_device *tcdev,
-+ unsigned long *state)
-+{
-+ struct iei_wt61p803_puzzle_thermal_cooling_device *cdev = tcdev->devdata;
-+
-+ if (!cdev)
-+ return -EINVAL;
-+
-+ if (cdev->cur_level < 0)
-+ return -EAGAIN;
-+
-+ *state = cdev->cur_level;
-+ return 0;
-+}
-+
-+static int iei_wt61p803_puzzle_set_cur_state(struct thermal_cooling_device *tcdev,
-+ unsigned long state)
-+{
-+ struct iei_wt61p803_puzzle_thermal_cooling_device *cdev = tcdev->devdata;
-+ u8 pwm_level;
-+
-+ if (!cdev)
-+ return -EINVAL;
-+
-+ if (state >= cdev->num_levels)
-+ return -EINVAL;
-+
-+ if (state == cdev->cur_level)
-+ return 0;
-+
-+ cdev->cur_level = state;
-+ pwm_level = cdev->cooling_levels[state];
-+
-+ return iei_wt61p803_puzzle_write_pwm_channel(cdev->mcu_hwmon, cdev->pwm_channel, pwm_level);
-+}
-+
-+static const struct thermal_cooling_device_ops iei_wt61p803_puzzle_cooling_ops = {
-+ .get_max_state = iei_wt61p803_puzzle_get_max_state,
-+ .get_cur_state = iei_wt61p803_puzzle_get_cur_state,
-+ .set_cur_state = iei_wt61p803_puzzle_set_cur_state,
-+};
-+
-+static int
-+iei_wt61p803_puzzle_enable_thermal_cooling_dev(struct device *dev,
-+ struct fwnode_handle *child,
-+ struct iei_wt61p803_puzzle_hwmon *mcu_hwmon)
-+{
-+ struct iei_wt61p803_puzzle_thermal_cooling_device *cdev;
-+ u32 pwm_channel;
-+ u8 num_levels;
-+ int i, ret;
-+
-+ ret = fwnode_property_read_u32(child, "reg", &pwm_channel);
-+ if (ret)
-+ return ret;
-+
-+ mcu_hwmon->thermal_cooling_dev_present[pwm_channel] = true;
-+
-+ num_levels = fwnode_property_count_u32(child, "cooling-levels");
-+ if (!num_levels)
-+ return -EINVAL;
-+
-+ cdev = devm_kzalloc(dev, sizeof(*cdev), GFP_KERNEL);
-+ if (!cdev)
-+ return -ENOMEM;
-+
-+ cdev->cooling_levels = devm_kmalloc_array(dev, num_levels, sizeof(u32), GFP_KERNEL);
-+ if (!cdev->cooling_levels)
-+ return -ENOMEM;
-+
-+ ret = fwnode_property_read_u32_array(child, "cooling-levels",
-+ cdev->cooling_levels,
-+ num_levels);
-+ if (ret) {
-+ dev_err(dev, "Couldn't read property 'cooling-levels'\n");
-+ return ret;
-+ }
-+
-+ for (i = 0; i < num_levels; i++) {
-+ if (cdev->cooling_levels[i] >
-+ IEI_WT61P803_PUZZLE_HWMON_MAX_PWM_VAL) {
-+ dev_err(dev, "iei_wt61p803_fan state[%d]:%d > %d\n", i,
-+ cdev->cooling_levels[i],
-+ IEI_WT61P803_PUZZLE_HWMON_MAX_PWM_VAL);
-+ return -EINVAL;
-+ }
-+ }
-+
-+ cdev->mcu_hwmon = mcu_hwmon;
-+ cdev->pwm_channel = pwm_channel;
-+ cdev->num_levels = num_levels;
-+ cdev->cur_level = -1;
-+ mcu_hwmon->cdev[pwm_channel] = cdev;
-+
-+ snprintf(cdev->name, THERMAL_NAME_LENGTH, "wt61p803_puzzle_%d", pwm_channel);
-+ cdev->tcdev = devm_thermal_of_cooling_device_register(dev, to_of_node(child), cdev->name,
-+ cdev, &iei_wt61p803_puzzle_cooling_ops);
-+ if (IS_ERR(cdev->tcdev))
-+ return PTR_ERR(cdev->tcdev);
-+
-+ return 0;
-+}
-+
-+static int iei_wt61p803_puzzle_hwmon_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct iei_wt61p803_puzzle *mcu = dev_get_drvdata(dev->parent);
-+ struct iei_wt61p803_puzzle_hwmon *mcu_hwmon;
-+ struct fwnode_handle *child;
-+ struct device *hwmon_dev;
-+ int ret;
-+
-+ mcu_hwmon = devm_kzalloc(dev, sizeof(*mcu_hwmon), GFP_KERNEL);
-+ if (!mcu_hwmon)
-+ return -ENOMEM;
-+
-+ mcu_hwmon->mcu = mcu;
-+ platform_set_drvdata(pdev, mcu_hwmon);
-+ mutex_init(&mcu_hwmon->lock);
-+
-+ hwmon_dev = devm_hwmon_device_register_with_info(dev, "iei_wt61p803_puzzle",
-+ mcu_hwmon,
-+ &iei_wt61p803_puzzle_chip_info,
-+ NULL);
-+ if (IS_ERR(hwmon_dev))
-+ return PTR_ERR(hwmon_dev);
-+
-+ /* Control fans via PWM lines via Linux Kernel */
-+ if (IS_ENABLED(CONFIG_THERMAL)) {
-+ device_for_each_child_node(dev, child) {
-+ ret = iei_wt61p803_puzzle_enable_thermal_cooling_dev(dev, child, mcu_hwmon);
-+ if (ret) {
-+ dev_err(dev, "Enabling the PWM fan failed\n");
-+ fwnode_handle_put(child);
-+ return ret;
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+static const struct of_device_id iei_wt61p803_puzzle_hwmon_id_table[] = {
-+ { .compatible = "iei,wt61p803-puzzle-hwmon" },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, iei_wt61p803_puzzle_hwmon_id_table);
-+
-+static struct platform_driver iei_wt61p803_puzzle_hwmon_driver = {
-+ .driver = {
-+ .name = "iei-wt61p803-puzzle-hwmon",
-+ .of_match_table = iei_wt61p803_puzzle_hwmon_id_table,
-+ },
-+ .probe = iei_wt61p803_puzzle_hwmon_probe,
-+};
-+
-+module_platform_driver(iei_wt61p803_puzzle_hwmon_driver);
-+
-+MODULE_DESCRIPTION("IEI WT61P803 PUZZLE MCU HWMON Driver");
-+MODULE_AUTHOR("Luka Kovacic <luka.kovacic@sartura.hr>");
-+MODULE_LICENSE("GPL v2");
+++ /dev/null
-From f3b44eb69cc561cf05d00506dcec0dd9be003ed8 Mon Sep 17 00:00:00 2001
-From: Luka Kovacic <luka.kovacic () sartura ! hr>
-Date: Tue, 24 Aug 2021 12:44:35 +0000
-Subject: [PATCH 4/7] drivers: leds: Add the IEI WT61P803 PUZZLE LED driver
-
-Add support for the IEI WT61P803 PUZZLE LED driver.
-Currently only the front panel power LED is supported,
-since it is the only LED on this board wired through the
-MCU.
-
-The LED is wired directly to the on-board MCU controller
-and is toggled using an MCU command.
-
-Support for more LEDs is going to be added in case more
-boards implement this microcontroller, as LEDs use many
-different GPIOs.
-
-This driver depends on the IEI WT61P803 PUZZLE MFD driver.
-
-Signed-off-by: Luka Kovacic <luka.kovacic@sartura.hr>
-Signed-off-by: Pavo Banicevic <pavo.banicevic@sartura.hr>
-Cc: Luka Perkov <luka.perkov@sartura.hr>
-Cc: Robert Marko <robert.marko@sartura.hr>
----
- drivers/leds/Kconfig | 8 ++
- drivers/leds/Makefile | 1 +
- drivers/leds/leds-iei-wt61p803-puzzle.c | 147 ++++++++++++++++++++++++
- 3 files changed, 156 insertions(+)
- create mode 100644 drivers/leds/leds-iei-wt61p803-puzzle.c
-
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -300,6 +300,14 @@ config LEDS_IPAQ_MICRO
- Choose this option if you want to use the notification LED on
- Compaq/HP iPAQ h3100 and h3600.
-
-+config LEDS_IEI_WT61P803_PUZZLE
-+ tristate "LED Support for the IEI WT61P803 PUZZLE MCU"
-+ depends on LEDS_CLASS
-+ depends on MFD_IEI_WT61P803_PUZZLE
-+ help
-+ This option enables support for LEDs controlled by the IEI WT61P803
-+ M801 MCU.
-+
- config LEDS_HP6XX
- tristate "LED Support for the HP Jornada 6xx"
- depends on LEDS_CLASS
---- a/drivers/leds/Makefile
-+++ b/drivers/leds/Makefile
-@@ -32,6 +32,7 @@ obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.
- obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o
- obj-$(CONFIG_LEDS_IP30) += leds-ip30.o
- obj-$(CONFIG_LEDS_IPAQ_MICRO) += leds-ipaq-micro.o
-+obj-$(CONFIG_LEDS_IEI_WT61P803_PUZZLE) += leds-iei-wt61p803-puzzle.o
- obj-$(CONFIG_LEDS_IS31FL319X) += leds-is31fl319x.o
- obj-$(CONFIG_LEDS_IS31FL32XX) += leds-is31fl32xx.o
- obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
---- /dev/null
-+++ b/drivers/leds/leds-iei-wt61p803-puzzle.c
-@@ -0,0 +1,147 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* IEI WT61P803 PUZZLE MCU LED Driver
-+ *
-+ * Copyright (C) 2020 Sartura Ltd.
-+ * Author: Luka Kovacic <luka.kovacic@sartura.hr>
-+ */
-+
-+#include <linux/leds.h>
-+#include <linux/mfd/iei-wt61p803-puzzle.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/property.h>
-+#include <linux/slab.h>
-+
-+enum iei_wt61p803_puzzle_led_state {
-+ IEI_LED_OFF = 0x30,
-+ IEI_LED_ON = 0x31,
-+ IEI_LED_BLINK_5HZ = 0x32,
-+ IEI_LED_BLINK_1HZ = 0x33,
-+};
-+
-+/**
-+ * struct iei_wt61p803_puzzle_led - MCU LED Driver
-+ * @cdev: LED classdev
-+ * @mcu: MCU struct pointer
-+ * @response_buffer Global MCU response buffer
-+ * @lock: General mutex lock to protect simultaneous R/W access to led_power_state
-+ * @led_power_state: State of the front panel power LED
-+ */
-+struct iei_wt61p803_puzzle_led {
-+ struct led_classdev cdev;
-+ struct iei_wt61p803_puzzle *mcu;
-+ unsigned char response_buffer[IEI_WT61P803_PUZZLE_BUF_SIZE];
-+ struct mutex lock; /* mutex to protect led_power_state */
-+ int led_power_state;
-+};
-+
-+static inline struct iei_wt61p803_puzzle_led *cdev_to_iei_wt61p803_puzzle_led
-+ (struct led_classdev *led_cdev)
-+{
-+ return container_of(led_cdev, struct iei_wt61p803_puzzle_led, cdev);
-+}
-+
-+static int iei_wt61p803_puzzle_led_brightness_set_blocking(struct led_classdev *cdev,
-+ enum led_brightness brightness)
-+{
-+ struct iei_wt61p803_puzzle_led *priv = cdev_to_iei_wt61p803_puzzle_led(cdev);
-+ unsigned char *resp_buf = priv->response_buffer;
-+ unsigned char led_power_cmd[5] = {};
-+ size_t reply_size;
-+ int ret;
-+
-+ led_power_cmd[0] = IEI_WT61P803_PUZZLE_CMD_HEADER_START;
-+ led_power_cmd[1] = IEI_WT61P803_PUZZLE_CMD_LED;
-+ led_power_cmd[2] = IEI_WT61P803_PUZZLE_CMD_LED_POWER;
-+ led_power_cmd[3] = brightness == LED_OFF ? IEI_LED_OFF : IEI_LED_ON;
-+
-+ ret = iei_wt61p803_puzzle_write_command(priv->mcu, led_power_cmd,
-+ sizeof(led_power_cmd),
-+ resp_buf,
-+ &reply_size);
-+ if (ret)
-+ return ret;
-+
-+ if (reply_size != 3)
-+ return -EIO;
-+
-+ if (!(resp_buf[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
-+ resp_buf[1] == IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK &&
-+ resp_buf[2] == IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK))
-+ return -EIO;
-+
-+ mutex_lock(&priv->lock);
-+ priv->led_power_state = brightness;
-+ mutex_unlock(&priv->lock);
-+
-+ return 0;
-+}
-+
-+static enum led_brightness iei_wt61p803_puzzle_led_brightness_get(struct led_classdev *cdev)
-+{
-+ struct iei_wt61p803_puzzle_led *priv = cdev_to_iei_wt61p803_puzzle_led(cdev);
-+ int led_state;
-+
-+ mutex_lock(&priv->lock);
-+ led_state = priv->led_power_state;
-+ mutex_unlock(&priv->lock);
-+
-+ return led_state;
-+}
-+
-+static int iei_wt61p803_puzzle_led_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct iei_wt61p803_puzzle *mcu = dev_get_drvdata(dev->parent);
-+ struct iei_wt61p803_puzzle_led *priv;
-+ struct led_init_data init_data = {};
-+ struct fwnode_handle *child;
-+ int ret;
-+
-+ if (device_get_child_node_count(dev) != 1)
-+ return -EINVAL;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->mcu = mcu;
-+ priv->led_power_state = 1;
-+ mutex_init(&priv->lock);
-+ dev_set_drvdata(dev, priv);
-+
-+ child = device_get_next_child_node(dev, NULL);
-+ init_data.fwnode = child;
-+
-+ priv->cdev.brightness_set_blocking = iei_wt61p803_puzzle_led_brightness_set_blocking;
-+ priv->cdev.brightness_get = iei_wt61p803_puzzle_led_brightness_get;
-+ priv->cdev.max_brightness = 1;
-+
-+ ret = devm_led_classdev_register_ext(dev, &priv->cdev, &init_data);
-+ if (ret)
-+ dev_err(dev, "Could not register LED\n");
-+
-+ fwnode_handle_put(child);
-+ return ret;
-+}
-+
-+static const struct of_device_id iei_wt61p803_puzzle_led_of_match[] = {
-+ { .compatible = "iei,wt61p803-puzzle-leds" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, iei_wt61p803_puzzle_led_of_match);
-+
-+static struct platform_driver iei_wt61p803_puzzle_led_driver = {
-+ .driver = {
-+ .name = "iei-wt61p803-puzzle-led",
-+ .of_match_table = iei_wt61p803_puzzle_led_of_match,
-+ },
-+ .probe = iei_wt61p803_puzzle_led_probe,
-+};
-+module_platform_driver(iei_wt61p803_puzzle_led_driver);
-+
-+MODULE_DESCRIPTION("IEI WT61P803 PUZZLE front panel LED driver");
-+MODULE_AUTHOR("Luka Kovacic <luka.kovacic@sartura.hr>");
-+MODULE_LICENSE("GPL v2");
-+MODULE_ALIAS("platform:leds-iei-wt61p803-puzzle");
+++ /dev/null
-From 2fab3b4956c5b2f83c1e1abffc1df39de2933d83 Mon Sep 17 00:00:00 2001
-From: Luka Kovacic <luka.kovacic () sartura ! hr>
-Date: Tue, 24 Aug 2021 12:44:36 +0000
-Subject: [PATCH 5/7] Documentation/ABI: Add iei-wt61p803-puzzle driver sysfs
- interface documentation
-
-Add the iei-wt61p803-puzzle driver sysfs interface documentation to allow
-monitoring and control of the microcontroller from user space.
-
-Signed-off-by: Luka Kovacic <luka.kovacic@sartura.hr>
-Signed-off-by: Pavo Banicevic <pavo.banicevic@sartura.hr>
-Cc: Luka Perkov <luka.perkov@sartura.hr>
-Cc: Robert Marko <robert.marko@sartura.hr>
----
- .../testing/sysfs-driver-iei-wt61p803-puzzle | 61 +++++++++++++++++++
- 1 file changed, 61 insertions(+)
- create mode 100644 Documentation/ABI/testing/sysfs-driver-iei-wt61p803-puzzle
-
---- /dev/null
-+++ b/Documentation/ABI/testing/sysfs-driver-iei-wt61p803-puzzle
-@@ -0,0 +1,61 @@
-+What: /sys/bus/serial/devices/.../mac_address_*
-+Date: September 2020
-+Contact: Luka Kovacic <luka.kovacic@sartura.hr>
-+Description: (RW) Internal factory assigned MAC address values
-+
-+What: /sys/bus/serial/devices/.../serial_number
-+Date: September 2020
-+Contact: Luka Kovacic <luka.kovacic@sartura.hr>
-+Description: (RW) Internal factory assigned serial number
-+
-+What: /sys/bus/serial/devices/.../version
-+Date: September 2020
-+Contact: Luka Kovacic <luka.kovacic@sartura.hr>
-+Description: (RO) Internal MCU firmware version
-+
-+What: /sys/bus/serial/devices/.../protocol_version
-+Date: September 2020
-+Contact: Luka Kovacic <luka.kovacic@sartura.hr>
-+Description: (RO) Internal MCU communication protocol version
-+
-+What: /sys/bus/serial/devices/.../power_loss_recovery
-+Date: September 2020
-+Contact: Luka Kovacic <luka.kovacic@sartura.hr>
-+Description: (RW) Host platform power loss recovery settings
-+ Value mapping: 0 - Always-On, 1 - Always-Off, 2 - Always-AC, 3 - Always-WA
-+
-+What: /sys/bus/serial/devices/.../bootloader_mode
-+Date: September 2020
-+Contact: Luka Kovacic <luka.kovacic@sartura.hr>
-+Description: (RO) Internal MCU bootloader mode status
-+ Value mapping:
-+ 0 - normal mode
-+ 1 - bootloader mode
-+
-+What: /sys/bus/serial/devices/.../power_status
-+Date: September 2020
-+Contact: Luka Kovacic <luka.kovacic@sartura.hr>
-+Description: (RO) Power status indicates the host platform power on method.
-+ Value mapping (bitwise list):
-+ 0x80 - Null
-+ 0x40 - Firmware flag
-+ 0x20 - Power loss detection flag (powered off)
-+ 0x10 - Power loss detection flag (AC mode)
-+ 0x08 - Button power on
-+ 0x04 - Wake-on-LAN power on
-+ 0x02 - RTC alarm power on
-+ 0x01 - AC recover power on
-+
-+What: /sys/bus/serial/devices/.../build_info
-+Date: September 2020
-+Contact: Luka Kovacic <luka.kovacic@sartura.hr>
-+Description: (RO) Internal MCU firmware build date
-+ Format: yyyy/mm/dd hh:mm
-+
-+What: /sys/bus/serial/devices/.../ac_recovery_status
-+Date: September 2020
-+Contact: Luka Kovacic <luka.kovacic@sartura.hr>
-+Description: (RO) Host platform AC recovery status value
-+ Value mapping:
-+ 0 - board has not been recovered from power down
-+ 1 - board has been recovered from power down
+++ /dev/null
-From 0aff3e5923fecc6842473ad07a688d6e2f2c2d55 Mon Sep 17 00:00:00 2001
-From: Luka Kovacic <luka.kovacic () sartura ! hr>
-Date: Tue, 24 Aug 2021 12:44:37 +0000
-Subject: [PATCH 6/7] Documentation/hwmon: Add iei-wt61p803-puzzle hwmon driver
- documentation
-
-Add the iei-wt61p803-puzzle driver hwmon driver interface documentation.
-
-Signed-off-by: Luka Kovacic <luka.kovacic@sartura.hr>
-Signed-off-by: Pavo Banicevic <pavo.banicevic@sartura.hr>
-Cc: Luka Perkov <luka.perkov@sartura.hr>
-Cc: Robert Marko <robert.marko@sartura.hr>
----
- .../hwmon/iei-wt61p803-puzzle-hwmon.rst | 43 +++++++++++++++++++
- Documentation/hwmon/index.rst | 1 +
- 2 files changed, 44 insertions(+)
- create mode 100644 Documentation/hwmon/iei-wt61p803-puzzle-hwmon.rst
-
---- /dev/null
-+++ b/Documentation/hwmon/iei-wt61p803-puzzle-hwmon.rst
-@@ -0,0 +1,43 @@
-+.. SPDX-License-Identifier: GPL-2.0-only
-+
-+Kernel driver iei-wt61p803-puzzle-hwmon
-+=======================================
-+
-+Supported chips:
-+ * IEI WT61P803 PUZZLE for IEI Puzzle M801
-+
-+ Prefix: 'iei-wt61p803-puzzle-hwmon'
-+
-+Author: Luka Kovacic <luka.kovacic@sartura.hr>
-+
-+
-+Description
-+-----------
-+
-+This driver adds fan and temperature sensor reading for some IEI Puzzle
-+series boards.
-+
-+Sysfs attributes
-+----------------
-+
-+The following attributes are supported:
-+
-+- IEI WT61P803 PUZZLE for IEI Puzzle M801
-+
-+/sys files in hwmon subsystem
-+-----------------------------
-+
-+================= == =====================================================
-+fan[1-5]_input RO files for fan speed (in RPM)
-+pwm[1-2] RW files for fan[1-2] target duty cycle (0..255)
-+temp[1-2]_input RO files for temperature sensors, in millidegree Celsius
-+================= == =====================================================
-+
-+/sys files in thermal subsystem
-+-------------------------------
-+
-+================= == =====================================================
-+cur_state RW file for current cooling state of the cooling device
-+ (0..max_state)
-+max_state RO file for maximum cooling state of the cooling device
-+================= == =====================================================
---- a/Documentation/hwmon/index.rst
-+++ b/Documentation/hwmon/index.rst
-@@ -77,6 +77,7 @@ Hardware Monitoring Kernel Drivers
- ibmaem
- ibm-cffps
- ibmpowernv
-+ iei-wt61p803-puzzle-hwmon
- ina209
- ina2xx
- ina238
+++ /dev/null
-From 12479baad28d2a08c6cb9e83471057635fa1635c Mon Sep 17 00:00:00 2001
-From: Luka Kovacic <luka.kovacic () sartura ! hr>
-Date: Tue, 24 Aug 2021 12:44:38 +0000
-Subject: [PATCH 7/7] MAINTAINERS: Add an entry for the IEI WT61P803 PUZZLE
- driver
-
-Add an entry for the IEI WT61P803 PUZZLE driver (MFD, HWMON, LED drivers).
-
-Signed-off-by: Luka Kovacic <luka.kovacic@sartura.hr>
-Signed-off-by: Pavo Banicevic <pavo.banicevic@sartura.hr>
-Cc: Luka Perkov <luka.perkov@sartura.hr>
-Cc: Robert Marko <robert.marko@sartura.hr>
----
- MAINTAINERS | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -9900,6 +9900,22 @@ F: include/net/nl802154.h
- F: net/ieee802154/
- F: net/mac802154/
-
-+IEI WT61P803 M801 MFD DRIVER
-+M: Luka Kovacic <luka.kovacic@sartura.hr>
-+M: Luka Perkov <luka.perkov@sartura.hr>
-+M: Goran Medic <goran.medic@sartura.hr>
-+L: linux-kernel@vger.kernel.org
-+S: Maintained
-+F: Documentation/ABI/stable/sysfs-driver-iei-wt61p803-puzzle
-+F: Documentation/devicetree/bindings/hwmon/iei,wt61p803-puzzle-hwmon.yaml
-+F: Documentation/devicetree/bindings/leds/iei,wt61p803-puzzle-leds.yaml
-+F: Documentation/devicetree/bindings/mfd/iei,wt61p803-puzzle.yaml
-+F: Documentation/hwmon/iei-wt61p803-puzzle-hwmon.rst
-+F: drivers/hwmon/iei-wt61p803-puzzle-hwmon.c
-+F: drivers/leds/leds-iei-wt61p803-puzzle.c
-+F: drivers/mfd/iei-wt61p803-puzzle.c
-+F: include/linux/mfd/iei-wt61p803-puzzle.h
-+
- IFE PROTOCOL
- M: Yotam Gigi <yotam.gi@gmail.com>
- M: Jamal Hadi Salim <jhs@mojatatu.com>
+++ /dev/null
---- a/drivers/leds/leds-iei-wt61p803-puzzle.c
-+++ b/drivers/leds/leds-iei-wt61p803-puzzle.c
-@@ -9,9 +9,13 @@
- #include <linux/mfd/iei-wt61p803-puzzle.h>
- #include <linux/mod_devicetable.h>
- #include <linux/module.h>
-+#include <linux/of.h>
- #include <linux/platform_device.h>
- #include <linux/property.h>
- #include <linux/slab.h>
-+#include <linux/workqueue.h>
-+
-+#define IEI_LEDS_MAX 4
-
- enum iei_wt61p803_puzzle_led_state {
- IEI_LED_OFF = 0x30,
-@@ -33,7 +37,11 @@ struct iei_wt61p803_puzzle_led {
- struct iei_wt61p803_puzzle *mcu;
- unsigned char response_buffer[IEI_WT61P803_PUZZLE_BUF_SIZE];
- struct mutex lock; /* mutex to protect led_power_state */
-+ struct work_struct work;
- int led_power_state;
-+ int id;
-+ u8 blinking;
-+ bool active_low;
- };
-
- static inline struct iei_wt61p803_puzzle_led *cdev_to_iei_wt61p803_puzzle_led
-@@ -51,10 +59,18 @@ static int iei_wt61p803_puzzle_led_brigh
- size_t reply_size;
- int ret;
-
-+ if (priv->blinking) {
-+ if (brightness == LED_OFF)
-+ priv->blinking = 0;
-+ else
-+ return 0;
-+ }
-+
- led_power_cmd[0] = IEI_WT61P803_PUZZLE_CMD_HEADER_START;
- led_power_cmd[1] = IEI_WT61P803_PUZZLE_CMD_LED;
-- led_power_cmd[2] = IEI_WT61P803_PUZZLE_CMD_LED_POWER;
-- led_power_cmd[3] = brightness == LED_OFF ? IEI_LED_OFF : IEI_LED_ON;
-+ led_power_cmd[2] = IEI_WT61P803_PUZZLE_CMD_LED_SET(priv->id);
-+ led_power_cmd[3] = ((brightness == LED_OFF) ^ priv->active_low) ?
-+ IEI_LED_OFF : priv->blinking?priv->blinking:IEI_LED_ON;
-
- ret = iei_wt61p803_puzzle_write_command(priv->mcu, led_power_cmd,
- sizeof(led_power_cmd),
-@@ -90,39 +106,166 @@ static enum led_brightness iei_wt61p803_
- return led_state;
- }
-
-+static void iei_wt61p803_puzzle_led_apply_blink(struct work_struct *work)
-+{
-+ struct iei_wt61p803_puzzle_led *priv = container_of(work, struct iei_wt61p803_puzzle_led, work);
-+ unsigned char led_blink_cmd[5] = {};
-+ unsigned char resp_buf[IEI_WT61P803_PUZZLE_BUF_SIZE];
-+ size_t reply_size;
-+
-+ led_blink_cmd[0] = IEI_WT61P803_PUZZLE_CMD_HEADER_START;
-+ led_blink_cmd[1] = IEI_WT61P803_PUZZLE_CMD_LED;
-+ led_blink_cmd[2] = IEI_WT61P803_PUZZLE_CMD_LED_SET(priv->id);
-+ led_blink_cmd[3] = priv->blinking;
-+
-+ iei_wt61p803_puzzle_write_command(priv->mcu, led_blink_cmd,
-+ sizeof(led_blink_cmd),
-+ resp_buf,
-+ &reply_size);
-+
-+ return;
-+}
-+
-+static int iei_wt61p803_puzzle_led_set_blink(struct led_classdev *cdev,
-+ unsigned long *delay_on,
-+ unsigned long *delay_off)
-+{
-+ struct iei_wt61p803_puzzle_led *priv = cdev_to_iei_wt61p803_puzzle_led(cdev);
-+ u8 blink_mode = 0;
-+ int ret = 0;
-+
-+ /* set defaults */
-+ if (!*delay_on && !*delay_off) {
-+ *delay_on = 500;
-+ *delay_off = 500;
-+ }
-+
-+ /* minimum delay for soft-driven blinking is 100ms to keep load low */
-+ if (*delay_on < 100)
-+ *delay_on = 100;
-+
-+ if (*delay_off < 100)
-+ *delay_off = 100;
-+
-+ /* offload blinking to hardware, if possible */
-+ if (*delay_on != *delay_off) {
-+ ret = -EINVAL;
-+ } else if (*delay_on == 100) {
-+ blink_mode = IEI_LED_BLINK_5HZ;
-+ *delay_on = 100;
-+ *delay_off = 100;
-+ } else if (*delay_on <= 500) {
-+ blink_mode = IEI_LED_BLINK_1HZ;
-+ *delay_on = 500;
-+ *delay_off = 500;
-+ } else {
-+ ret = -EINVAL;
-+ }
-+
-+ mutex_lock(&priv->lock);
-+ priv->blinking = blink_mode;
-+ mutex_unlock(&priv->lock);
-+
-+ if (blink_mode)
-+ schedule_work(&priv->work);
-+
-+ return ret;
-+}
-+
-+
-+static int iei_wt61p803_puzzle_led_set_dt_default(struct led_classdev *cdev,
-+ struct device_node *np)
-+{
-+ const char *state;
-+ int ret = 0;
-+
-+ state = of_get_property(np, "default-state", NULL);
-+ if (state) {
-+ if (!strcmp(state, "on")) {
-+ ret =
-+ iei_wt61p803_puzzle_led_brightness_set_blocking(
-+ cdev, cdev->max_brightness);
-+ } else {
-+ ret = iei_wt61p803_puzzle_led_brightness_set_blocking(
-+ cdev, LED_OFF);
-+ }
-+ }
-+
-+ return ret;
-+}
-+
- static int iei_wt61p803_puzzle_led_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-+ struct device_node *np = dev_of_node(dev);
-+ struct device_node *child;
- struct iei_wt61p803_puzzle *mcu = dev_get_drvdata(dev->parent);
- struct iei_wt61p803_puzzle_led *priv;
-- struct led_init_data init_data = {};
-- struct fwnode_handle *child;
- int ret;
-+ u32 reg;
-
-- if (device_get_child_node_count(dev) != 1)
-+ if (device_get_child_node_count(dev) > IEI_LEDS_MAX)
- return -EINVAL;
-
-- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-- if (!priv)
-- return -ENOMEM;
--
-- priv->mcu = mcu;
-- priv->led_power_state = 1;
-- mutex_init(&priv->lock);
-- dev_set_drvdata(dev, priv);
--
-- child = device_get_next_child_node(dev, NULL);
-- init_data.fwnode = child;
--
-- priv->cdev.brightness_set_blocking = iei_wt61p803_puzzle_led_brightness_set_blocking;
-- priv->cdev.brightness_get = iei_wt61p803_puzzle_led_brightness_get;
-- priv->cdev.max_brightness = 1;
-+ for_each_available_child_of_node(np, child) {
-+ struct led_init_data init_data = {};
-
-- ret = devm_led_classdev_register_ext(dev, &priv->cdev, &init_data);
-- if (ret)
-- dev_err(dev, "Could not register LED\n");
-+ ret = of_property_read_u32(child, "reg", ®);
-+ if (ret) {
-+ dev_err(dev, "Failed to read led 'reg' property\n");
-+ goto put_child_node;
-+ }
-+
-+ if (reg > IEI_LEDS_MAX) {
-+ dev_err(dev, "Invalid led reg %u\n", reg);
-+ ret = -EINVAL;
-+ goto put_child_node;
-+ }
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv) {
-+ ret = -ENOMEM;
-+ goto put_child_node;
-+ }
-+
-+ mutex_init(&priv->lock);
-+
-+ dev_set_drvdata(dev, priv);
-+
-+ if (of_property_read_bool(child, "active-low"))
-+ priv->active_low = true;
-+
-+ priv->mcu = mcu;
-+ priv->id = reg;
-+ priv->led_power_state = 1;
-+ priv->blinking = 0;
-+ init_data.fwnode = of_fwnode_handle(child);
-+
-+ priv->cdev.brightness_set_blocking = iei_wt61p803_puzzle_led_brightness_set_blocking;
-+ priv->cdev.brightness_get = iei_wt61p803_puzzle_led_brightness_get;
-+ priv->cdev.blink_set = iei_wt61p803_puzzle_led_set_blink;
-+
-+ priv->cdev.max_brightness = 1;
-+
-+ INIT_WORK(&priv->work, iei_wt61p803_puzzle_led_apply_blink);
-+
-+ ret = iei_wt61p803_puzzle_led_set_dt_default(&priv->cdev, child);
-+ if (ret) {
-+ dev_err(dev, "Could apply default from DT\n");
-+ goto put_child_node;
-+ }
-+
-+ ret = devm_led_classdev_register_ext(dev, &priv->cdev, &init_data);
-+ if (ret) {
-+ dev_err(dev, "Could not register LED\n");
-+ goto put_child_node;
-+ }
-+ }
-+
-+ return ret;
-
-- fwnode_handle_put(child);
-+put_child_node:
-+ of_node_put(child);
- return ret;
- }
-
---- a/include/linux/mfd/iei-wt61p803-puzzle.h
-+++ b/include/linux/mfd/iei-wt61p803-puzzle.h
-@@ -36,7 +36,7 @@
- #define IEI_WT61P803_PUZZLE_CMD_FUNCTION_OTHER_POWER_LOSS 0x41 /* A */
-
- #define IEI_WT61P803_PUZZLE_CMD_LED 0x52 /* R */
--#define IEI_WT61P803_PUZZLE_CMD_LED_POWER 0x31 /* 1 */
-+#define IEI_WT61P803_PUZZLE_CMD_LED_SET(n) (0x30 | (n))
-
- #define IEI_WT61P803_PUZZLE_CMD_TEMP 0x54 /* T */
- #define IEI_WT61P803_PUZZLE_CMD_TEMP_ALL 0x41 /* A */
---- a/drivers/mfd/iei-wt61p803-puzzle.c
-+++ b/drivers/mfd/iei-wt61p803-puzzle.c
-@@ -176,6 +176,9 @@ static int iei_wt61p803_puzzle_recv_buf(
- struct iei_wt61p803_puzzle *mcu = serdev_device_get_drvdata(serdev);
- int ret;
-
-+ print_hex_dump_debug("puzzle-mcu rx: ", DUMP_PREFIX_NONE,
-+ 16, 1, data, size, false);
-+
- ret = iei_wt61p803_puzzle_process_resp(mcu, data, size);
- /* Return the number of processed bytes if function returns error,
- * discard the remaining incoming data, since the frame this data
-@@ -246,6 +249,9 @@ int iei_wt61p803_puzzle_write_command(st
-
- cmd[size - 1] = iei_wt61p803_puzzle_checksum(cmd, size - 1);
-
-+ print_hex_dump_debug("puzzle-mcu tx: ", DUMP_PREFIX_NONE,
-+ 16, 1, cmd, size, false);
-+
- /* Initialize reply struct */
- reinit_completion(&mcu->reply->received);
- mcu->reply->size = 0;
+++ /dev/null
---- a/drivers/mfd/iei-wt61p803-puzzle.c
-+++ b/drivers/mfd/iei-wt61p803-puzzle.c
-@@ -241,6 +241,7 @@ int iei_wt61p803_puzzle_write_command(st
- {
- struct device *dev = &mcu->serdev->dev;
- int ret;
-+ int retries;
-
- if (size <= 1 || size > IEI_WT61P803_PUZZLE_MAX_COMMAND_LENGTH)
- return -EINVAL;
-@@ -252,24 +253,36 @@ int iei_wt61p803_puzzle_write_command(st
- print_hex_dump_debug("puzzle-mcu tx: ", DUMP_PREFIX_NONE,
- 16, 1, cmd, size, false);
-
-+ retries = 3;
- /* Initialize reply struct */
-- reinit_completion(&mcu->reply->received);
-- mcu->reply->size = 0;
-- usleep_range(2000, 10000);
-- serdev_device_write_flush(mcu->serdev);
-- ret = serdev_device_write_buf(mcu->serdev, cmd, size);
-- if (ret < 0)
-- goto exit;
--
-- serdev_device_wait_until_sent(mcu->serdev, IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
-- ret = wait_for_completion_timeout(&mcu->reply->received,
-- IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
-- if (ret == 0) {
-- dev_err(dev, "Command reply receive timeout\n");
-- ret = -ETIMEDOUT;
-- goto exit;
-+ while (retries) {
-+ reinit_completion(&mcu->reply->received);
-+ mcu->reply->size = 0;
-+ usleep_range(2000, 10000);
-+ serdev_device_write_flush(mcu->serdev);
-+ ret = serdev_device_write_buf(mcu->serdev, cmd, size);
-+ if (ret < 0)
-+ goto exit;
-+
-+ serdev_device_wait_until_sent(mcu->serdev, IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
-+ ret = wait_for_completion_timeout(&mcu->reply->received,
-+ IEI_WT61P803_PUZZLE_GENERAL_TIMEOUT);
-+ retries--;
-+ if (ret == 0) {
-+ if (retries == 0) {
-+ dev_err(dev, "Command reply receive timeout\n");
-+ ret = -ETIMEDOUT;
-+ goto exit;
-+ }
-+ }
-+ else {
-+ if (mcu->reply->data[0] == IEI_WT61P803_PUZZLE_CMD_HEADER_START &&
-+ mcu->reply->data[1] == IEI_WT61P803_PUZZLE_CMD_RESPONSE_OK &&
-+ mcu->reply->data[2] == IEI_WT61P803_PUZZLE_CHECKSUM_RESPONSE_OK) {
-+ break;
-+ }
-+ }
- }
--
- *reply_size = mcu->reply->size;
- /* Copy the received data, as it will not be available after a new frame is received */
- memcpy(reply_data, mcu->reply->data, mcu->reply->size);
};
partition@480000 {
+ compatible = "u-boot,env";
label = "0:appsblenv";
reg = <0x480000 0x10000>;
};
START=99
-. /lib/functions.sh
-
boot() {
case $(board_name) in
- yuncore,fap650)
- fw_setenv owrt_bootcount 0
- ;;
- esac
+ yuncore,fap650)
+ fw_setenv owrt_bootcount 0
+ ;;
+ esac
}
SUBTARGETS:=mt7620 mt7621 mt76x8 rt288x rt305x rt3883
FEATURES:=squashfs gpio
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Ralink RT288x/RT3xxx based boards.
leds {
compatible = "gpio-leds";
- lan {
+ led-0 {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
};
- usb {
+ led-1 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
linux,default-trigger = "usbport";
};
- led_wps: wps {
+ led_wps: led-2 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
- wan {
+ led-3 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
};
- wlan {
+ led-4 {
function = LED_FUNCTION_WLAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
leds {
compatible = "gpio-leds";
- lan {
+ led-0 {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
};
- led_power: power {
+ led_power: led-1 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
default-state = "keep";
};
- usb {
+ led-2 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
linux,default-trigger = "usbport";
};
- wan {
+ led-3 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
};
- wan_orange {
+ led-4 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_ORANGE>;
gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
};
- wlan5g {
- label = "blue:wlan5g";
+ led-5 {
+ function = LED_FUNCTION_WLAN_5GHZ;
+ color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
linux,default-trigger = "phy0tpt";
};
- wlan2g {
- label = "blue:wlan2g";
+ led-6 {
+ function = LED_FUNCTION_WLAN_2GHZ;
+ color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
linux,default-trigger = "phy1tpt";
};
- wps {
+ led-7 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
leds {
compatible = "gpio-leds";
- lan {
+ led-0 {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
};
- usb {
+ led-1 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
linux,default-trigger = "usbport";
};
- led_wps: wps {
+ led_wps: led-2 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};
- wan {
+ led-3 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
};
- wlan {
+ led-4 {
function = LED_FUNCTION_WLAN;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
leds {
compatible = "gpio-leds";
- lan {
+ led-0 {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
};
- led_power: power {
+ led_power: led-1 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- usb {
+ led-2 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
linux,default-trigger = "usbport";
};
- wan {
+ led-3 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
};
- wan_orange {
+ led-4 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_ORANGE>;
gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
};
- wlan5g {
- label = "green:wlan5g";
+ led-5 {
+ function = LED_FUNCTION_WLAN_5GHZ;
+ color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
linux,default-trigger = "phy0tpt";
};
- wlan2g {
- label = "green:wlan2g";
+ led-6 {
+ function = LED_FUNCTION_WLAN_2GHZ;
+ color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
linux,default-trigger = "phy1tpt";
};
- wps {
+ led-7 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
--- /dev/null
+// 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 {
+ label = "params";
+ reg = <0x50000 0x10000>;
+ read-only;
+ };
+
+ partition@60000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x60000 0x7a0000>;
+ };
+ };
+ };
+};
+
+ðernet {
+ 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";
+ };
+};
#interrupt-cells = <1>;
interrupts = <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>;
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ interrupts = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ interrupts = <1>;
+ };
+
+ ethphy2: ethernet-phy@2 {
+ reg = <2>;
+ interrupts = <2>;
+ };
+
+ ethphy3: ethernet-phy@3 {
+ reg = <3>;
+ interrupts = <3>;
+ };
+
+ ethphy4: ethernet-phy@4 {
+ reg = <4>;
+ interrupts = <4>;
+ };
+ };
+
ports {
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
reg = <0>;
label = "lan0";
+ phy-handle = <ðphy0>;
};
port@1 {
status = "disabled";
reg = <1>;
label = "lan1";
+ phy-handle = <ðphy1>;
};
port@2 {
status = "disabled";
reg = <2>;
label = "lan2";
+ phy-handle = <ðphy2>;
};
port@3 {
status = "disabled";
reg = <3>;
label = "lan3";
+ phy-handle = <ðphy3>;
};
port@4 {
status = "disabled";
reg = <4>;
label = "lan4";
+ phy-handle = <ðphy4>;
};
port@6 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&pcie {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
status = "okay";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&gmac0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&pcie {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include <dt-bindings/leds/common.h>
-
-#include "mt7621_dlink_dir-xx60-a1.dtsi"
+#include "mt7621_dlink_dir_nand_128m.dtsi"
/ {
compatible = "dlink,dir-1960-a1", "mediatek,mt7621-soc";
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir_nand_128m.dtsi"
+
+/ {
+ compatible = "dlink,dir-2150-a1", "mediatek,mt7621-soc";
+ model = "D-Link DIR-2150 A1";
+};
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include "mt7621_dlink_dir-xx60-a1.dtsi"
+#include "mt7621_dlink_dir_nand_128m.dtsi"
/ {
compatible = "dlink,dir-2640-a1", "mediatek,mt7621-soc";
};
&leds {
- usb2_white {
- label = "white:usb2";
+ led-4 {
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_WHITE>;
+ function-enumerator = <2>;
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
trigger-sources = <&ehci_port2>;
linux,default-trigger = "usbport";
};
- usb3_white {
- label = "white:usb3";
+ led-5 {
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_WHITE>;
+ function-enumerator = <3>;
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
trigger-sources = <&xhci_ehci_port1>;
linux,default-trigger = "usbport";
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include "mt7621_dlink_dir-xx60-a1.dtsi"
+#include "mt7621_dlink_dir_nand_128m.dtsi"
/ {
compatible = "dlink,dir-2660-a1", "mediatek,mt7621-soc";
};
&leds {
- usb2_white {
- label = "white:usb2";
+ led-4 {
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_WHITE>;
+ function-enumerator = <2>;
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
trigger-sources = <&ehci_port2>;
linux,default-trigger = "usbport";
};
- usb3_white {
- label = "white:usb3";
+ led-5 {
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_WHITE>;
+ function-enumerator = <3>;
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
trigger-sources = <&xhci_ehci_port1>;
linux,default-trigger = "usbport";
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include "mt7621_dlink_dir-xx60-a1.dtsi"
+#include "mt7621_dlink_dir_nand_128m.dtsi"
/ {
compatible = "dlink,dir-3040-a1", "mediatek,mt7621-soc";
};
&leds {
- usb2_white {
+ led-4 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_WHITE>;
- function-enumerator = <0>;
+ function-enumerator = <2>;
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
trigger-sources = <&ehci_port2>;
linux,default-trigger = "usbport";
};
- usb3_white {
+ led-5 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_WHITE>;
- function-enumerator = <1>;
+ function-enumerator = <3>;
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
trigger-sources = <&xhci_ehci_port1>;
linux,default-trigger = "usbport";
};
- wlan2g {
+ led-6 {
function = LED_FUNCTION_WLAN_2GHZ;
color = <LED_COLOR_ID_WHITE>;
gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "phy0radio";
};
- wlan5glb {
+ led-7 {
function = LED_FUNCTION_WLAN_5GHZ;
color = <LED_COLOR_ID_WHITE>;
function-enumerator = <0>;
linux,default-trigger = "phy1radio";
};
- wlan5ghb {
+ led-8 {
function = LED_FUNCTION_WLAN_5GHZ;
color = <LED_COLOR_ID_WHITE>;
function-enumerator = <1>;
leds {
compatible = "gpio-leds";
- led_power_orange: power_orange {
+ led_power_orange: led-0 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_ORANGE>;
gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
};
- led_power_white: power_white {
+ led_power_white: led-1 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_WHITE>;
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
};
- led_net_orange: net_orange {
- label = "orange:net";
+ led_net_orange: led-2 {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_ORANGE>;
gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
};
- net_white {
- label = "white:net";
+ led-3 {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_WHITE>;
gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
};
- usb2_white {
- label = "white:usb2";
+ led-4 {
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_WHITE>;
+ function-enumerator = <2>;
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
trigger-sources = <&ehci_port2>;
linux,default-trigger = "usbport";
};
- usb3_white {
- label = "white:usb3";
+ led-5 {
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_WHITE>;
+ function-enumerator = <3>;
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
trigger-sources = <&xhci_ehci_port1>;
linux,default-trigger = "usbport";
};
- wlan2g {
- label = "white:wlan2g";
+ led-6 {
+ function = LED_FUNCTION_WLAN_2GHZ;
+ color = <LED_COLOR_ID_WHITE>;
gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "phy0radio";
};
- wlan5glb {
- label = "white:wlan5glb";
+ led-7 {
+ function = LED_FUNCTION_WLAN_5GHZ;
+ color = <LED_COLOR_ID_WHITE>;
+ function-enumerator = <0>;
gpios = <&gpio 9 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "phy1radio";
};
- wlan5ghb {
- label = "white:wlan5ghb";
+ led-8 {
+ function = LED_FUNCTION_WLAN_5GHZ;
+ color = <LED_COLOR_ID_WHITE>;
+ function-enumerator = <1>;
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "phy2radio";
};
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
+++ /dev/null
-// 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 {
- label-mac-device = &gmac0;
- 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: wps {
- label = "wps";
- gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_WPS_BUTTON>;
- };
- };
-
- leds: leds {
- compatible = "gpio-leds";
-
- led_power_orange: power_orange {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_ORANGE>;
- gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
- };
-
- led_power_white: power_white {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_WHITE>;
- gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
- };
-
- led_net_orange: net_orange {
- label = "orange:net";
- gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
- };
-
- net_white {
- label = "white:net";
- 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 0x4da8>;
- };
-
- eeprom_factory_8000: eeprom@8000 {
- reg = <0x8000 0x4da8>;
- };
-
- macaddr_factory_e000: macaddr@e000 {
- compatible = "mac-base";
- reg = <0xe000 0x6>;
- #nvmem-cell-cells = <1>;
- };
- };
- };
-
- partition@140000 {
- label = "config2";
- reg = <0x140000 0x40000>;
- read-only;
- };
-
- partition@180000 {
- label = "firmware";
- compatible = "openwrt,uimage", "denx,uimage";
- openwrt,padding = <96>;
- reg = <0x180000 0x2800000>;
- };
-
- partition@2980000 {
- label = "private";
- reg = <0x2980000 0x2000000>;
- read-only;
- };
-
- partition@4980000 {
- label = "firmware2";
- reg = <0x4980000 0x2800000>;
- };
-
- partition@7180000 {
- label = "mydlink";
- reg = <0x7180000 0x600000>;
- read-only;
- };
-
- partition@7780000 {
- label = "reserved";
- reg = <0x7780000 0x880000>;
- read-only;
- };
- };
-};
-
-&pcie {
- status = "okay";
-};
-
-&pcie0 {
- wifi0: wifi@0,0 {
- compatible = "mediatek,mt76";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_0>, <&macaddr_factory_e000 1>;
- nvmem-cell-names = "eeprom", "mac-address";
- ieee80211-freq-limit = <2400000 2500000>;
-
- led {
- led-active-low;
- };
- };
-};
-
-&pcie1 {
- wifi1: wifi@0,0 {
- compatible = "mediatek,mt76";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_8000>, <&macaddr_factory_e000 2>;
- nvmem-cell-names = "eeprom", "mac-address";
- ieee80211-freq-limit = <5000000 6000000>;
-
- led {
- led-active-low;
- };
- };
-};
-
-&gmac0 {
- nvmem-cells = <&macaddr_factory_e000 0>;
- nvmem-cell-names = "mac-address";
-};
-
-&gmac1 {
- status = "okay";
- label = "wan";
- phy-handle = <ðphy4>;
-
- nvmem-cells = <&macaddr_factory_e000 3>;
- nvmem-cell-names = "mac-address";
-};
-
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
-};
-
-&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";
- };
-};
--- /dev/null
+// 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 {
+ label-mac-device = &gmac0;
+ 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: wps {
+ label = "wps";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+ };
+
+ leds: 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 0x4da8>;
+ };
+
+ eeprom_factory_8000: eeprom@8000 {
+ reg = <0x8000 0x4da8>;
+ };
+
+ macaddr_factory_e000: macaddr@e000 {
+ compatible = "mac-base";
+ reg = <0xe000 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@140000 {
+ label = "config2";
+ reg = <0x140000 0x40000>;
+ read-only;
+ };
+
+ partition@180000 {
+ label = "firmware";
+ compatible = "openwrt,uimage", "denx,uimage";
+ openwrt,padding = <96>;
+ reg = <0x180000 0x2800000>;
+ };
+
+ partition@2980000 {
+ label = "private";
+ reg = <0x2980000 0x2000000>;
+ read-only;
+ };
+
+ partition@4980000 {
+ label = "firmware2";
+ reg = <0x4980000 0x2800000>;
+ };
+
+ partition@7180000 {
+ label = "mydlink";
+ reg = <0x7180000 0x600000>;
+ read-only;
+ };
+
+ partition@7780000 {
+ label = "reserved";
+ reg = <0x7780000 0x880000>;
+ read-only;
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie0 {
+ wifi0: wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>, <&macaddr_factory_e000 1>;
+ nvmem-cell-names = "eeprom", "mac-address";
+ ieee80211-freq-limit = <2400000 2500000>;
+
+ led {
+ led-active-low;
+ };
+ };
+};
+
+&pcie1 {
+ wifi1: wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_8000>, <&macaddr_factory_e000 2>;
+ nvmem-cell-names = "eeprom", "mac-address";
+ ieee80211-freq-limit = <5000000 6000000>;
+
+ led {
+ led-active-low;
+ };
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_e000 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ status = "okay";
+ label = "wan";
+ phy-handle = <ðphy4>;
+
+ nvmem-cells = <&macaddr_factory_e000 3>;
+ nvmem-cell-names = "mac-address";
+};
+
+ðphy4 {
+ /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";
+ };
+};
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wrc-gs-1pci.dtsi"
+
+/ {
+ compatible = "elecom,wmc-m1267gst2", "mediatek,mt7621-soc";
+ model = "ELECOM WMC-M1267GST2";
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_fff4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ nvmem-cells = <&macaddr_factory_fffa>;
+ nvmem-cell-names = "mac-address";
+};
+
+&partitions {
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0x1800000>;
+ };
+
+ partition@1850000 {
+ label = "tm_pattern";
+ reg = <0x1850000 0x400000>;
+ read-only;
+ };
+
+ partition@1c50000 {
+ label = "tm_key";
+ reg = <0x1c50000 0x100000>;
+ read-only;
+ };
+
+ partition@1d50000 {
+ label = "nvram";
+ reg = <0x1d50000 0xb0000>;
+ read-only;
+ };
+
+ partition@1e00000 {
+ label = "user_data";
+ reg = <0x1e00000 0x200000>;
+ read-only;
+ };
+};
+
+&wifi {
+ nvmem-cells = <&macaddr_factory_4 (-1)>;
+ nvmem-cell-names = "mac-address";
+};
+
+&factory {
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_factory_4: macaddr@4 {
+ compatible = "mac-base";
+ reg = <0x4 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ macaddr_factory_fff4: macaddr@fff4 {
+ reg = <0xfff4 0x6>;
+ };
+
+ macaddr_factory_fffa: macaddr@fffa {
+ reg = <0xfffa 0x6>;
+ };
+ };
+};
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wrc-gs-1pci.dtsi"
+
+/ {
+ compatible = "elecom,wmc-s1267gs2", "mediatek,mt7621-soc";
+ model = "ELECOM WMC-S1267GS2";
+
+ aliases {
+ /*
+ * A MAC address printed to the label is an address of
+ * 5 GHz band on stock firmware, but there is no
+ * per-band MAC address support on Linux Kernel and that
+ * address is not assigned to any wlan devices now.
+ */
+ /delete-property/ label-mac-device;
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_fff4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ status = "disabled";
+};
+
+&partitions {
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0x1800000>;
+ };
+
+ partition@1850000 {
+ label = "tm_pattern";
+ reg = <0x1850000 0x400000>;
+ read-only;
+ };
+
+ partition@1c50000 {
+ label = "tm_key";
+ reg = <0x1c50000 0x100000>;
+ read-only;
+ };
+
+ partition@1d50000 {
+ label = "nvram";
+ reg = <0x1d50000 0xb0000>;
+ read-only;
+ };
+
+ partition@1e00000 {
+ label = "user_data";
+ reg = <0x1e00000 0x200000>;
+ read-only;
+ };
+};
+
+&wifi {
+ nvmem-cells = <&macaddr_factory_4 (-1)>;
+ nvmem-cell-names = "mac-address";
+};
+
+&factory {
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_factory_4: macaddr@4 {
+ compatible = "mac-base";
+ reg = <0x4 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ macaddr_factory_fff4: macaddr@fff4 {
+ reg = <0xfff4 0x6>;
+ };
+ };
+};
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&nand {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&nand {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "jdcloud,re-cp-02", "mediatek,mt7621-soc";
+ model = "JDCloud RE-CP-02";
+
+ aliases {
+ label-mac-device = &gmac0;
+ led-boot = &led_status_blue;
+ led-failsafe = &led_status_red;
+ led-running = &led_status_green;
+ led-upgrade = &led_status_blue;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_red: led-0 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+ };
+
+ led_status_blue: led-1 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+ };
+
+ led_status_green: led-2 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ wps {
+ label = "wps";
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+};
+
+&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 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ compatible = "u-boot,env";
+ label = "Config";
+ reg = <0x40000 0x10000>;
+ };
+
+ 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_3fff4: macaddr@3fff4 {
+ reg = <0x3fff4 0x6>;
+ };
+
+ macaddr_factory_3fffa: macaddr@3fffa {
+ reg = <0x3fffa 0x6>;
+ };
+ };
+ };
+
+ partition@90000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x90000 0xf70000>;
+ };
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "uart3", "jtag", "wdt";
+ function = "gpio";
+ };
+};
+
+&sdhci {
+ status = "okay";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ mediatek,disable-radar-background;
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_3fff4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ status = "okay";
+ label = "wan";
+ phy-handle = <ðphy4>;
+
+ nvmem-cells = <&macaddr_factory_3fffa>;
+ nvmem-cell-names = "mac-address";
+};
+
+ðphy4 {
+ /delete-property/ interrupts;
+};
+
+&switch0 {
+ ports {
+ port@1 {
+ status = "okay";
+ label = "lan1";
+ };
+
+ port@2 {
+ status = "okay";
+ label = "lan2";
+ };
+
+ port@3 {
+ status = "okay";
+ label = "lan3";
+ };
+ };
+};
+
+&xhci {
+ status = "disabled";
+};
};
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&gmac0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethernet-phy@0 {
- status = "disabled";
- };
+ðphy0 {
+ interrupts = <0>;
+};
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
};
};
-ðernet {
- pinctrl-names = "default";
- pinctrl-0 = <&mdio_pins>;
-};
-
&gmac0 {
nvmem-cells = <&macaddr_custom_40 0>;
nvmem-cell-names = "mac-address";
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&pcie {
status = "okay";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&gmac0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
};
};
-
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&state_default {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
-
&switch0 {
ports {
port@1 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy0>;
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
phy-handle = <ðphy4>;
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
-};
-
&pcie {
status = "okay";
};
};
};
-&gmac0 {
- nvmem-cells = <&macaddr_factory_3fff4>;
- nvmem-cell-names = "mac-address";
-};
-
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
-};
-
&switch0 {
ports {
port@3 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
-
&switch0 {
gpio-controller;
#gpio-cells = <2>;
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&nand {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy4: ethernet-phy@4 {
- reg = <4>;
- };
+ðphy4 {
+ /delete-property/ interrupts;
};
&switch0 {
nvmem-cell-names = "mac-address";
};
-&mdio {
- ethphy0: ethernet-phy@0 {
- reg = <0>;
- };
+ðphy0 {
+ /delete-property/ interrupts;
};
&pcie {
do {
data_src = &hwstats->tx_bytes;
data_dst = data;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
start = u64_stats_fetch_begin(&hwstats->syncp);
-#else
- start = u64_stats_fetch_begin_irq(&hwstats->syncp);
-#endif
for (i = 0; i < ARRAY_SIZE(fe_gdma_str); i++)
*data_dst++ = *data_src++;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
} while (u64_stats_fetch_retry(&hwstats->syncp, start));
-#else
- } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
-#endif
}
static struct ethtool_ops fe_ethtool_ops = {
}
do {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
start = u64_stats_fetch_begin(&hwstats->syncp);
-#else
- start = u64_stats_fetch_begin_irq(&hwstats->syncp);
-#endif
storage->rx_packets = hwstats->rx_packets;
storage->tx_packets = hwstats->tx_packets;
storage->rx_bytes = hwstats->rx_bytes;
storage->rx_crc_errors = hwstats->rx_fcs_errors;
storage->rx_errors = hwstats->rx_checksum_errors;
storage->tx_aborted_errors = hwstats->tx_skip;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
} while (u64_stats_fetch_retry(&hwstats->syncp, start));
-#else
- } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
-#endif
storage->tx_errors = priv->netdev->stats.tx_errors;
storage->rx_dropped = priv->netdev->stats.rx_dropped;
#include <linux/dma-mapping.h>
#include <linux/phy.h>
#include <linux/ethtool.h>
-#include <linux/version.h>
enum fe_reg {
FE_REG_PDMA_GLO_CFG = 0,
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/version.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/pinctrl/pinconf.h>
gpiochip->set_multiple = aw9523_gpio_set_multiple;
gpiochip->set_config = gpiochip_generic_config;
gpiochip->parent = dev;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
gpiochip->fwnode = dev->fwnode;
-#else
- gpiochip->of_node = dev->of_node;
-#endif
gpiochip->owner = THIS_MODULE;
gpiochip->can_sleep = true;
return regmap_reinit_cache(awi->regmap, &aw9523_regmap);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
static int aw9523_probe(struct i2c_client *client)
-#else
-static int aw9523_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-#endif
{
struct device *dev = &client->dev;
struct pinctrl_desc *pdesc;
endef
TARGET_DEVICES += wavlink_wl-wn530hg4
+define Device/wavlink_wl-wn531g3
+ SOC := mt7620a
+ IMAGE_SIZE := 7808k
+ DEVICE_VENDOR := Wavlink
+ DEVICE_MODEL := WL-WN531G3
+ DEVICE_PACKAGES := kmod-mt76x2 kmod-phy-realtek kmod-usb2 kmod-usb-ohci
+endef
+TARGET_DEVICES += wavlink_wl-wn531g3
+
define Device/wavlink_wl-wn535k1
SOC := mt7620a
IMAGE_SIZE := 7360k
check-size | append-metadata
endef
-define Device/dlink_dir-xx60-a1
+define Device/dlink_dir_nand_128m
$(Device/nand)
IMAGE_SIZE := 40960k
DEVICE_VENDOR := D-Link
TARGET_DEVICES += dlink_dir-1935-a1
define Device/dlink_dir-1960-a1
- $(Device/dlink_dir-xx60-a1)
+ $(Device/dlink_dir_nand_128m)
DEVICE_MODEL := DIR-1960
DEVICE_VARIANT := A1
endef
TARGET_DEVICES += dlink_dir-1960-a1
+define Device/dlink_dir-2150-a1
+ $(Device/dlink_dir_nand_128m)
+ DEVICE_MODEL := DIR-2150
+ DEVICE_VARIANT := A1
+ DEVICE_PACKAGES += kmod-mt7603 -kmod-usb3 -kmod-usb-ledtrig-usbport
+ IMAGES += factory.bin
+ IMAGE/factory.bin := $$(IMAGE/recovery.bin) | dlink-sge-image $$(DEVICE_MODEL)
+endef
+TARGET_DEVICES += dlink_dir-2150-a1
+
define Device/dlink_dir-2640-a1
- $(Device/dlink_dir-xx60-a1)
+ $(Device/dlink_dir_nand_128m)
DEVICE_MODEL := DIR-2640
DEVICE_VARIANT := A1
endef
TARGET_DEVICES += dlink_dir-2640-a1
define Device/dlink_dir-2660-a1
- $(Device/dlink_dir-xx60-a1)
+ $(Device/dlink_dir_nand_128m)
DEVICE_MODEL := DIR-2660
DEVICE_VARIANT := A1
endef
TARGET_DEVICES += dlink_dir-2660-a1
define Device/dlink_dir-3040-a1
- $(Device/dlink_dir-xx60-a1)
+ $(Device/dlink_dir_nand_128m)
DEVICE_MODEL := DIR-3040
DEVICE_VARIANT := A1
endef
TARGET_DEVICES += dlink_dir-3040-a1
define Device/dlink_dir-3060-a1
- $(Device/dlink_dir-xx60-a1)
+ $(Device/dlink_dir_nand_128m)
DEVICE_MODEL := DIR-3060
DEVICE_VARIANT := A1
endef
TARGET_DEVICES += dlink_dir-853-a1
define Device/dlink_dir-853-a3
- $(Device/dlink_dir-xx60-a1)
+ $(Device/dlink_dir_nand_128m)
DEVICE_MODEL := DIR-853
DEVICE_VARIANT := A3
IMAGES += factory.bin
endef
TARGET_DEVICES += edimax_rg21s
-define Device/elecom_wrc-1167ghbk2-s
+define Device/elecom_wrc-gs
$(Device/dsa-migration)
- IMAGE_SIZE := 15488k
+ $(Device/uimage-lzma-loader)
DEVICE_VENDOR := ELECOM
- DEVICE_MODEL := WRC-1167GHBK2-S
IMAGES += factory.bin
IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
- elecom-wrc-gs-factory WRC-1167GHBK2-S 0.00
+ elecom-wrc-gs-factory $$$$(ELECOM_HWNAME) 0.00 -N | \
+ append-string MT7621_ELECOM_$$$$(ELECOM_HWNAME)
DEVICE_PACKAGES := kmod-mt7615-firmware -uboot-envtools
endef
-TARGET_DEVICES += elecom_wrc-1167ghbk2-s
-define Device/elecom_wrc-gs
+define Device/elecom_wmc-m1267gst2
+ $(Device/elecom_wrc-gs)
+ IMAGE_SIZE := 24576k
+ DEVICE_MODEL := WMC-M1267GST2
+ ELECOM_HWNAME := WMC-DLGST2
+endef
+TARGET_DEVICES += elecom_wmc-m1267gst2
+
+define Device/elecom_wmc-s1267gs2
+ $(Device/elecom_wrc-gs)
+ IMAGE_SIZE := 24576k
+ DEVICE_MODEL := WMC-S1267GS2
+ ELECOM_HWNAME := WMC-DLGST2
+endef
+TARGET_DEVICES += elecom_wmc-s1267gs2
+
+define Device/elecom_wrc-1167ghbk2-s
$(Device/dsa-migration)
- $(Device/uimage-lzma-loader)
+ IMAGE_SIZE := 15488k
DEVICE_VENDOR := ELECOM
+ DEVICE_MODEL := WRC-1167GHBK2-S
IMAGES += factory.bin
IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
- elecom-wrc-gs-factory $$$$(ELECOM_HWNAME) 0.00 -N | \
- append-string MT7621_ELECOM_$$$$(ELECOM_HWNAME)
+ elecom-wrc-gs-factory WRC-1167GHBK2-S 0.00
DEVICE_PACKAGES := kmod-mt7615-firmware -uboot-envtools
endef
+TARGET_DEVICES += elecom_wrc-1167ghbk2-s
define Device/elecom_wrc-1167gs2-b
$(Device/elecom_wrc-gs)
endef
TARGET_DEVICES += jcg_y2
+define Device/jdcloud_re-cp-02
+ $(Device/dsa-migration)
+ IMAGE_SIZE := 16000k
+ DEVICE_VENDOR := JD-Cloud
+ DEVICE_MODEL := RE-CP-02
+ DEVICE_PACKAGES := kmod-mt7915-firmware kmod-sdhci-mt7620
+endef
+TARGET_DEVICES += jdcloud_re-cp-02
+
define Device/keenetic_kn-3010
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
ucidef_add_switch "switch1" \
"0:lan:3" "1:lan:2" "2:lan:1" "4:lan:4" "3:wan" "7@eth0"
;;
+ wavlink,wl-wn531g3)
+ 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"
tplink,ec220-g5-v2)
wan_mac=$(macaddr_add "$(mtd_get_mac_binary rom 0xf100)" 1)
;;
+ wavlink,wl-wn531g3|\
+ zbtlink,zbt-we1026-5g-16m)
+ label_mac=$(mtd_get_mac_binary factory 0x4)
+ ;;
wavlink,wl-wn535k1)
wan_mac=$(mtd_get_mac_binary factory 0x2e)
label_mac=$(mtd_get_mac_binary factory 0x8004)
;;
- zbtlink,zbt-we1026-5g-16m)
- label_mac=$(mtd_get_mac_binary factory 0x4)
- ;;
zyxel,keenetic-lite-iii-a)
lan_mac=$(mtd_get_mac_binary RF-EEPROM 0x4)
wan_mac=$(mtd_get_mac_binary RF-EEPROM 0x28)
+++ /dev/null
-CONFIG_AR8216_PHY=y
-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_MQ_PCI=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CEVT_R4K=y
-CONFIG_CEVT_SYSTICK_QUIRK=y
-CONFIG_CLKEVT_RT3352=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLK_MTMIPS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=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_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=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_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_DEBUG_PINCTRL=y
-CONFIG_DMA_NONCOHERENT=y
-# CONFIG_DTB_MT7620A_EVAL is not set
-# CONFIG_DTB_OMEGA2P is not set
-CONFIG_DTB_RT_NONE=y
-# CONFIG_DTB_VOCORE2 is not set
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_ETHERNET_PACKET_MANGLE=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_GCC11_NO_ARRAY_BOUNDS=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_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIO_CDEV=y
-# CONFIG_GPIO_MT7621 is not set
-CONFIG_GPIO_RALINK=y
-CONFIG_GPIO_WATCHDOG=y
-# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=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_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_BUILTIN_EXTEND is not set
-# 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_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MT7621_WDT is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
-CONFIG_MTD_SPLIT_JIMAGE_FW=y
-CONFIG_MTD_SPLIT_SEAMA_FW=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_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_GSW_MT7620=y
-CONFIG_NET_RALINK_MDIO=y
-CONFIG_NET_RALINK_MDIO_MT7620=y
-CONFIG_NET_RALINK_MT7620=y
-# CONFIG_NET_RALINK_RT3050 is not set
-CONFIG_NET_RALINK_SOC=y
-CONFIG_NET_SELFTESTS=y
-# CONFIG_NET_VENDOR_MEDIATEK is not set
-CONFIG_NET_VENDOR_RALINK=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_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-# CONFIG_PHY_MT7621_PCI is not set
-CONFIG_PHY_RALINK_USB=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_MT7620=y
-CONFIG_PINCTRL_RALINK=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RALINK=y
-CONFIG_RALINK_WDT=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_SERIAL_8250_RT288X=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SOC_MT7620=y
-# CONFIG_SOC_MT7621 is not set
-# CONFIG_SOC_RT288X is not set
-# CONFIG_SOC_RT305X is not set
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_MT7621 is not set
-CONFIG_SPI_RT2880=y
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_LEDS=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_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=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_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_ZBOOT_LOAD_ADDRESS=0x0
ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "green:rssihigh" "wlan1" "76" "100"
;;
dlink,dir-1960-a1|\
+dlink,dir-2150-a1|\
dlink,dir-2640-a1|\
dlink,dir-2660-a1)
- ucidef_set_led_netdev "wan" "wan" "white:net" "wan"
+ ucidef_set_led_netdev "wan" "wan" "white:wan" "wan"
;;
dlink,dir-3040-a1|\
dlink,dir-3060-a1)
- ucidef_set_led_netdev "net_white" "WAN Link" "white:net" "wan" "link"
- ucidef_set_led_netdev "net_orange" "WAN Activity" "orange:net" "wan" "tx rx"
+ ucidef_set_led_netdev "net_white" "WAN Link" "white:wan" "wan" "link"
+ ucidef_set_led_netdev "net_orange" "WAN Activity" "orange:wan" "wan" "tx rx"
;;
dlink,dir-853-a1|\
dlink,dir-853-a3)
dlink,covr-x1860-a1)
ucidef_set_interfaces_lan_wan "ethernet" "internet"
;;
+ elecom,wmc-s1267gs2|\
+ linksys,re6500|\
+ netgear,wac104|\
+ zyxel,lte3301-plus)
+ ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
+ ;;
gnubee,gb-pc1)
ucidef_set_interface_lan "ethblack ethblue"
;;
gnubee,gb-pc2)
ucidef_set_interface_lan "ethblack ethblue ethyellow"
;;
- linksys,re6500|\
- netgear,wac104|\
- zyxel,lte3301-plus)
- ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
- ;;
mikrotik,routerboard-750gr3)
ucidef_set_interfaces_lan_wan "lan2 lan3 lan4 lan5" "wan"
;;
$((0xff)) ]] || printf '\xff' | dd of=/dev/mtdblock3 \
count=1 bs=1 seek=$((0x20001))
;;
+ jdcloud,re-cp-02)
+ echo -e "bootcount 0\nbootlimit 5\nupgrade_available 1" | /usr/sbin/fw_setenv -s -
+ ;;
linksys,e5600|\
linksys,ea6350-v4|\
linksys,ea7300-v1|\
board=$(board_name)
case "$board" in
+dlink,dir-1960-a1|\
+dlink,dir-2640-a1|\
+dlink,dir-2660-a1|\
+dlink,dir-3040-a1|\
+dlink,dir-3060-a1)
+ migrate_leds ':net=:wan'
+ ;;
tplink,archer-a6-v3|\
tplink,archer-c6-v3)
migrate_leds ':wifi2g$=:wlan-2' ':wifi5g$=:wlan-5'
dlink,covr-x1860-a1|\
dlink,dap-x1860-a1|\
dlink,dir-1960-a1|\
+ dlink,dir-2150-a1|\
dlink,dir-2640-a1|\
dlink,dir-2660-a1|\
dlink,dir-3040-a1|\
+++ /dev/null
-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_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=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_MT7621=y
-CONFIG_CLOCKSOURCE_WATCHDOG=y
-CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-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_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_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_CRC16=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_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_CSRC_R4K=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_PINCTRL=y
-CONFIG_DIMLIB=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DTC=y
-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_GCC11_NO_ARRAY_BOUNDS=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_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_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-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_GRO_CELLS=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_I2C_MT7621=y
-CONFIG_ICPLUS_PHY=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_LED_TRIGGER_PHY=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEDIATEK_GE_PHY=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIKROTIK=y
-CONFIG_MIKROTIK_RB_SYSFS=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_BUILTIN_EXTEND is not set
-# 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_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=4
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MT7621_WDT=y
-# CONFIG_MTD_CFI_INTELEXT 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_MT7621=y
-CONFIG_MTD_NAND_MTK_BMT=y
-# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_ROUTERBOOT_PARTS=y
-CONFIG_MTD_SERCOMM_PARTS=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
-CONFIG_MTD_SPLIT_FIT_FW=y
-CONFIG_MTD_SPLIT_MINOR_FW=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_TRX_FW=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_MTD_VIRT_CONCAT=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MT7530=y
-CONFIG_NET_DSA_MT7530_MDIO=y
-# CONFIG_NET_DSA_MT7530_MMIO is not set
-CONFIG_NET_DSA_TAG_MTK=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_MEDIATEK_SOC=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NET_VENDOR_MEDIATEK=y
-# CONFIG_NET_VENDOR_RALINK is not set
-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_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_POOL_STATS=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_PCIE_MT7621=y
-CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_DRIVERS_GENERIC=y
-CONFIG_PCS_MTK_LYNXI=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PHY_MT7621_PCI=y
-# CONFIG_PHY_RALINK_USB is not set
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_AW9523=y
-CONFIG_PINCTRL_MT7621=y
-CONFIG_PINCTRL_RALINK=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINCTRL_SX150X=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_QCOM_NET_PHYLIB=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RALINK=y
-# CONFIG_RALINK_WDT is not set
-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_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_BQ32K=y
-CONFIG_RTC_DRV_PCF8563=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-# CONFIG_SCHED_CORE is not set
-CONFIG_SCHED_SMT=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BUS=y
-# CONFIG_SOC_MT7620 is not set
-CONFIG_SOC_MT7621=y
-# CONFIG_SOC_RT288X is not set
-# CONFIG_SOC_RT305X is not set
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_MT7621=y
-# CONFIG_SPI_RT2880 is not set
-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_HIGHMEM=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_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_USB_SUPPORT=y
-CONFIG_USE_OF=y
-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
+++ /dev/null
-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_MQ_PCI=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CEVT_R4K=y
-CONFIG_CEVT_SYSTICK_QUIRK=y
-CONFIG_CLKEVT_RT3352=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLK_MTMIPS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=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_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=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_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_DEBUG_PINCTRL=y
-CONFIG_DMA_NONCOHERENT=y
-# CONFIG_DTB_MT7620A_EVAL is not set
-# CONFIG_DTB_OMEGA2P is not set
-CONFIG_DTB_RT_NONE=y
-# CONFIG_DTB_VOCORE2 is not set
-CONFIG_DTC=y
-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_GCC11_NO_ARRAY_BOUNDS=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_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_GENERIC=y
-CONFIG_GPIO_MT7621=y
-# CONFIG_GPIO_RALINK is not set
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=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_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_BUILTIN_EXTEND is not set
-# 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_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MT7621_WDT=y
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set
-CONFIG_MTD_PARSER_TRX=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=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_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_ESW_RT3050=y
-# CONFIG_NET_RALINK_MT7620 is not set
-CONFIG_NET_RALINK_RT3050=y
-CONFIG_NET_RALINK_SOC=y
-CONFIG_NET_SELFTESTS=y
-# CONFIG_NET_VENDOR_MEDIATEK is not set
-CONFIG_NET_VENDOR_RALINK=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_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-# CONFIG_PHY_MT7621_PCI is not set
-CONFIG_PHY_RALINK_USB=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_MT7620=y
-CONFIG_PINCTRL_RALINK=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RALINK=y
-# CONFIG_RALINK_WDT is not set
-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_RTC_CLASS=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SOC_MT7620=y
-# CONFIG_SOC_MT7621 is not set
-# CONFIG_SOC_RT288X is not set
-# CONFIG_SOC_RT305X is not set
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_MT7621=y
-# CONFIG_SPI_RT2880 is not set
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_LEDS=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_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=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_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_ZBOOT_LOAD_ADDRESS=0x0
+++ /dev/null
-From 35dcae535afc153fa83f2fe51c0812536c192c58 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 6 Feb 2023 09:33:05 +0100
-Subject: [PATCH] clk: ralink: fix 'mt7621_gate_is_enabled()' function
-
-Compiling clock driver with CONFIG_UBSAN enabled shows the following trace:
-
-UBSAN: shift-out-of-bounds in drivers/clk/ralink/clk-mt7621.c:121:15
-shift exponent 131072 is too large for 32-bit type 'long unsigned int'
-CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.15.86 #0
-Stack : ...
-
-Call Trace:
-[<80009a58>] show_stack+0x38/0x118
-[<8045ce04>] dump_stack_lvl+0x60/0x80
-[<80458868>] ubsan_epilogue+0x10/0x54
-[<804590e0>] __ubsan_handle_shift_out_of_bounds+0x118/0x190
-[<804c9a10>] mt7621_gate_is_enabled+0x98/0xa0
-[<804bb774>] clk_core_is_enabled+0x34/0x90
-[<80aad73c>] clk_disable_unused_subtree+0x98/0x1e4
-[<80aad6d4>] clk_disable_unused_subtree+0x30/0x1e4
-[<80aad6d4>] clk_disable_unused_subtree+0x30/0x1e4
-[<80aad900>] clk_disable_unused+0x78/0x120
-[<80002030>] do_one_initcall+0x54/0x1f0
-[<80a922a4>] kernel_init_freeable+0x280/0x31c
-[<808047c4>] kernel_init+0x20/0x118
-[<80003e58>] ret_from_kernel_thread+0x14/0x1c
-
-Shifting a value (131032) larger than the type (32 bit unsigned integer)
-is undefined behaviour in C.
-
-The problem is in 'mt7621_gate_is_enabled()' function which is using the
-'BIT()' kernel macro with the bit index for the clock gate to check if the
-bit is set. When the clock gates structure is created driver is already
-setting 'bit_idx' using 'BIT()' macro, so we are wrongly applying an extra
-'BIT()' mask here. Removing it solve the problem and makes this function
-correct. However when clock gating is correctly working, the kernel starts
-disabling those clocks that are not requested. Some drivers for this SoC
-are older than this clock driver itself. So to avoid the kernel to disable
-clocks that have been enabled until now, we must apply 'CLK_IS_CRITICAL'
-flag on gates initialization code.
-
-Fixes: 48df7a26f470 ("clk: ralink: add clock driver for mt7621 SoC")
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20230206083305.147582-1-sergio.paracuellos@gmail.com
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
----
- drivers/clk/ralink/clk-mt7621.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
---- a/drivers/clk/ralink/clk-mt7621.c
-+++ b/drivers/clk/ralink/clk-mt7621.c
-@@ -121,7 +121,7 @@ static int mt7621_gate_is_enabled(struct
- if (regmap_read(sysc, SYSC_REG_CLKCFG1, &val))
- return 0;
-
-- return val & BIT(clk_gate->bit_idx);
-+ return val & clk_gate->bit_idx;
- }
-
- static const struct clk_ops mt7621_gate_ops = {
-@@ -133,8 +133,14 @@ static const struct clk_ops mt7621_gate_
- static int mt7621_gate_ops_init(struct device *dev,
- struct mt7621_gate *sclk)
- {
-+ /*
-+ * There are drivers for this SoC that are older
-+ * than clock driver and are not prepared for the clock.
-+ * We don't want the kernel to disable anything so we
-+ * add CLK_IS_CRITICAL flag here.
-+ */
- struct clk_init_data init = {
-- .flags = CLK_SET_RATE_PARENT,
-+ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
- .num_parents = 1,
- .parent_names = &sclk->parent_name,
- .ops = &mt7621_gate_ops,
+++ /dev/null
-From 612616e6381929e7f9e303f8b8ad3655cc101516 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 19 Jun 2023 06:09:33 +0200
-Subject: [PATCH 1/9] dt-bindings: clock: add mtmips SoCs system controller
-
-Adds device tree binding documentation for system controller node present
-in Mediatek MIPS and Ralink SOCs. This node is a clock and reset provider
-for the rest of the world. This covers RT2880, RT3050, RT3052, RT3350,
-RT3883, RT5350, MT7620, MT7628 and MT7688 SoCs.
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Acked-by: Stephen Boyd <sboyd@kernel.org>
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- .../bindings/clock/mediatek,mtmips-sysc.yaml | 64 ++++++++++++++++++++++
- 1 file changed, 64 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mtmips-sysc.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/mediatek,mtmips-sysc.yaml
-@@ -0,0 +1,64 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/mediatek,mtmips-sysc.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MTMIPS SoCs System Controller
-+
-+maintainers:
-+ - Sergio Paracuellos <sergio.paracuellos@gmail.com>
-+
-+description: |
-+ MediaTek MIPS and Ralink SoCs provides a system controller to allow
-+ to access to system control registers. These registers include clock
-+ and reset related ones so this node is both clock and reset provider
-+ for the rest of the world.
-+
-+ These SoCs have an XTAL from where the cpu clock is
-+ provided as well as derived clocks for the bus and the peripherals.
-+
-+properties:
-+ compatible:
-+ items:
-+ - enum:
-+ - ralink,mt7620-sysc
-+ - ralink,mt7628-sysc
-+ - ralink,mt7688-sysc
-+ - ralink,rt2880-sysc
-+ - ralink,rt3050-sysc
-+ - ralink,rt3052-sysc
-+ - ralink,rt3352-sysc
-+ - ralink,rt3883-sysc
-+ - ralink,rt5350-sysc
-+ - const: syscon
-+
-+ reg:
-+ maxItems: 1
-+
-+ '#clock-cells':
-+ description:
-+ The first cell indicates the clock number.
-+ const: 1
-+
-+ '#reset-cells':
-+ description:
-+ The first cell indicates the reset bit within the register.
-+ const: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - '#clock-cells'
-+ - '#reset-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ syscon@0 {
-+ compatible = "ralink,rt5350-sysc", "syscon";
-+ reg = <0x0 0x100>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
+++ /dev/null
-From 6f3b15586eef736831abe6a14f2a6906bc0dc074 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 19 Jun 2023 06:09:34 +0200
-Subject: [PATCH 2/9] clk: ralink: add clock and reset driver for MTMIPS SoCs
-
-Until now, clock related code for old ralink SoCs was based in fixed clocks
-using 'clk_register_fixed_rate' and 'clkdev_create' directly doing in code
-and not using device tree at all for their definition. Including this driver
-is an effort to be able to define proper clocks using device tree and also
-cleaning all the clock and reset related code from 'arch/mips/ralink' dir.
-This clock and reset driver covers all the ralink SoCs but MT7621 which is
-the newest and provides gating and some differences that make it different
-from its predecesors. It has its own driver since some time ago. The ralink
-SoCs we are taking about are RT2880, RT3050, RT3052, RT3350, RT3352, RT3883,
-RT5350, MT7620, MT7628 and MT7688. Mostly the code in this new driver has
-been extracted from 'arch/mips/ralink' and cleanly put using kernel clock
-driver APIs. The clock plans for this SoCs only talks about relation between
-CPU frequency and BUS frequency. This relation is different depending on the
-particular SoC. CPU clock is derived from XTAL frequencies.
-
-Depending on the SoC we have the following frequencies:
-* RT2880 SoC:
- - XTAL: 40 MHz.
- - CPU: 250, 266, 280 or 300 MHz.
- - BUS: CPU / 2 MHz.
-* RT3050, RT3052, RT3350:
- - XTAL: 40 MHz.
- - CPU: 320 or 384 MHz.
- - BUS: CPU / 3 MHz.
-* RT3352:
- - XTAL: 40 MHz.
- - CPU: 384 or 400 MHz.
- - BUS: CPU / 3 MHz.
- - PERIPH: 40 MHz.
-* RT3383:
- - XTAL: 40 MHz.
- - CPU: 250, 384, 480 or 500 MHz.
- - BUS: Depends on RAM Type and CPU:
- + RAM DDR2: 125. ELSE 83 MHz.
- + RAM DDR2: 128. ELSE 96 MHz.
- + RAM DDR2: 160. ELSE 120 MHz.
- + RAM DDR2: 166. ELSE 125 MHz.
-* RT5350:
- - XTAL: 40 MHz.
- - CPU: 300, 320 or 360 MHz.
- - BUS: CPU / 3, CPU / 4, CPU / 3 MHz.
- - PERIPH: 40 MHz.
-* MT7628 and MT7688:
- - XTAL: 20 MHz or 40 MHz.
- - CPU: 575 or 580 MHz.
- - BUS: CPU / 3.
- - PCMI2S: 480 MHz.
- - PERIPH: 40 MHz.
-* MT7620:
- - XTAL: 20 MHz or 40 MHz.
- - PLL: XTAL, 480, 600 MHz.
- - CPU: depends on PLL and some mult and dividers.
- - BUS: depends on PLL and some mult and dividers.
- - PERIPH: 40 or XTAL MHz.
-
-MT7620 is a bit more complex deriving CPU clock from a PLL and an bunch of
-register reads and predividers. To derive CPU and BUS frequencies in the
-MT7620 SoC 'mt7620_calc_rate()' helper is used.
-
-In the case XTAL can have different frequencies and we need a different
-clock frequency for peripherals 'periph' clock in introduced.
-
-The rest of the peripherals present in the SoC just follow their parent
-frequencies.
-
-With this information the clk driver will provide all the clock and reset
-functionality from a set of hardcoded clocks allowing to define a nice
-device tree without fixed clocks.
-
-Acked-by: Stephen Boyd <sboyd@kernel.org>
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- drivers/clk/ralink/Kconfig | 7 +
- drivers/clk/ralink/Makefile | 1 +
- drivers/clk/ralink/clk-mtmips.c | 1115 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 1123 insertions(+)
- create mode 100644 drivers/clk/ralink/clk-mtmips.c
-
---- a/drivers/clk/ralink/Kconfig
-+++ b/drivers/clk/ralink/Kconfig
-@@ -9,3 +9,10 @@ config CLK_MT7621
- select MFD_SYSCON
- help
- This driver supports MediaTek MT7621 basic clocks.
-+
-+config CLK_MTMIPS
-+ bool "Clock driver for MTMIPS SoCs"
-+ depends on SOC_RT305X || SOC_RT288X || SOC_RT3883 || SOC_MT7620 || COMPILE_TEST
-+ select MFD_SYSCON
-+ help
-+ This driver supports MTMIPS basic clocks.
---- a/drivers/clk/ralink/Makefile
-+++ b/drivers/clk/ralink/Makefile
-@@ -1,2 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-$(CONFIG_CLK_MT7621) += clk-mt7621.o
-+obj-$(CONFIG_CLK_MTMIPS) += clk-mtmips.o
---- /dev/null
-+++ b/drivers/clk/ralink/clk-mtmips.c
-@@ -0,0 +1,1115 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * MTMIPS SoCs Clock Driver
-+ * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-+ */
-+
-+#include <linux/bitops.h>
-+#include <linux/clk-provider.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+#include <linux/reset-controller.h>
-+#include <linux/slab.h>
-+
-+/* Configuration registers */
-+#define SYSC_REG_SYSTEM_CONFIG 0x10
-+#define SYSC_REG_CLKCFG0 0x2c
-+#define SYSC_REG_RESET_CTRL 0x34
-+#define SYSC_REG_CPU_SYS_CLKCFG 0x3c
-+#define SYSC_REG_CPLL_CONFIG0 0x54
-+#define SYSC_REG_CPLL_CONFIG1 0x58
-+
-+/* RT2880 SoC */
-+#define RT2880_CONFIG_CPUCLK_SHIFT 20
-+#define RT2880_CONFIG_CPUCLK_MASK 0x3
-+#define RT2880_CONFIG_CPUCLK_250 0x0
-+#define RT2880_CONFIG_CPUCLK_266 0x1
-+#define RT2880_CONFIG_CPUCLK_280 0x2
-+#define RT2880_CONFIG_CPUCLK_300 0x3
-+
-+/* RT305X SoC */
-+#define RT305X_SYSCFG_CPUCLK_SHIFT 18
-+#define RT305X_SYSCFG_CPUCLK_MASK 0x1
-+#define RT305X_SYSCFG_CPUCLK_LOW 0x0
-+#define RT305X_SYSCFG_CPUCLK_HIGH 0x1
-+
-+/* RT3352 SoC */
-+#define RT3352_SYSCFG0_CPUCLK_SHIFT 8
-+#define RT3352_SYSCFG0_CPUCLK_MASK 0x1
-+#define RT3352_SYSCFG0_CPUCLK_LOW 0x0
-+#define RT3352_SYSCFG0_CPUCLK_HIGH 0x1
-+
-+/* RT3383 SoC */
-+#define RT3883_SYSCFG0_DRAM_TYPE_DDR2 BIT(17)
-+#define RT3883_SYSCFG0_CPUCLK_SHIFT 8
-+#define RT3883_SYSCFG0_CPUCLK_MASK 0x3
-+#define RT3883_SYSCFG0_CPUCLK_250 0x0
-+#define RT3883_SYSCFG0_CPUCLK_384 0x1
-+#define RT3883_SYSCFG0_CPUCLK_480 0x2
-+#define RT3883_SYSCFG0_CPUCLK_500 0x3
-+
-+/* RT5350 SoC */
-+#define RT5350_CLKCFG0_XTAL_SEL BIT(20)
-+#define RT5350_SYSCFG0_CPUCLK_SHIFT 8
-+#define RT5350_SYSCFG0_CPUCLK_MASK 0x3
-+#define RT5350_SYSCFG0_CPUCLK_360 0x0
-+#define RT5350_SYSCFG0_CPUCLK_320 0x2
-+#define RT5350_SYSCFG0_CPUCLK_300 0x3
-+
-+/* MT7620 and MT76x8 SoCs */
-+#define MT7620_XTAL_FREQ_SEL BIT(6)
-+#define CPLL_CFG0_SW_CFG BIT(31)
-+#define CPLL_CFG0_PLL_MULT_RATIO_SHIFT 16
-+#define CPLL_CFG0_PLL_MULT_RATIO_MASK 0x7
-+#define CPLL_CFG0_LC_CURFCK BIT(15)
-+#define CPLL_CFG0_BYPASS_REF_CLK BIT(14)
-+#define CPLL_CFG0_PLL_DIV_RATIO_SHIFT 10
-+#define CPLL_CFG0_PLL_DIV_RATIO_MASK 0x3
-+#define CPLL_CFG1_CPU_AUX1 BIT(25)
-+#define CPLL_CFG1_CPU_AUX0 BIT(24)
-+#define CLKCFG0_PERI_CLK_SEL BIT(4)
-+#define CPU_SYS_CLKCFG_OCP_RATIO_SHIFT 16
-+#define CPU_SYS_CLKCFG_OCP_RATIO_MASK 0xf
-+#define CPU_SYS_CLKCFG_OCP_RATIO_1 0 /* 1:1 (Reserved) */
-+#define CPU_SYS_CLKCFG_OCP_RATIO_1_5 1 /* 1:1.5 (Reserved) */
-+#define CPU_SYS_CLKCFG_OCP_RATIO_2 2 /* 1:2 */
-+#define CPU_SYS_CLKCFG_OCP_RATIO_2_5 3 /* 1:2.5 (Reserved) */
-+#define CPU_SYS_CLKCFG_OCP_RATIO_3 4 /* 1:3 */
-+#define CPU_SYS_CLKCFG_OCP_RATIO_3_5 5 /* 1:3.5 (Reserved) */
-+#define CPU_SYS_CLKCFG_OCP_RATIO_4 6 /* 1:4 */
-+#define CPU_SYS_CLKCFG_OCP_RATIO_5 7 /* 1:5 */
-+#define CPU_SYS_CLKCFG_OCP_RATIO_10 8 /* 1:10 */
-+#define CPU_SYS_CLKCFG_CPU_FDIV_SHIFT 8
-+#define CPU_SYS_CLKCFG_CPU_FDIV_MASK 0x1f
-+#define CPU_SYS_CLKCFG_CPU_FFRAC_SHIFT 0
-+#define CPU_SYS_CLKCFG_CPU_FFRAC_MASK 0x1f
-+
-+/* clock scaling */
-+#define CLKCFG_FDIV_MASK 0x1f00
-+#define CLKCFG_FDIV_USB_VAL 0x0300
-+#define CLKCFG_FFRAC_MASK 0x001f
-+#define CLKCFG_FFRAC_USB_VAL 0x0003
-+
-+struct mtmips_clk;
-+struct mtmips_clk_fixed;
-+struct mtmips_clk_factor;
-+
-+struct mtmips_clk_data {
-+ struct mtmips_clk *clk_base;
-+ size_t num_clk_base;
-+ struct mtmips_clk_fixed *clk_fixed;
-+ size_t num_clk_fixed;
-+ struct mtmips_clk_factor *clk_factor;
-+ size_t num_clk_factor;
-+ struct mtmips_clk *clk_periph;
-+ size_t num_clk_periph;
-+};
-+
-+struct mtmips_clk_priv {
-+ struct regmap *sysc;
-+ const struct mtmips_clk_data *data;
-+};
-+
-+struct mtmips_clk {
-+ struct clk_hw hw;
-+ struct mtmips_clk_priv *priv;
-+};
-+
-+struct mtmips_clk_fixed {
-+ const char *name;
-+ const char *parent;
-+ unsigned long rate;
-+ struct clk_hw *hw;
-+};
-+
-+struct mtmips_clk_factor {
-+ const char *name;
-+ const char *parent;
-+ int mult;
-+ int div;
-+ unsigned long flags;
-+ struct clk_hw *hw;
-+};
-+
-+static unsigned long mtmips_pherip_clk_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ return parent_rate;
-+}
-+
-+static const struct clk_ops mtmips_periph_clk_ops = {
-+ .recalc_rate = mtmips_pherip_clk_rate,
-+};
-+
-+#define CLK_PERIPH(_name, _parent) { \
-+ .init = &(const struct clk_init_data) { \
-+ .name = _name, \
-+ .ops = &mtmips_periph_clk_ops, \
-+ .parent_data = &(const struct clk_parent_data) {\
-+ .name = _parent, \
-+ .fw_name = _parent \
-+ }, \
-+ .num_parents = 1, \
-+ /* \
-+ * There are drivers for these SoCs that are \
-+ * older than clock driver and are not prepared \
-+ * for the clock. We don't want the kernel to \
-+ * disable anything so we add CLK_IS_CRITICAL \
-+ * flag here. \
-+ */ \
-+ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL \
-+ }, \
-+}
-+
-+static struct mtmips_clk rt2880_pherip_clks[] = {
-+ { CLK_PERIPH("300100.timer", "bus") },
-+ { CLK_PERIPH("300120.watchdog", "bus") },
-+ { CLK_PERIPH("300500.uart", "bus") },
-+ { CLK_PERIPH("300900.i2c", "bus") },
-+ { CLK_PERIPH("300c00.uartlite", "bus") },
-+ { CLK_PERIPH("400000.ethernet", "bus") },
-+ { CLK_PERIPH("480000.wmac", "xtal") }
-+};
-+
-+static struct mtmips_clk rt305x_pherip_clks[] = {
-+ { CLK_PERIPH("10000100.timer", "bus") },
-+ { CLK_PERIPH("10000120.watchdog", "bus") },
-+ { CLK_PERIPH("10000500.uart", "bus") },
-+ { CLK_PERIPH("10000900.i2c", "bus") },
-+ { CLK_PERIPH("10000a00.i2s", "bus") },
-+ { CLK_PERIPH("10000b00.spi", "bus") },
-+ { CLK_PERIPH("10000b40.spi", "bus") },
-+ { CLK_PERIPH("10000c00.uartlite", "bus") },
-+ { CLK_PERIPH("10100000.ethernet", "bus") },
-+ { CLK_PERIPH("10180000.wmac", "xtal") }
-+};
-+
-+static struct mtmips_clk rt5350_pherip_clks[] = {
-+ { CLK_PERIPH("10000100.timer", "bus") },
-+ { CLK_PERIPH("10000120.watchdog", "bus") },
-+ { CLK_PERIPH("10000500.uart", "periph") },
-+ { CLK_PERIPH("10000900.i2c", "periph") },
-+ { CLK_PERIPH("10000a00.i2s", "periph") },
-+ { CLK_PERIPH("10000b00.spi", "bus") },
-+ { CLK_PERIPH("10000b40.spi", "bus") },
-+ { CLK_PERIPH("10000c00.uartlite", "periph") },
-+ { CLK_PERIPH("10100000.ethernet", "bus") },
-+ { CLK_PERIPH("10180000.wmac", "xtal") }
-+};
-+
-+static struct mtmips_clk mt7620_pherip_clks[] = {
-+ { CLK_PERIPH("10000100.timer", "periph") },
-+ { CLK_PERIPH("10000120.watchdog", "periph") },
-+ { CLK_PERIPH("10000500.uart", "periph") },
-+ { CLK_PERIPH("10000900.i2c", "periph") },
-+ { CLK_PERIPH("10000a00.i2s", "periph") },
-+ { CLK_PERIPH("10000b00.spi", "bus") },
-+ { CLK_PERIPH("10000b40.spi", "bus") },
-+ { CLK_PERIPH("10000c00.uartlite", "periph") },
-+ { CLK_PERIPH("10180000.wmac", "xtal") }
-+};
-+
-+static struct mtmips_clk mt76x8_pherip_clks[] = {
-+ { CLK_PERIPH("10000100.timer", "periph") },
-+ { CLK_PERIPH("10000120.watchdog", "periph") },
-+ { CLK_PERIPH("10000900.i2c", "periph") },
-+ { CLK_PERIPH("10000a00.i2s", "pcmi2s") },
-+ { CLK_PERIPH("10000b00.spi", "bus") },
-+ { CLK_PERIPH("10000b40.spi", "bus") },
-+ { CLK_PERIPH("10000c00.uart0", "periph") },
-+ { CLK_PERIPH("10000d00.uart1", "periph") },
-+ { CLK_PERIPH("10000e00.uart2", "periph") },
-+ { CLK_PERIPH("10300000.wmac", "xtal") }
-+};
-+
-+static int mtmips_register_pherip_clocks(struct device_node *np,
-+ struct clk_hw_onecell_data *clk_data,
-+ struct mtmips_clk_priv *priv)
-+{
-+ struct clk_hw **hws = clk_data->hws;
-+ struct mtmips_clk *sclk;
-+ size_t idx_start = priv->data->num_clk_base + priv->data->num_clk_fixed +
-+ priv->data->num_clk_factor;
-+ int ret, i;
-+
-+ for (i = 0; i < priv->data->num_clk_periph; i++) {
-+ int idx = idx_start + i;
-+
-+ sclk = &priv->data->clk_periph[i];
-+ ret = of_clk_hw_register(np, &sclk->hw);
-+ if (ret) {
-+ pr_err("Couldn't register peripheral clock %d\n", idx);
-+ goto err_clk_unreg;
-+ }
-+
-+ hws[idx] = &sclk->hw;
-+ }
-+
-+ return 0;
-+
-+err_clk_unreg:
-+ while (--i >= 0) {
-+ sclk = &priv->data->clk_periph[i];
-+ clk_hw_unregister(&sclk->hw);
-+ }
-+ return ret;
-+}
-+
-+#define CLK_FIXED(_name, _parent, _rate) \
-+ { \
-+ .name = _name, \
-+ .parent = _parent, \
-+ .rate = _rate \
-+ }
-+
-+static struct mtmips_clk_fixed rt305x_fixed_clocks[] = {
-+ CLK_FIXED("xtal", NULL, 40000000)
-+};
-+
-+static struct mtmips_clk_fixed rt3352_fixed_clocks[] = {
-+ CLK_FIXED("periph", "xtal", 40000000)
-+};
-+
-+static struct mtmips_clk_fixed mt76x8_fixed_clocks[] = {
-+ CLK_FIXED("pcmi2s", "xtal", 480000000),
-+ CLK_FIXED("periph", "xtal", 40000000)
-+};
-+
-+static int mtmips_register_fixed_clocks(struct clk_hw_onecell_data *clk_data,
-+ struct mtmips_clk_priv *priv)
-+{
-+ struct clk_hw **hws = clk_data->hws;
-+ struct mtmips_clk_fixed *sclk;
-+ size_t idx_start = priv->data->num_clk_base;
-+ int ret, i;
-+
-+ for (i = 0; i < priv->data->num_clk_fixed; i++) {
-+ int idx = idx_start + i;
-+
-+ sclk = &priv->data->clk_fixed[i];
-+ sclk->hw = clk_hw_register_fixed_rate(NULL, sclk->name,
-+ sclk->parent, 0,
-+ sclk->rate);
-+ if (IS_ERR(sclk->hw)) {
-+ pr_err("Couldn't register fixed clock %d\n", idx);
-+ goto err_clk_unreg;
-+ }
-+
-+ hws[idx] = sclk->hw;
-+ }
-+
-+ return 0;
-+
-+err_clk_unreg:
-+ while (--i >= 0) {
-+ sclk = &priv->data->clk_fixed[i];
-+ clk_hw_unregister_fixed_rate(sclk->hw);
-+ }
-+ return ret;
-+}
-+
-+#define CLK_FACTOR(_name, _parent, _mult, _div) \
-+ { \
-+ .name = _name, \
-+ .parent = _parent, \
-+ .mult = _mult, \
-+ .div = _div, \
-+ .flags = CLK_SET_RATE_PARENT \
-+ }
-+
-+static struct mtmips_clk_factor rt2880_factor_clocks[] = {
-+ CLK_FACTOR("bus", "cpu", 1, 2)
-+};
-+
-+static struct mtmips_clk_factor rt305x_factor_clocks[] = {
-+ CLK_FACTOR("bus", "cpu", 1, 3)
-+};
-+
-+static int mtmips_register_factor_clocks(struct clk_hw_onecell_data *clk_data,
-+ struct mtmips_clk_priv *priv)
-+{
-+ struct clk_hw **hws = clk_data->hws;
-+ struct mtmips_clk_factor *sclk;
-+ size_t idx_start = priv->data->num_clk_base + priv->data->num_clk_fixed;
-+ int ret, i;
-+
-+ for (i = 0; i < priv->data->num_clk_factor; i++) {
-+ int idx = idx_start + i;
-+
-+ sclk = &priv->data->clk_factor[i];
-+ sclk->hw = clk_hw_register_fixed_factor(NULL, sclk->name,
-+ sclk->parent, sclk->flags,
-+ sclk->mult, sclk->div);
-+ if (IS_ERR(sclk->hw)) {
-+ pr_err("Couldn't register factor clock %d\n", idx);
-+ goto err_clk_unreg;
-+ }
-+
-+ hws[idx] = sclk->hw;
-+ }
-+
-+ return 0;
-+
-+err_clk_unreg:
-+ while (--i >= 0) {
-+ sclk = &priv->data->clk_factor[i];
-+ clk_hw_unregister_fixed_factor(sclk->hw);
-+ }
-+ return ret;
-+}
-+
-+static inline struct mtmips_clk *to_mtmips_clk(struct clk_hw *hw)
-+{
-+ return container_of(hw, struct mtmips_clk, hw);
-+}
-+
-+static unsigned long rt5350_xtal_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 val;
-+
-+ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &val);
-+ if (!(val & RT5350_CLKCFG0_XTAL_SEL))
-+ return 20000000;
-+
-+ return 40000000;
-+}
-+
-+static unsigned long rt5350_cpu_recalc_rate(struct clk_hw *hw,
-+ unsigned long xtal_clk)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 t;
-+
-+ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);
-+ t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) & RT5350_SYSCFG0_CPUCLK_MASK;
-+
-+ switch (t) {
-+ case RT5350_SYSCFG0_CPUCLK_360:
-+ return 360000000;
-+ case RT5350_SYSCFG0_CPUCLK_320:
-+ return 320000000;
-+ case RT5350_SYSCFG0_CPUCLK_300:
-+ return 300000000;
-+ default:
-+ BUG();
-+ }
-+}
-+
-+static unsigned long rt5350_bus_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ if (parent_rate == 320000000)
-+ return parent_rate / 4;
-+
-+ return parent_rate / 3;
-+}
-+
-+static unsigned long rt3352_cpu_recalc_rate(struct clk_hw *hw,
-+ unsigned long xtal_clk)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 t;
-+
-+ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);
-+ t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) & RT3352_SYSCFG0_CPUCLK_MASK;
-+
-+ switch (t) {
-+ case RT3352_SYSCFG0_CPUCLK_LOW:
-+ return 384000000;
-+ case RT3352_SYSCFG0_CPUCLK_HIGH:
-+ return 400000000;
-+ default:
-+ BUG();
-+ }
-+}
-+
-+static unsigned long rt305x_cpu_recalc_rate(struct clk_hw *hw,
-+ unsigned long xtal_clk)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 t;
-+
-+ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);
-+ t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) & RT305X_SYSCFG_CPUCLK_MASK;
-+
-+ switch (t) {
-+ case RT305X_SYSCFG_CPUCLK_LOW:
-+ return 320000000;
-+ case RT305X_SYSCFG_CPUCLK_HIGH:
-+ return 384000000;
-+ default:
-+ BUG();
-+ }
-+}
-+
-+static unsigned long rt3883_cpu_recalc_rate(struct clk_hw *hw,
-+ unsigned long xtal_clk)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 t;
-+
-+ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);
-+ t = (t >> RT3883_SYSCFG0_CPUCLK_SHIFT) & RT3883_SYSCFG0_CPUCLK_MASK;
-+
-+ switch (t) {
-+ case RT3883_SYSCFG0_CPUCLK_250:
-+ return 250000000;
-+ case RT3883_SYSCFG0_CPUCLK_384:
-+ return 384000000;
-+ case RT3883_SYSCFG0_CPUCLK_480:
-+ return 480000000;
-+ case RT3883_SYSCFG0_CPUCLK_500:
-+ return 500000000;
-+ default:
-+ BUG();
-+ }
-+}
-+
-+static unsigned long rt3883_bus_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 ddr2;
-+ u32 t;
-+
-+ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);
-+ ddr2 = t & RT3883_SYSCFG0_DRAM_TYPE_DDR2;
-+
-+ switch (parent_rate) {
-+ case 250000000:
-+ return (ddr2) ? 125000000 : 83000000;
-+ case 384000000:
-+ return (ddr2) ? 128000000 : 96000000;
-+ case 480000000:
-+ return (ddr2) ? 160000000 : 120000000;
-+ case 500000000:
-+ return (ddr2) ? 166000000 : 125000000;
-+ default:
-+ WARN_ON_ONCE(parent_rate == 0);
-+ return parent_rate / 4;
-+ }
-+}
-+
-+static unsigned long rt2880_cpu_recalc_rate(struct clk_hw *hw,
-+ unsigned long xtal_clk)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 t;
-+
-+ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);
-+ t = (t >> RT2880_CONFIG_CPUCLK_SHIFT) & RT2880_CONFIG_CPUCLK_MASK;
-+
-+ switch (t) {
-+ case RT2880_CONFIG_CPUCLK_250:
-+ return 250000000;
-+ case RT2880_CONFIG_CPUCLK_266:
-+ return 266000000;
-+ case RT2880_CONFIG_CPUCLK_280:
-+ return 280000000;
-+ case RT2880_CONFIG_CPUCLK_300:
-+ return 300000000;
-+ default:
-+ BUG();
-+ }
-+}
-+
-+static u32 mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div)
-+{
-+ u64 t;
-+
-+ t = ref_rate;
-+ t *= mul;
-+ t = div_u64(t, div);
-+
-+ return t;
-+}
-+
-+static unsigned long mt7620_pll_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ static const u32 clk_divider[] = { 2, 3, 4, 8 };
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ unsigned long cpu_pll;
-+ u32 t;
-+ u32 mul;
-+ u32 div;
-+
-+ regmap_read(sysc, SYSC_REG_CPLL_CONFIG0, &t);
-+ if (t & CPLL_CFG0_BYPASS_REF_CLK) {
-+ cpu_pll = parent_rate;
-+ } else if ((t & CPLL_CFG0_SW_CFG) == 0) {
-+ cpu_pll = 600000000;
-+ } else {
-+ mul = (t >> CPLL_CFG0_PLL_MULT_RATIO_SHIFT) &
-+ CPLL_CFG0_PLL_MULT_RATIO_MASK;
-+ mul += 24;
-+ if (t & CPLL_CFG0_LC_CURFCK)
-+ mul *= 2;
-+
-+ div = (t >> CPLL_CFG0_PLL_DIV_RATIO_SHIFT) &
-+ CPLL_CFG0_PLL_DIV_RATIO_MASK;
-+
-+ WARN_ON_ONCE(div >= ARRAY_SIZE(clk_divider));
-+
-+ cpu_pll = mt7620_calc_rate(parent_rate, mul, clk_divider[div]);
-+ }
-+
-+ regmap_read(sysc, SYSC_REG_CPLL_CONFIG1, &t);
-+ if (t & CPLL_CFG1_CPU_AUX1)
-+ return parent_rate;
-+
-+ if (t & CPLL_CFG1_CPU_AUX0)
-+ return 480000000;
-+
-+ return cpu_pll;
-+}
-+
-+static unsigned long mt7620_cpu_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 t;
-+ u32 mul;
-+ u32 div;
-+
-+ regmap_read(sysc, SYSC_REG_CPU_SYS_CLKCFG, &t);
-+ mul = t & CPU_SYS_CLKCFG_CPU_FFRAC_MASK;
-+ div = (t >> CPU_SYS_CLKCFG_CPU_FDIV_SHIFT) &
-+ CPU_SYS_CLKCFG_CPU_FDIV_MASK;
-+
-+ return mt7620_calc_rate(parent_rate, mul, div);
-+}
-+
-+static unsigned long mt7620_bus_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ static const u32 ocp_dividers[16] = {
-+ [CPU_SYS_CLKCFG_OCP_RATIO_2] = 2,
-+ [CPU_SYS_CLKCFG_OCP_RATIO_3] = 3,
-+ [CPU_SYS_CLKCFG_OCP_RATIO_4] = 4,
-+ [CPU_SYS_CLKCFG_OCP_RATIO_5] = 5,
-+ [CPU_SYS_CLKCFG_OCP_RATIO_10] = 10,
-+ };
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 t;
-+ u32 ocp_ratio;
-+ u32 div;
-+
-+ regmap_read(sysc, SYSC_REG_CPU_SYS_CLKCFG, &t);
-+ ocp_ratio = (t >> CPU_SYS_CLKCFG_OCP_RATIO_SHIFT) &
-+ CPU_SYS_CLKCFG_OCP_RATIO_MASK;
-+
-+ if (WARN_ON_ONCE(ocp_ratio >= ARRAY_SIZE(ocp_dividers)))
-+ return parent_rate;
-+
-+ div = ocp_dividers[ocp_ratio];
-+
-+ if (WARN(!div, "invalid divider for OCP ratio %u", ocp_ratio))
-+ return parent_rate;
-+
-+ return parent_rate / div;
-+}
-+
-+static unsigned long mt7620_periph_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 t;
-+
-+ regmap_read(sysc, SYSC_REG_CLKCFG0, &t);
-+ if (t & CLKCFG0_PERI_CLK_SEL)
-+ return parent_rate;
-+
-+ return 40000000;
-+}
-+
-+static unsigned long mt76x8_xtal_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct mtmips_clk *clk = to_mtmips_clk(hw);
-+ struct regmap *sysc = clk->priv->sysc;
-+ u32 t;
-+
-+ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);
-+ if (t & MT7620_XTAL_FREQ_SEL)
-+ return 40000000;
-+
-+ return 20000000;
-+}
-+
-+static unsigned long mt76x8_cpu_recalc_rate(struct clk_hw *hw,
-+ unsigned long xtal_clk)
-+{
-+ if (xtal_clk == 40000000)
-+ return 580000000;
-+
-+ return 575000000;
-+}
-+
-+#define CLK_BASE(_name, _parent, _recalc) { \
-+ .init = &(const struct clk_init_data) { \
-+ .name = _name, \
-+ .ops = &(const struct clk_ops) { \
-+ .recalc_rate = _recalc, \
-+ }, \
-+ .parent_data = &(const struct clk_parent_data) { \
-+ .name = _parent, \
-+ .fw_name = _parent \
-+ }, \
-+ .num_parents = _parent ? 1 : 0 \
-+ }, \
-+}
-+
-+static struct mtmips_clk rt2880_clks_base[] = {
-+ { CLK_BASE("cpu", "xtal", rt2880_cpu_recalc_rate) }
-+};
-+
-+static struct mtmips_clk rt305x_clks_base[] = {
-+ { CLK_BASE("cpu", "xtal", rt305x_cpu_recalc_rate) }
-+};
-+
-+static struct mtmips_clk rt3352_clks_base[] = {
-+ { CLK_BASE("xtal", NULL, rt5350_xtal_recalc_rate) },
-+ { CLK_BASE("cpu", "xtal", rt3352_cpu_recalc_rate) }
-+};
-+
-+static struct mtmips_clk rt3883_clks_base[] = {
-+ { CLK_BASE("cpu", "xtal", rt3883_cpu_recalc_rate) },
-+ { CLK_BASE("bus", "cpu", rt3883_bus_recalc_rate) }
-+};
-+
-+static struct mtmips_clk rt5350_clks_base[] = {
-+ { CLK_BASE("xtal", NULL, rt5350_xtal_recalc_rate) },
-+ { CLK_BASE("cpu", "xtal", rt5350_cpu_recalc_rate) },
-+ { CLK_BASE("bus", "cpu", rt5350_bus_recalc_rate) }
-+};
-+
-+static struct mtmips_clk mt7620_clks_base[] = {
-+ { CLK_BASE("xtal", NULL, mt76x8_xtal_recalc_rate) },
-+ { CLK_BASE("pll", "xtal", mt7620_pll_recalc_rate) },
-+ { CLK_BASE("cpu", "pll", mt7620_cpu_recalc_rate) },
-+ { CLK_BASE("periph", "xtal", mt7620_periph_recalc_rate) },
-+ { CLK_BASE("bus", "cpu", mt7620_bus_recalc_rate) }
-+};
-+
-+static struct mtmips_clk mt76x8_clks_base[] = {
-+ { CLK_BASE("xtal", NULL, mt76x8_xtal_recalc_rate) },
-+ { CLK_BASE("cpu", "xtal", mt76x8_cpu_recalc_rate) }
-+};
-+
-+static int mtmips_register_clocks(struct device_node *np,
-+ struct clk_hw_onecell_data *clk_data,
-+ struct mtmips_clk_priv *priv)
-+{
-+ struct clk_hw **hws = clk_data->hws;
-+ struct mtmips_clk *sclk;
-+ int ret, i;
-+
-+ for (i = 0; i < priv->data->num_clk_base; i++) {
-+ sclk = &priv->data->clk_base[i];
-+ sclk->priv = priv;
-+ ret = of_clk_hw_register(np, &sclk->hw);
-+ if (ret) {
-+ pr_err("Couldn't register top clock %i\n", i);
-+ goto err_clk_unreg;
-+ }
-+
-+ hws[i] = &sclk->hw;
-+ }
-+
-+ return 0;
-+
-+err_clk_unreg:
-+ while (--i >= 0) {
-+ sclk = &priv->data->clk_base[i];
-+ clk_hw_unregister(&sclk->hw);
-+ }
-+ return ret;
-+}
-+
-+static const struct mtmips_clk_data rt2880_clk_data = {
-+ .clk_base = rt2880_clks_base,
-+ .num_clk_base = ARRAY_SIZE(rt2880_clks_base),
-+ .clk_fixed = rt305x_fixed_clocks,
-+ .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
-+ .clk_factor = rt2880_factor_clocks,
-+ .num_clk_factor = ARRAY_SIZE(rt2880_factor_clocks),
-+ .clk_periph = rt2880_pherip_clks,
-+ .num_clk_periph = ARRAY_SIZE(rt2880_pherip_clks),
-+};
-+
-+static const struct mtmips_clk_data rt305x_clk_data = {
-+ .clk_base = rt305x_clks_base,
-+ .num_clk_base = ARRAY_SIZE(rt305x_clks_base),
-+ .clk_fixed = rt305x_fixed_clocks,
-+ .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
-+ .clk_factor = rt305x_factor_clocks,
-+ .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),
-+ .clk_periph = rt305x_pherip_clks,
-+ .num_clk_periph = ARRAY_SIZE(rt305x_pherip_clks),
-+};
-+
-+static const struct mtmips_clk_data rt3352_clk_data = {
-+ .clk_base = rt3352_clks_base,
-+ .num_clk_base = ARRAY_SIZE(rt3352_clks_base),
-+ .clk_fixed = rt3352_fixed_clocks,
-+ .num_clk_fixed = ARRAY_SIZE(rt3352_fixed_clocks),
-+ .clk_factor = rt305x_factor_clocks,
-+ .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),
-+ .clk_periph = rt5350_pherip_clks,
-+ .num_clk_periph = ARRAY_SIZE(rt5350_pherip_clks),
-+};
-+
-+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_factor = NULL,
-+ .num_clk_factor = 0,
-+ .clk_periph = rt5350_pherip_clks,
-+ .num_clk_periph = ARRAY_SIZE(rt5350_pherip_clks),
-+};
-+
-+static const struct mtmips_clk_data rt5350_clk_data = {
-+ .clk_base = rt5350_clks_base,
-+ .num_clk_base = ARRAY_SIZE(rt5350_clks_base),
-+ .clk_fixed = rt3352_fixed_clocks,
-+ .num_clk_fixed = ARRAY_SIZE(rt3352_fixed_clocks),
-+ .clk_factor = NULL,
-+ .num_clk_factor = 0,
-+ .clk_periph = rt5350_pherip_clks,
-+ .num_clk_periph = ARRAY_SIZE(rt5350_pherip_clks),
-+};
-+
-+static const struct mtmips_clk_data mt7620_clk_data = {
-+ .clk_base = mt7620_clks_base,
-+ .num_clk_base = ARRAY_SIZE(mt7620_clks_base),
-+ .clk_fixed = NULL,
-+ .num_clk_fixed = 0,
-+ .clk_factor = NULL,
-+ .num_clk_factor = 0,
-+ .clk_periph = mt7620_pherip_clks,
-+ .num_clk_periph = ARRAY_SIZE(mt7620_pherip_clks),
-+};
-+
-+static const struct mtmips_clk_data mt76x8_clk_data = {
-+ .clk_base = mt76x8_clks_base,
-+ .num_clk_base = ARRAY_SIZE(mt76x8_clks_base),
-+ .clk_fixed = mt76x8_fixed_clocks,
-+ .num_clk_fixed = ARRAY_SIZE(mt76x8_fixed_clocks),
-+ .clk_factor = rt305x_factor_clocks,
-+ .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),
-+ .clk_periph = mt76x8_pherip_clks,
-+ .num_clk_periph = ARRAY_SIZE(mt76x8_pherip_clks),
-+};
-+
-+static const struct of_device_id mtmips_of_match[] = {
-+ {
-+ .compatible = "ralink,rt2880-sysc",
-+ .data = &rt2880_clk_data,
-+ },
-+ {
-+ .compatible = "ralink,rt3050-sysc",
-+ .data = &rt305x_clk_data,
-+ },
-+ {
-+ .compatible = "ralink,rt3052-sysc",
-+ .data = &rt305x_clk_data,
-+ },
-+ {
-+ .compatible = "ralink,rt3352-sysc",
-+ .data = &rt3352_clk_data,
-+ },
-+ {
-+ .compatible = "ralink,rt3883-sysc",
-+ .data = &rt3883_clk_data,
-+ },
-+ {
-+ .compatible = "ralink,rt5350-sysc",
-+ .data = &rt5350_clk_data,
-+ },
-+ {
-+ .compatible = "ralink,mt7620-sysc",
-+ .data = &mt7620_clk_data,
-+ },
-+ {
-+ .compatible = "ralink,mt7628-sysc",
-+ .data = &mt76x8_clk_data,
-+ },
-+ {
-+ .compatible = "ralink,mt7688-sysc",
-+ .data = &mt76x8_clk_data,
-+ },
-+ {}
-+};
-+
-+static void __init mtmips_clk_regs_init(struct device_node *node,
-+ struct mtmips_clk_priv *priv)
-+{
-+ u32 t;
-+
-+ if (!of_device_is_compatible(node, "ralink,mt7620-sysc"))
-+ return;
-+
-+ /*
-+ * When the CPU goes into sleep mode, the BUS
-+ * clock will be too low for USB to function properly.
-+ * Adjust the busses fractional divider to fix this
-+ */
-+ regmap_read(priv->sysc, SYSC_REG_CPU_SYS_CLKCFG, &t);
-+ t &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK);
-+ t |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL;
-+ regmap_write(priv->sysc, SYSC_REG_CPU_SYS_CLKCFG, t);
-+}
-+
-+static void __init mtmips_clk_init(struct device_node *node)
-+{
-+ const struct of_device_id *match;
-+ const struct mtmips_clk_data *data;
-+ struct mtmips_clk_priv *priv;
-+ struct clk_hw_onecell_data *clk_data;
-+ int ret, i, count;
-+
-+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return;
-+
-+ priv->sysc = syscon_node_to_regmap(node);
-+ if (IS_ERR(priv->sysc)) {
-+ pr_err("Could not get sysc syscon regmap\n");
-+ goto free_clk_priv;
-+ }
-+
-+ mtmips_clk_regs_init(node, priv);
-+
-+ match = of_match_node(mtmips_of_match, node);
-+ if (WARN_ON(!match))
-+ return;
-+
-+ data = match->data;
-+ priv->data = data;
-+ count = priv->data->num_clk_base + priv->data->num_clk_fixed +
-+ priv->data->num_clk_factor + priv->data->num_clk_periph;
-+ clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL);
-+ if (!clk_data)
-+ goto free_clk_priv;
-+
-+ ret = mtmips_register_clocks(node, clk_data, priv);
-+ if (ret) {
-+ pr_err("Couldn't register top clocks\n");
-+ goto free_clk_data;
-+ }
-+
-+ ret = mtmips_register_fixed_clocks(clk_data, priv);
-+ if (ret) {
-+ pr_err("Couldn't register fixed clocks\n");
-+ goto unreg_clk_top;
-+ }
-+
-+ ret = mtmips_register_factor_clocks(clk_data, priv);
-+ if (ret) {
-+ pr_err("Couldn't register factor clocks\n");
-+ goto unreg_clk_fixed;
-+ }
-+
-+ ret = mtmips_register_pherip_clocks(node, clk_data, priv);
-+ if (ret) {
-+ pr_err("Couldn't register peripheral clocks\n");
-+ goto unreg_clk_factor;
-+ }
-+
-+ clk_data->num = count;
-+
-+ ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
-+ if (ret) {
-+ pr_err("Couldn't add clk hw provider\n");
-+ goto unreg_clk_periph;
-+ }
-+
-+ return;
-+
-+unreg_clk_periph:
-+ for (i = 0; i < priv->data->num_clk_periph; i++) {
-+ struct mtmips_clk *sclk = &priv->data->clk_periph[i];
-+
-+ clk_hw_unregister(&sclk->hw);
-+ }
-+
-+unreg_clk_factor:
-+ for (i = 0; i < priv->data->num_clk_factor; i++) {
-+ struct mtmips_clk_factor *sclk = &priv->data->clk_factor[i];
-+
-+ clk_hw_unregister_fixed_factor(sclk->hw);
-+ }
-+
-+unreg_clk_fixed:
-+ for (i = 0; i < priv->data->num_clk_fixed; i++) {
-+ struct mtmips_clk_fixed *sclk = &priv->data->clk_fixed[i];
-+
-+ clk_hw_unregister_fixed_rate(sclk->hw);
-+ }
-+
-+unreg_clk_top:
-+ for (i = 0; i < priv->data->num_clk_base; i++) {
-+ struct mtmips_clk *sclk = &priv->data->clk_base[i];
-+
-+ clk_hw_unregister(&sclk->hw);
-+ }
-+
-+free_clk_data:
-+ kfree(clk_data);
-+
-+free_clk_priv:
-+ kfree(priv);
-+}
-+CLK_OF_DECLARE_DRIVER(rt2880_clk, "ralink,rt2880-sysc", mtmips_clk_init);
-+CLK_OF_DECLARE_DRIVER(rt3050_clk, "ralink,rt3050-sysc", mtmips_clk_init);
-+CLK_OF_DECLARE_DRIVER(rt3052_clk, "ralink,rt3052-sysc", mtmips_clk_init);
-+CLK_OF_DECLARE_DRIVER(rt3352_clk, "ralink,rt3352-sysc", mtmips_clk_init);
-+CLK_OF_DECLARE_DRIVER(rt3883_clk, "ralink,rt3883-sysc", mtmips_clk_init);
-+CLK_OF_DECLARE_DRIVER(rt5350_clk, "ralink,rt5350-sysc", mtmips_clk_init);
-+CLK_OF_DECLARE_DRIVER(mt7620_clk, "ralink,mt7620-sysc", mtmips_clk_init);
-+CLK_OF_DECLARE_DRIVER(mt7628_clk, "ralink,mt7628-sysc", mtmips_clk_init);
-+CLK_OF_DECLARE_DRIVER(mt7688_clk, "ralink,mt7688-sysc", mtmips_clk_init);
-+
-+struct mtmips_rst {
-+ struct reset_controller_dev rcdev;
-+ struct regmap *sysc;
-+};
-+
-+static struct mtmips_rst *to_mtmips_rst(struct reset_controller_dev *dev)
-+{
-+ return container_of(dev, struct mtmips_rst, rcdev);
-+}
-+
-+static int mtmips_assert_device(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ struct mtmips_rst *data = to_mtmips_rst(rcdev);
-+ struct regmap *sysc = data->sysc;
-+
-+ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), BIT(id));
-+}
-+
-+static int mtmips_deassert_device(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ struct mtmips_rst *data = to_mtmips_rst(rcdev);
-+ struct regmap *sysc = data->sysc;
-+
-+ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), 0);
-+}
-+
-+static int mtmips_reset_device(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ int ret;
-+
-+ ret = mtmips_assert_device(rcdev, id);
-+ if (ret < 0)
-+ return ret;
-+
-+ return mtmips_deassert_device(rcdev, id);
-+}
-+
-+static int mtmips_rst_xlate(struct reset_controller_dev *rcdev,
-+ const struct of_phandle_args *reset_spec)
-+{
-+ unsigned long id = reset_spec->args[0];
-+
-+ if (id == 0 || id >= rcdev->nr_resets)
-+ return -EINVAL;
-+
-+ return id;
-+}
-+
-+static const struct reset_control_ops reset_ops = {
-+ .reset = mtmips_reset_device,
-+ .assert = mtmips_assert_device,
-+ .deassert = mtmips_deassert_device
-+};
-+
-+static int mtmips_reset_init(struct device *dev, struct regmap *sysc)
-+{
-+ struct mtmips_rst *rst_data;
-+
-+ rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL);
-+ if (!rst_data)
-+ return -ENOMEM;
-+
-+ rst_data->sysc = sysc;
-+ rst_data->rcdev.ops = &reset_ops;
-+ rst_data->rcdev.owner = THIS_MODULE;
-+ rst_data->rcdev.nr_resets = 32;
-+ rst_data->rcdev.of_reset_n_cells = 1;
-+ rst_data->rcdev.of_xlate = mtmips_rst_xlate;
-+ rst_data->rcdev.of_node = dev_of_node(dev);
-+
-+ return devm_reset_controller_register(dev, &rst_data->rcdev);
-+}
-+
-+static int mtmips_clk_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct device *dev = &pdev->dev;
-+ struct mtmips_clk_priv *priv;
-+ int ret;
-+
-+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->sysc = syscon_node_to_regmap(np);
-+ if (IS_ERR(priv->sysc))
-+ return dev_err_probe(dev, PTR_ERR(priv->sysc),
-+ "Could not get sysc syscon regmap\n");
-+
-+ ret = mtmips_reset_init(dev, priv->sysc);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Could not init reset controller\n");
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id mtmips_clk_of_match[] = {
-+ { .compatible = "ralink,rt2880-reset" },
-+ { .compatible = "ralink,rt2880-sysc" },
-+ { .compatible = "ralink,rt3050-sysc" },
-+ { .compatible = "ralink,rt3052-sysc" },
-+ { .compatible = "ralink,rt3352-sysc" },
-+ { .compatible = "ralink,rt3883-sysc" },
-+ { .compatible = "ralink,rt5350-sysc" },
-+ { .compatible = "ralink,mt7620-sysc" },
-+ { .compatible = "ralink,mt7628-sysc" },
-+ { .compatible = "ralink,mt7688-sysc" },
-+ {}
-+};
-+
-+static struct platform_driver mtmips_clk_driver = {
-+ .probe = mtmips_clk_probe,
-+ .driver = {
-+ .name = "mtmips-clk",
-+ .of_match_table = mtmips_clk_of_match,
-+ },
-+};
-+
-+static int __init mtmips_clk_reset_init(void)
-+{
-+ return platform_driver_register(&mtmips_clk_driver);
-+}
-+arch_initcall(mtmips_clk_reset_init);
+++ /dev/null
-From ffcdf47379eae86dc8f8f02c62994dacf2c9038e Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 19 Jun 2023 06:09:35 +0200
-Subject: [PATCH 3/9] mips: ralink: rt288x: remove clock related code
-
-A properly clock driver for ralink SoCs has been added. Hence there is no
-need to have clock related code in 'arch/mips/ralink' folder anymore.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/include/asm/mach-ralink/rt288x.h | 10 ----------
- arch/mips/ralink/rt288x.c | 31 ------------------------------
- 2 files changed, 41 deletions(-)
-
---- a/arch/mips/include/asm/mach-ralink/rt288x.h
-+++ b/arch/mips/include/asm/mach-ralink/rt288x.h
-@@ -17,7 +17,6 @@
- #define SYSC_REG_CHIP_NAME1 0x04
- #define SYSC_REG_CHIP_ID 0x0c
- #define SYSC_REG_SYSTEM_CONFIG 0x10
--#define SYSC_REG_CLKCFG 0x30
-
- #define RT2880_CHIP_NAME0 0x38325452
- #define RT2880_CHIP_NAME1 0x20203038
-@@ -26,15 +25,6 @@
- #define CHIP_ID_ID_SHIFT 8
- #define CHIP_ID_REV_MASK 0xff
-
--#define SYSTEM_CONFIG_CPUCLK_SHIFT 20
--#define SYSTEM_CONFIG_CPUCLK_MASK 0x3
--#define SYSTEM_CONFIG_CPUCLK_250 0x0
--#define SYSTEM_CONFIG_CPUCLK_266 0x1
--#define SYSTEM_CONFIG_CPUCLK_280 0x2
--#define SYSTEM_CONFIG_CPUCLK_300 0x3
--
--#define CLKCFG_SRAM_CS_N_WDT BIT(9)
--
- #define RT2880_SDRAM_BASE 0x08000000
- #define RT2880_MEM_SIZE_MIN 2
- #define RT2880_MEM_SIZE_MAX 128
---- a/arch/mips/ralink/rt288x.c
-+++ b/arch/mips/ralink/rt288x.c
-@@ -17,37 +17,6 @@
-
- #include "common.h"
-
--void __init ralink_clk_init(void)
--{
-- unsigned long cpu_rate, wmac_rate = 40000000;
-- u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
-- t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK);
--
-- switch (t) {
-- case SYSTEM_CONFIG_CPUCLK_250:
-- cpu_rate = 250000000;
-- break;
-- case SYSTEM_CONFIG_CPUCLK_266:
-- cpu_rate = 266666667;
-- break;
-- case SYSTEM_CONFIG_CPUCLK_280:
-- cpu_rate = 280000000;
-- break;
-- case SYSTEM_CONFIG_CPUCLK_300:
-- cpu_rate = 300000000;
-- break;
-- }
--
-- ralink_clk_add("cpu", cpu_rate);
-- ralink_clk_add("300100.timer", cpu_rate / 2);
-- ralink_clk_add("300120.watchdog", cpu_rate / 2);
-- ralink_clk_add("300500.uart", cpu_rate / 2);
-- ralink_clk_add("300900.i2c", cpu_rate / 2);
-- ralink_clk_add("300c00.uartlite", cpu_rate / 2);
-- ralink_clk_add("400000.ethernet", cpu_rate / 2);
-- ralink_clk_add("480000.wmac", wmac_rate);
--}
--
- void __init ralink_of_remap(void)
- {
- rt_sysc_membase = plat_of_remap_node("ralink,rt2880-sysc");
+++ /dev/null
-From daf73c70f69386fb15960526772ef584a4efcaf2 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 19 Jun 2023 06:09:36 +0200
-Subject: [PATCH 4/9] mips: ralink: rt305x: remove clock related code
-
-A properly clock driver for ralink SoCs has been added. Hence there is no
-need to have clock related code in 'arch/mips/ralink' folder anymore.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/include/asm/mach-ralink/rt305x.h | 21 --------
- arch/mips/ralink/rt305x.c | 78 ------------------------------
- 2 files changed, 99 deletions(-)
-
---- a/arch/mips/include/asm/mach-ralink/rt305x.h
-+++ b/arch/mips/include/asm/mach-ralink/rt305x.h
-@@ -66,26 +66,9 @@ static inline int soc_is_rt5350(void)
- #define CHIP_ID_ID_SHIFT 8
- #define CHIP_ID_REV_MASK 0xff
-
--#define RT305X_SYSCFG_CPUCLK_SHIFT 18
--#define RT305X_SYSCFG_CPUCLK_MASK 0x1
--#define RT305X_SYSCFG_CPUCLK_LOW 0x0
--#define RT305X_SYSCFG_CPUCLK_HIGH 0x1
--
- #define RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT 2
--#define RT305X_SYSCFG_CPUCLK_MASK 0x1
- #define RT305X_SYSCFG_SRAM_CS0_MODE_WDT 0x1
-
--#define RT3352_SYSCFG0_CPUCLK_SHIFT 8
--#define RT3352_SYSCFG0_CPUCLK_MASK 0x1
--#define RT3352_SYSCFG0_CPUCLK_LOW 0x0
--#define RT3352_SYSCFG0_CPUCLK_HIGH 0x1
--
--#define RT5350_SYSCFG0_CPUCLK_SHIFT 8
--#define RT5350_SYSCFG0_CPUCLK_MASK 0x3
--#define RT5350_SYSCFG0_CPUCLK_360 0x0
--#define RT5350_SYSCFG0_CPUCLK_320 0x2
--#define RT5350_SYSCFG0_CPUCLK_300 0x3
--
- #define RT5350_SYSCFG0_DRAM_SIZE_SHIFT 12
- #define RT5350_SYSCFG0_DRAM_SIZE_MASK 7
- #define RT5350_SYSCFG0_DRAM_SIZE_2M 0
-@@ -116,13 +99,9 @@ static inline int soc_is_rt5350(void)
-
- #define RT3352_SYSC_REG_SYSCFG0 0x010
- #define RT3352_SYSC_REG_SYSCFG1 0x014
--#define RT3352_SYSC_REG_CLKCFG1 0x030
- #define RT3352_SYSC_REG_RSTCTRL 0x034
- #define RT3352_SYSC_REG_USB_PS 0x05c
-
--#define RT3352_CLKCFG0_XTAL_SEL BIT(20)
--#define RT3352_CLKCFG1_UPHY0_CLK_EN BIT(18)
--#define RT3352_CLKCFG1_UPHY1_CLK_EN BIT(20)
- #define RT3352_RSTCTRL_UHST BIT(22)
- #define RT3352_RSTCTRL_UDEV BIT(25)
- #define RT3352_SYSCFG1_USB0_HOST_MODE BIT(10)
---- a/arch/mips/ralink/rt305x.c
-+++ b/arch/mips/ralink/rt305x.c
-@@ -53,84 +53,6 @@ static unsigned long rt5350_get_mem_size
- return ret;
- }
-
--void __init ralink_clk_init(void)
--{
-- unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate;
-- unsigned long wmac_rate = 40000000;
--
-- u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
--
-- if (soc_is_rt305x() || soc_is_rt3350()) {
-- t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) &
-- RT305X_SYSCFG_CPUCLK_MASK;
-- switch (t) {
-- case RT305X_SYSCFG_CPUCLK_LOW:
-- cpu_rate = 320000000;
-- break;
-- case RT305X_SYSCFG_CPUCLK_HIGH:
-- cpu_rate = 384000000;
-- break;
-- }
-- sys_rate = uart_rate = wdt_rate = cpu_rate / 3;
-- } else if (soc_is_rt3352()) {
-- t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) &
-- RT3352_SYSCFG0_CPUCLK_MASK;
-- switch (t) {
-- case RT3352_SYSCFG0_CPUCLK_LOW:
-- cpu_rate = 384000000;
-- break;
-- case RT3352_SYSCFG0_CPUCLK_HIGH:
-- cpu_rate = 400000000;
-- break;
-- }
-- sys_rate = wdt_rate = cpu_rate / 3;
-- uart_rate = 40000000;
-- } else if (soc_is_rt5350()) {
-- t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) &
-- RT5350_SYSCFG0_CPUCLK_MASK;
-- switch (t) {
-- case RT5350_SYSCFG0_CPUCLK_360:
-- cpu_rate = 360000000;
-- sys_rate = cpu_rate / 3;
-- break;
-- case RT5350_SYSCFG0_CPUCLK_320:
-- cpu_rate = 320000000;
-- sys_rate = cpu_rate / 4;
-- break;
-- case RT5350_SYSCFG0_CPUCLK_300:
-- cpu_rate = 300000000;
-- sys_rate = cpu_rate / 3;
-- break;
-- default:
-- BUG();
-- }
-- uart_rate = 40000000;
-- wdt_rate = sys_rate;
-- } else {
-- BUG();
-- }
--
-- if (soc_is_rt3352() || soc_is_rt5350()) {
-- u32 val = rt_sysc_r32(RT3352_SYSC_REG_SYSCFG0);
--
-- if (!(val & RT3352_CLKCFG0_XTAL_SEL))
-- wmac_rate = 20000000;
-- }
--
-- ralink_clk_add("cpu", cpu_rate);
-- ralink_clk_add("sys", sys_rate);
-- ralink_clk_add("10000900.i2c", uart_rate);
-- ralink_clk_add("10000a00.i2s", uart_rate);
-- ralink_clk_add("10000b00.spi", sys_rate);
-- ralink_clk_add("10000b40.spi", sys_rate);
-- ralink_clk_add("10000100.timer", wdt_rate);
-- ralink_clk_add("10000120.watchdog", wdt_rate);
-- ralink_clk_add("10000500.uart", uart_rate);
-- ralink_clk_add("10000c00.uartlite", uart_rate);
-- ralink_clk_add("10100000.ethernet", sys_rate);
-- ralink_clk_add("10180000.wmac", wmac_rate);
--}
--
- void __init ralink_of_remap(void)
- {
- rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc");
+++ /dev/null
-From 7cd1bb48885449a9323c7ff0f10012925e93b4e1 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 19 Jun 2023 06:09:37 +0200
-Subject: [PATCH 5/9] mips: ralink: rt3883: remove clock related code
-
-A properly clock driver for ralink SoCs has been added. Hence there is no
-need to have clock related code in 'arch/mips/ralink' folder anymore.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/include/asm/mach-ralink/rt3883.h | 8 ------
- arch/mips/ralink/rt3883.c | 44 ------------------------------
- 2 files changed, 52 deletions(-)
-
---- a/arch/mips/include/asm/mach-ralink/rt3883.h
-+++ b/arch/mips/include/asm/mach-ralink/rt3883.h
-@@ -90,14 +90,6 @@
- #define RT3883_REVID_VER_ID_SHIFT 8
- #define RT3883_REVID_ECO_ID_MASK 0x0f
-
--#define RT3883_SYSCFG0_DRAM_TYPE_DDR2 BIT(17)
--#define RT3883_SYSCFG0_CPUCLK_SHIFT 8
--#define RT3883_SYSCFG0_CPUCLK_MASK 0x3
--#define RT3883_SYSCFG0_CPUCLK_250 0x0
--#define RT3883_SYSCFG0_CPUCLK_384 0x1
--#define RT3883_SYSCFG0_CPUCLK_480 0x2
--#define RT3883_SYSCFG0_CPUCLK_500 0x3
--
- #define RT3883_SYSCFG1_USB0_HOST_MODE BIT(10)
- #define RT3883_SYSCFG1_PCIE_RC_MODE BIT(8)
- #define RT3883_SYSCFG1_PCI_HOST_MODE BIT(7)
---- a/arch/mips/ralink/rt3883.c
-+++ b/arch/mips/ralink/rt3883.c
-@@ -17,50 +17,6 @@
-
- #include "common.h"
-
--void __init ralink_clk_init(void)
--{
-- unsigned long cpu_rate, sys_rate;
-- u32 syscfg0;
-- u32 clksel;
-- u32 ddr2;
--
-- syscfg0 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG0);
-- clksel = ((syscfg0 >> RT3883_SYSCFG0_CPUCLK_SHIFT) &
-- RT3883_SYSCFG0_CPUCLK_MASK);
-- ddr2 = syscfg0 & RT3883_SYSCFG0_DRAM_TYPE_DDR2;
--
-- switch (clksel) {
-- case RT3883_SYSCFG0_CPUCLK_250:
-- cpu_rate = 250000000;
-- sys_rate = (ddr2) ? 125000000 : 83000000;
-- break;
-- case RT3883_SYSCFG0_CPUCLK_384:
-- cpu_rate = 384000000;
-- sys_rate = (ddr2) ? 128000000 : 96000000;
-- break;
-- case RT3883_SYSCFG0_CPUCLK_480:
-- cpu_rate = 480000000;
-- sys_rate = (ddr2) ? 160000000 : 120000000;
-- break;
-- case RT3883_SYSCFG0_CPUCLK_500:
-- cpu_rate = 500000000;
-- sys_rate = (ddr2) ? 166000000 : 125000000;
-- break;
-- }
--
-- ralink_clk_add("cpu", cpu_rate);
-- ralink_clk_add("10000100.timer", sys_rate);
-- ralink_clk_add("10000120.watchdog", sys_rate);
-- ralink_clk_add("10000500.uart", 40000000);
-- ralink_clk_add("10000900.i2c", 40000000);
-- ralink_clk_add("10000a00.i2s", 40000000);
-- ralink_clk_add("10000b00.spi", sys_rate);
-- ralink_clk_add("10000b40.spi", sys_rate);
-- ralink_clk_add("10000c00.uartlite", 40000000);
-- ralink_clk_add("10100000.ethernet", sys_rate);
-- ralink_clk_add("10180000.wmac", 40000000);
--}
--
- void __init ralink_of_remap(void)
- {
- rt_sysc_membase = plat_of_remap_node("ralink,rt3883-sysc");
+++ /dev/null
-From 04b153abdfcbaba70ceef5a846067d4447fd0078 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 19 Jun 2023 06:09:38 +0200
-Subject: [PATCH 6/9] mips: ralink: mt7620: remove clock related code
-
-A proper clock driver for ralink SoCs has been added. Hence there is no
-need to have clock related code in 'arch/mips/ralink' folder anymore.
-Since this is the last clock related code removal, remove also remaining
-prototypes in 'common.h' header file.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/include/asm/mach-ralink/mt7620.h | 35 -----
- arch/mips/ralink/common.h | 3 -
- arch/mips/ralink/mt7620.c | 226 -----------------------------
- 3 files changed, 264 deletions(-)
-
---- a/arch/mips/include/asm/mach-ralink/mt7620.h
-+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
-@@ -19,52 +19,17 @@
- #define SYSC_REG_CHIP_REV 0x0c
- #define SYSC_REG_SYSTEM_CONFIG0 0x10
- #define SYSC_REG_SYSTEM_CONFIG1 0x14
--#define SYSC_REG_CLKCFG0 0x2c
--#define SYSC_REG_CPU_SYS_CLKCFG 0x3c
--#define SYSC_REG_CPLL_CONFIG0 0x54
--#define SYSC_REG_CPLL_CONFIG1 0x58
-
- #define MT7620_CHIP_NAME0 0x3637544d
- #define MT7620_CHIP_NAME1 0x20203032
- #define MT7628_CHIP_NAME1 0x20203832
-
--#define SYSCFG0_XTAL_FREQ_SEL BIT(6)
--
- #define CHIP_REV_PKG_MASK 0x1
- #define CHIP_REV_PKG_SHIFT 16
- #define CHIP_REV_VER_MASK 0xf
- #define CHIP_REV_VER_SHIFT 8
- #define CHIP_REV_ECO_MASK 0xf
-
--#define CLKCFG0_PERI_CLK_SEL BIT(4)
--
--#define CPU_SYS_CLKCFG_OCP_RATIO_SHIFT 16
--#define CPU_SYS_CLKCFG_OCP_RATIO_MASK 0xf
--#define CPU_SYS_CLKCFG_OCP_RATIO_1 0 /* 1:1 (Reserved) */
--#define CPU_SYS_CLKCFG_OCP_RATIO_1_5 1 /* 1:1.5 (Reserved) */
--#define CPU_SYS_CLKCFG_OCP_RATIO_2 2 /* 1:2 */
--#define CPU_SYS_CLKCFG_OCP_RATIO_2_5 3 /* 1:2.5 (Reserved) */
--#define CPU_SYS_CLKCFG_OCP_RATIO_3 4 /* 1:3 */
--#define CPU_SYS_CLKCFG_OCP_RATIO_3_5 5 /* 1:3.5 (Reserved) */
--#define CPU_SYS_CLKCFG_OCP_RATIO_4 6 /* 1:4 */
--#define CPU_SYS_CLKCFG_OCP_RATIO_5 7 /* 1:5 */
--#define CPU_SYS_CLKCFG_OCP_RATIO_10 8 /* 1:10 */
--#define CPU_SYS_CLKCFG_CPU_FDIV_SHIFT 8
--#define CPU_SYS_CLKCFG_CPU_FDIV_MASK 0x1f
--#define CPU_SYS_CLKCFG_CPU_FFRAC_SHIFT 0
--#define CPU_SYS_CLKCFG_CPU_FFRAC_MASK 0x1f
--
--#define CPLL_CFG0_SW_CFG BIT(31)
--#define CPLL_CFG0_PLL_MULT_RATIO_SHIFT 16
--#define CPLL_CFG0_PLL_MULT_RATIO_MASK 0x7
--#define CPLL_CFG0_LC_CURFCK BIT(15)
--#define CPLL_CFG0_BYPASS_REF_CLK BIT(14)
--#define CPLL_CFG0_PLL_DIV_RATIO_SHIFT 10
--#define CPLL_CFG0_PLL_DIV_RATIO_MASK 0x3
--
--#define CPLL_CFG1_CPU_AUX1 BIT(25)
--#define CPLL_CFG1_CPU_AUX0 BIT(24)
--
- #define SYSCFG0_DRAM_TYPE_MASK 0x3
- #define SYSCFG0_DRAM_TYPE_SHIFT 4
- #define SYSCFG0_DRAM_TYPE_SDRAM 0
---- a/arch/mips/ralink/common.h
-+++ b/arch/mips/ralink/common.h
-@@ -23,9 +23,6 @@ extern struct ralink_soc_info soc_info;
-
- extern void ralink_of_remap(void);
-
--extern void ralink_clk_init(void);
--extern void ralink_clk_add(const char *dev, unsigned long rate);
--
- extern void ralink_rst_init(void);
-
- extern void __init prom_soc_init(struct ralink_soc_info *soc_info);
---- a/arch/mips/ralink/mt7620.c
-+++ b/arch/mips/ralink/mt7620.c
-@@ -34,12 +34,6 @@
- #define PMU1_CFG 0x8C
- #define DIG_SW_SEL BIT(25)
-
--/* clock scaling */
--#define CLKCFG_FDIV_MASK 0x1f00
--#define CLKCFG_FDIV_USB_VAL 0x0300
--#define CLKCFG_FFRAC_MASK 0x001f
--#define CLKCFG_FFRAC_USB_VAL 0x0003
--
- /* EFUSE bits */
- #define EFUSE_MT7688 0x100000
-
-@@ -49,226 +43,6 @@
- /* does the board have sdram or ddram */
- static int dram_type;
-
--static __init u32
--mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div)
--{
-- u64 t;
--
-- t = ref_rate;
-- t *= mul;
-- do_div(t, div);
--
-- return t;
--}
--
--#define MHZ(x) ((x) * 1000 * 1000)
--
--static __init unsigned long
--mt7620_get_xtal_rate(void)
--{
-- u32 reg;
--
-- reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
-- if (reg & SYSCFG0_XTAL_FREQ_SEL)
-- return MHZ(40);
--
-- return MHZ(20);
--}
--
--static __init unsigned long
--mt7620_get_periph_rate(unsigned long xtal_rate)
--{
-- u32 reg;
--
-- reg = rt_sysc_r32(SYSC_REG_CLKCFG0);
-- if (reg & CLKCFG0_PERI_CLK_SEL)
-- return xtal_rate;
--
-- return MHZ(40);
--}
--
--static const u32 mt7620_clk_divider[] __initconst = { 2, 3, 4, 8 };
--
--static __init unsigned long
--mt7620_get_cpu_pll_rate(unsigned long xtal_rate)
--{
-- u32 reg;
-- u32 mul;
-- u32 div;
--
-- reg = rt_sysc_r32(SYSC_REG_CPLL_CONFIG0);
-- if (reg & CPLL_CFG0_BYPASS_REF_CLK)
-- return xtal_rate;
--
-- if ((reg & CPLL_CFG0_SW_CFG) == 0)
-- return MHZ(600);
--
-- mul = (reg >> CPLL_CFG0_PLL_MULT_RATIO_SHIFT) &
-- CPLL_CFG0_PLL_MULT_RATIO_MASK;
-- mul += 24;
-- if (reg & CPLL_CFG0_LC_CURFCK)
-- mul *= 2;
--
-- div = (reg >> CPLL_CFG0_PLL_DIV_RATIO_SHIFT) &
-- CPLL_CFG0_PLL_DIV_RATIO_MASK;
--
-- WARN_ON(div >= ARRAY_SIZE(mt7620_clk_divider));
--
-- return mt7620_calc_rate(xtal_rate, mul, mt7620_clk_divider[div]);
--}
--
--static __init unsigned long
--mt7620_get_pll_rate(unsigned long xtal_rate, unsigned long cpu_pll_rate)
--{
-- u32 reg;
--
-- reg = rt_sysc_r32(SYSC_REG_CPLL_CONFIG1);
-- if (reg & CPLL_CFG1_CPU_AUX1)
-- return xtal_rate;
--
-- if (reg & CPLL_CFG1_CPU_AUX0)
-- return MHZ(480);
--
-- return cpu_pll_rate;
--}
--
--static __init unsigned long
--mt7620_get_cpu_rate(unsigned long pll_rate)
--{
-- u32 reg;
-- u32 mul;
-- u32 div;
--
-- reg = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
--
-- mul = reg & CPU_SYS_CLKCFG_CPU_FFRAC_MASK;
-- div = (reg >> CPU_SYS_CLKCFG_CPU_FDIV_SHIFT) &
-- CPU_SYS_CLKCFG_CPU_FDIV_MASK;
--
-- return mt7620_calc_rate(pll_rate, mul, div);
--}
--
--static const u32 mt7620_ocp_dividers[16] __initconst = {
-- [CPU_SYS_CLKCFG_OCP_RATIO_2] = 2,
-- [CPU_SYS_CLKCFG_OCP_RATIO_3] = 3,
-- [CPU_SYS_CLKCFG_OCP_RATIO_4] = 4,
-- [CPU_SYS_CLKCFG_OCP_RATIO_5] = 5,
-- [CPU_SYS_CLKCFG_OCP_RATIO_10] = 10,
--};
--
--static __init unsigned long
--mt7620_get_dram_rate(unsigned long pll_rate)
--{
-- if (dram_type == SYSCFG0_DRAM_TYPE_SDRAM)
-- return pll_rate / 4;
--
-- return pll_rate / 3;
--}
--
--static __init unsigned long
--mt7620_get_sys_rate(unsigned long cpu_rate)
--{
-- u32 reg;
-- u32 ocp_ratio;
-- u32 div;
--
-- reg = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
--
-- ocp_ratio = (reg >> CPU_SYS_CLKCFG_OCP_RATIO_SHIFT) &
-- CPU_SYS_CLKCFG_OCP_RATIO_MASK;
--
-- if (WARN_ON(ocp_ratio >= ARRAY_SIZE(mt7620_ocp_dividers)))
-- return cpu_rate;
--
-- div = mt7620_ocp_dividers[ocp_ratio];
-- if (WARN(!div, "invalid divider for OCP ratio %u", ocp_ratio))
-- return cpu_rate;
--
-- return cpu_rate / div;
--}
--
--void __init ralink_clk_init(void)
--{
-- unsigned long xtal_rate;
-- unsigned long cpu_pll_rate;
-- unsigned long pll_rate;
-- unsigned long cpu_rate;
-- unsigned long sys_rate;
-- unsigned long dram_rate;
-- unsigned long periph_rate;
-- unsigned long pcmi2s_rate;
--
-- xtal_rate = mt7620_get_xtal_rate();
--
--#define RFMT(label) label ":%lu.%03luMHz "
--#define RINT(x) ((x) / 1000000)
--#define RFRAC(x) (((x) / 1000) % 1000)
--
-- if (is_mt76x8()) {
-- if (xtal_rate == MHZ(40))
-- cpu_rate = MHZ(580);
-- else
-- cpu_rate = MHZ(575);
-- dram_rate = sys_rate = cpu_rate / 3;
-- periph_rate = MHZ(40);
-- pcmi2s_rate = MHZ(480);
--
-- ralink_clk_add("10000d00.uartlite", periph_rate);
-- ralink_clk_add("10000e00.uartlite", periph_rate);
-- } else {
-- cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate);
-- pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate);
--
-- cpu_rate = mt7620_get_cpu_rate(pll_rate);
-- dram_rate = mt7620_get_dram_rate(pll_rate);
-- sys_rate = mt7620_get_sys_rate(cpu_rate);
-- periph_rate = mt7620_get_periph_rate(xtal_rate);
-- pcmi2s_rate = periph_rate;
--
-- pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"),
-- RINT(xtal_rate), RFRAC(xtal_rate),
-- RINT(cpu_pll_rate), RFRAC(cpu_pll_rate),
-- RINT(pll_rate), RFRAC(pll_rate));
--
-- ralink_clk_add("10000500.uart", periph_rate);
-- }
--
-- pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"),
-- RINT(cpu_rate), RFRAC(cpu_rate),
-- RINT(dram_rate), RFRAC(dram_rate),
-- RINT(sys_rate), RFRAC(sys_rate),
-- RINT(periph_rate), RFRAC(periph_rate));
--#undef RFRAC
--#undef RINT
--#undef RFMT
--
-- ralink_clk_add("cpu", cpu_rate);
-- ralink_clk_add("10000100.timer", periph_rate);
-- ralink_clk_add("10000120.watchdog", periph_rate);
-- ralink_clk_add("10000900.i2c", periph_rate);
-- ralink_clk_add("10000a00.i2s", pcmi2s_rate);
-- ralink_clk_add("10000b00.spi", sys_rate);
-- ralink_clk_add("10000b40.spi", sys_rate);
-- ralink_clk_add("10000c00.uartlite", periph_rate);
-- ralink_clk_add("10000d00.uart1", periph_rate);
-- ralink_clk_add("10000e00.uart2", periph_rate);
-- ralink_clk_add("10180000.wmac", xtal_rate);
--
-- if (IS_ENABLED(CONFIG_USB) && !is_mt76x8()) {
-- /*
-- * When the CPU goes into sleep mode, the BUS clock will be
-- * too low for USB to function properly. Adjust the busses
-- * fractional divider to fix this
-- */
-- u32 val = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG);
--
-- val &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK);
-- val |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL;
--
-- rt_sysc_w32(val, SYSC_REG_CPU_SYS_CLKCFG);
-- }
--}
--
- void __init ralink_of_remap(void)
- {
- rt_sysc_membase = plat_of_remap_node("ralink,mt7620a-sysc");
+++ /dev/null
-From 201ddc05777cd8e084b508bcdda22214bfe2895e Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 19 Jun 2023 06:09:39 +0200
-Subject: [PATCH 7/9] mips: ralink: remove reset related code
-
-A proper clock driver for ralink SoCs has been added. This driver is also
-a reset provider for the SoC. Hence there is no need to have reset related
-code in 'arch/mips/ralink' folder anymore. The only code that remains is
-the one related with mips_reboot_setup where a PCI reset is performed.
-We maintain this because I cannot test old ralink board with PCI to be
-sure all works if we remove also this code.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/ralink/common.h | 2 --
- arch/mips/ralink/of.c | 4 ----
- arch/mips/ralink/reset.c | 61 -----------------------------------------------
- 3 files changed, 67 deletions(-)
-
---- a/arch/mips/ralink/common.h
-+++ b/arch/mips/ralink/common.h
-@@ -23,8 +23,6 @@ extern struct ralink_soc_info soc_info;
-
- extern void ralink_of_remap(void);
-
--extern void ralink_rst_init(void);
--
- extern void __init prom_soc_init(struct ralink_soc_info *soc_info);
-
- __iomem void *plat_of_remap_node(const char *node);
---- a/arch/mips/ralink/of.c
-+++ b/arch/mips/ralink/of.c
-@@ -81,10 +81,6 @@ static int __init plat_of_setup(void)
- {
- __dt_register_buses(soc_info.compatible, "palmbus");
-
-- /* make sure that the reset controller is setup early */
-- if (ralink_soc != MT762X_SOC_MT7621AT)
-- ralink_rst_init();
--
- return 0;
- }
-
---- a/arch/mips/ralink/reset.c
-+++ b/arch/mips/ralink/reset.c
-@@ -10,7 +10,6 @@
- #include <linux/io.h>
- #include <linux/of.h>
- #include <linux/delay.h>
--#include <linux/reset-controller.h>
-
- #include <asm/reboot.h>
-
-@@ -22,66 +21,6 @@
- #define RSTCTL_RESET_PCI BIT(26)
- #define RSTCTL_RESET_SYSTEM BIT(0)
-
--static int ralink_assert_device(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- u32 val;
--
-- if (id == 0)
-- return -1;
--
-- val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
-- val |= BIT(id);
-- rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
--
-- return 0;
--}
--
--static int ralink_deassert_device(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- u32 val;
--
-- if (id == 0)
-- return -1;
--
-- val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
-- val &= ~BIT(id);
-- rt_sysc_w32(val, SYSC_REG_RESET_CTRL);
--
-- return 0;
--}
--
--static int ralink_reset_device(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- ralink_assert_device(rcdev, id);
-- return ralink_deassert_device(rcdev, id);
--}
--
--static const struct reset_control_ops reset_ops = {
-- .reset = ralink_reset_device,
-- .assert = ralink_assert_device,
-- .deassert = ralink_deassert_device,
--};
--
--static struct reset_controller_dev reset_dev = {
-- .ops = &reset_ops,
-- .owner = THIS_MODULE,
-- .nr_resets = 32,
-- .of_reset_n_cells = 1,
--};
--
--void ralink_rst_init(void)
--{
-- reset_dev.of_node = of_find_compatible_node(NULL, NULL,
-- "ralink,rt2880-reset");
-- if (!reset_dev.of_node)
-- pr_err("Failed to find reset controller node");
-- else
-- reset_controller_register(&reset_dev);
--}
--
- static void ralink_restart(char *command)
- {
- if (IS_ENABLED(CONFIG_PCI)) {
+++ /dev/null
-From ad38c17b0c26ae2108b50ac1eb0281a2e1ce08e9 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 19 Jun 2023 06:09:40 +0200
-Subject: [PATCH 8/9] mips: ralink: get cpu rate from new driver code
-
-At very early stage on boot, there is a need to set 'mips_hpt_frequency'.
-This timer frequency is a half of the CPU frequency. To get clocks properly
-set we need to call to 'of_clk_init()' and properly get cpu clock frequency
-afterwards. Depending on the SoC, CPU clock index and compatible differs, so
-use them to get the proper clock frm the clock provider. Hence, adapt code
-to be aligned with new clock driver.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/ralink/clk.c | 61 ++++++++++++++++++++++++++++++++++++++++++--------
- 1 file changed, 52 insertions(+), 9 deletions(-)
-
---- a/arch/mips/ralink/clk.c
-+++ b/arch/mips/ralink/clk.c
-@@ -11,29 +11,72 @@
- #include <linux/clkdev.h>
- #include <linux/clk.h>
- #include <linux/clk-provider.h>
-+#include <asm/mach-ralink/ralink_regs.h>
-
- #include <asm/time.h>
-
- #include "common.h"
-
--void ralink_clk_add(const char *dev, unsigned long rate)
-+static const char *clk_cpu(int *idx)
- {
-- struct clk *clk = clk_register_fixed_rate(NULL, dev, NULL, 0, rate);
--
-- if (!clk)
-- panic("failed to add clock");
--
-- clkdev_create(clk, NULL, "%s", dev);
-+ switch (ralink_soc) {
-+ case RT2880_SOC:
-+ *idx = 0;
-+ return "ralink,rt2880-sysc";
-+ case RT3883_SOC:
-+ *idx = 0;
-+ return "ralink,rt3883-sysc";
-+ case RT305X_SOC_RT3050:
-+ *idx = 0;
-+ return "ralink,rt3050-sysc";
-+ case RT305X_SOC_RT3052:
-+ *idx = 0;
-+ return "ralink,rt3052-sysc";
-+ case RT305X_SOC_RT3350:
-+ *idx = 1;
-+ return "ralink,rt3350-sysc";
-+ case RT305X_SOC_RT3352:
-+ *idx = 1;
-+ return "ralink,rt3352-sysc";
-+ case RT305X_SOC_RT5350:
-+ *idx = 1;
-+ return "ralink,rt5350-sysc";
-+ case MT762X_SOC_MT7620A:
-+ *idx = 2;
-+ return "ralink,mt7620-sysc";
-+ case MT762X_SOC_MT7620N:
-+ *idx = 2;
-+ return "ralink,mt7620-sysc";
-+ case MT762X_SOC_MT7628AN:
-+ *idx = 1;
-+ return "ralink,mt7628-sysc";
-+ case MT762X_SOC_MT7688:
-+ *idx = 1;
-+ return "ralink,mt7688-sysc";
-+ default:
-+ *idx = -1;
-+ return "invalid";
-+ }
- }
-
- void __init plat_time_init(void)
- {
-+ struct of_phandle_args clkspec;
-+ const char *compatible;
- struct clk *clk;
-+ int cpu_clk_idx;
-
- ralink_of_remap();
-
-- ralink_clk_init();
-- clk = clk_get_sys("cpu", NULL);
-+ compatible = clk_cpu(&cpu_clk_idx);
-+ if (cpu_clk_idx == -1)
-+ panic("unable to get CPU clock index");
-+
-+ of_clk_init(NULL);
-+ clkspec.np = of_find_compatible_node(NULL, NULL, compatible);
-+ clkspec.args_count = 1;
-+ clkspec.args[0] = cpu_clk_idx;
-+ clk = of_clk_get_from_provider(&clkspec);
- if (IS_ERR(clk))
- panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
- pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
+++ /dev/null
-From fc15a7193a4d37d79e873fa06cc423180ddd2ddf Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 19 Jun 2023 06:09:41 +0200
-Subject: [PATCH 9/9] MAINTAINERS: add Mediatek MTMIPS Clock maintainer
-
-Adding myself as maintainer for Mediatek MTMIPS clock driver.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- MAINTAINERS | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -13021,6 +13021,12 @@ S: Maintained
- F: Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml
- F: drivers/clk/ralink/clk-mt7621.c
-
-+MEDIATEK MTMIPS CLOCK DRIVER
-+M: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-+S: Maintained
-+F: Documentation/devicetree/bindings/clock/mediatek,mtmips-sysc.yaml
-+F: drivers/clk/ralink/clk-mtmips.c
-+
- MEDIATEK MT7621/28/88 I2C DRIVER
- M: Stefan Roese <sr@denx.de>
- L: linux-i2c@vger.kernel.org
+++ /dev/null
-From fd99ac5055d4705e91c73d1adba18bc71c8511a8 Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Tue, 20 Jun 2023 19:44:32 +0800
-Subject: [PATCH] mips: ralink: introduce commonly used remap node function
-
-The ralink_of_remap() function is repeated several times on SoC specific
-source files. They have the same structure, but just differ in compatible
-strings. In order to make commonly use of these codes, this patch
-introduces a newly designed mtmips_of_remap_node() function to match and
-remap all supported system controller and memory controller nodes.
-
-Build and run tested on MT7620 and MT7628.
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/ralink/common.h | 2 --
- arch/mips/ralink/mt7620.c | 9 ---------
- arch/mips/ralink/mt7621.c | 9 ---------
- arch/mips/ralink/of.c | 42 +++++++++++++++++++++++++++++++++++-------
- arch/mips/ralink/rt288x.c | 9 ---------
- arch/mips/ralink/rt305x.c | 9 ---------
- arch/mips/ralink/rt3883.c | 9 ---------
- 7 files changed, 35 insertions(+), 54 deletions(-)
-
---- a/arch/mips/ralink/common.h
-+++ b/arch/mips/ralink/common.h
-@@ -25,6 +25,4 @@ extern void ralink_of_remap(void);
-
- extern void __init prom_soc_init(struct ralink_soc_info *soc_info);
-
--__iomem void *plat_of_remap_node(const char *node);
--
- #endif /* _RALINK_COMMON_H__ */
---- a/arch/mips/ralink/mt7620.c
-+++ b/arch/mips/ralink/mt7620.c
-@@ -43,15 +43,6 @@
- /* does the board have sdram or ddram */
- static int dram_type;
-
--void __init ralink_of_remap(void)
--{
-- rt_sysc_membase = plat_of_remap_node("ralink,mt7620a-sysc");
-- rt_memc_membase = plat_of_remap_node("ralink,mt7620a-memc");
--
-- if (!rt_sysc_membase || !rt_memc_membase)
-- panic("Failed to remap core resources");
--}
--
- static __init void
- mt7620_dram_init(struct ralink_soc_info *soc_info)
- {
---- a/arch/mips/ralink/mt7621.c
-+++ b/arch/mips/ralink/mt7621.c
-@@ -89,15 +89,6 @@ static void __init mt7621_memory_detect(
- memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
- }
-
--void __init ralink_of_remap(void)
--{
-- rt_sysc_membase = plat_of_remap_node("mediatek,mt7621-sysc");
-- rt_memc_membase = plat_of_remap_node("mediatek,mt7621-memc");
--
-- if (!rt_sysc_membase || !rt_memc_membase)
-- panic("Failed to remap core resources");
--}
--
- static unsigned int __init mt7621_get_soc_name0(void)
- {
- return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME0);
---- a/arch/mips/ralink/of.c
-+++ b/arch/mips/ralink/of.c
-@@ -29,28 +29,56 @@ __iomem void *rt_sysc_membase;
- __iomem void *rt_memc_membase;
- EXPORT_SYMBOL_GPL(rt_sysc_membase);
-
--__iomem void *plat_of_remap_node(const char *node)
-+static const struct of_device_id mtmips_memc_match[] = {
-+ { .compatible = "mediatek,mt7621-memc" },
-+ { .compatible = "ralink,mt7620a-memc" },
-+ { .compatible = "ralink,rt2880-memc" },
-+ { .compatible = "ralink,rt3050-memc" },
-+ { .compatible = "ralink,rt3883-memc" },
-+ {}
-+};
-+
-+static const struct of_device_id mtmips_sysc_match[] = {
-+ { .compatible = "mediatek,mt7621-sysc" },
-+ { .compatible = "ralink,mt7620a-sysc" },
-+ { .compatible = "ralink,rt2880-sysc" },
-+ { .compatible = "ralink,rt3050-sysc" },
-+ { .compatible = "ralink,rt3883-sysc" },
-+ {}
-+};
-+
-+static __iomem void *
-+mtmips_of_remap_node(const struct of_device_id *match, const char *type)
- {
- struct resource res;
- struct device_node *np;
-
-- np = of_find_compatible_node(NULL, NULL, node);
-+ np = of_find_matching_node(NULL, match);
- if (!np)
-- panic("Failed to find %s node", node);
-+ panic("Failed to find %s controller node", type);
-
- if (of_address_to_resource(np, 0, &res))
-- panic("Failed to get resource for %s", node);
--
-- of_node_put(np);
-+ panic("Failed to get resource for %s node", np->name);
-
- if (!request_mem_region(res.start,
- resource_size(&res),
- res.name))
-- panic("Failed to request resources for %s", node);
-+ panic("Failed to request resources for %s node", np->name);
-+
-+ of_node_put(np);
-
- return ioremap(res.start, resource_size(&res));
- }
-
-+void __init ralink_of_remap(void)
-+{
-+ rt_sysc_membase = mtmips_of_remap_node(mtmips_sysc_match, "system");
-+ rt_memc_membase = mtmips_of_remap_node(mtmips_memc_match, "memory");
-+
-+ if (!rt_sysc_membase || !rt_memc_membase)
-+ panic("Failed to remap core resources");
-+}
-+
- void __init plat_mem_setup(void)
- {
- void *dtb;
---- a/arch/mips/ralink/rt288x.c
-+++ b/arch/mips/ralink/rt288x.c
-@@ -17,15 +17,6 @@
-
- #include "common.h"
-
--void __init ralink_of_remap(void)
--{
-- rt_sysc_membase = plat_of_remap_node("ralink,rt2880-sysc");
-- rt_memc_membase = plat_of_remap_node("ralink,rt2880-memc");
--
-- if (!rt_sysc_membase || !rt_memc_membase)
-- panic("Failed to remap core resources");
--}
--
- void __init prom_soc_init(struct ralink_soc_info *soc_info)
- {
- void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT2880_SYSC_BASE);
---- a/arch/mips/ralink/rt305x.c
-+++ b/arch/mips/ralink/rt305x.c
-@@ -53,15 +53,6 @@ static unsigned long rt5350_get_mem_size
- return ret;
- }
-
--void __init ralink_of_remap(void)
--{
-- rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc");
-- rt_memc_membase = plat_of_remap_node("ralink,rt3050-memc");
--
-- if (!rt_sysc_membase || !rt_memc_membase)
-- panic("Failed to remap core resources");
--}
--
- void __init prom_soc_init(struct ralink_soc_info *soc_info)
- {
- void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
---- a/arch/mips/ralink/rt3883.c
-+++ b/arch/mips/ralink/rt3883.c
-@@ -17,15 +17,6 @@
-
- #include "common.h"
-
--void __init ralink_of_remap(void)
--{
-- rt_sysc_membase = plat_of_remap_node("ralink,rt3883-sysc");
-- rt_memc_membase = plat_of_remap_node("ralink,rt3883-memc");
--
-- if (!rt_sysc_membase || !rt_memc_membase)
-- panic("Failed to remap core resources");
--}
--
- void __init prom_soc_init(struct ralink_soc_info *soc_info)
- {
- void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT3883_SYSC_BASE);
+++ /dev/null
-From 6e68dae946e3a0333fbde5487ce163142ca10ae0 Mon Sep 17 00:00:00 2001
-From: Nathan Chancellor <nathan@kernel.org>
-Date: Thu, 22 Jun 2023 15:56:19 +0000
-Subject: clk: ralink: mtmips: Fix uninitialized use of ret in
- mtmips_register_{fixed,factor}_clocks()
-
-Clang warns:
-
- drivers/clk/ralink/clk-mtmips.c:309:9: error: variable 'ret' is uninitialized when used here [-Werror,-Wuninitialized]
- 309 | return ret;
- | ^~~
- drivers/clk/ralink/clk-mtmips.c:285:9: note: initialize the variable 'ret' to silence this warning
- 285 | int ret, i;
- | ^
- | = 0
- drivers/clk/ralink/clk-mtmips.c:359:9: error: variable 'ret' is uninitialized when used here [-Werror,-Wuninitialized]
- 359 | return ret;
- | ^~~
- drivers/clk/ralink/clk-mtmips.c:335:9: note: initialize the variable 'ret' to silence this warning
- 335 | int ret, i;
- | ^
- | = 0
- 2 errors generated.
-
-Set ret to the return value of clk_hw_register_fixed_rate() using the
-PTR_ERR() macro, which ensures ret is not used uninitialized, clearing
-up the warning.
-
-Fixes: 6f3b15586eef ("clk: ralink: add clock and reset driver for MTMIPS SoCs")
-Closes: https://github.com/ClangBuiltLinux/linux/issues/1879
-Signed-off-by: Nathan Chancellor <nathan@kernel.org>
-Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
-Acked-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- drivers/clk/ralink/clk-mtmips.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/clk/ralink/clk-mtmips.c
-+++ b/drivers/clk/ralink/clk-mtmips.c
-@@ -292,6 +292,7 @@ static int mtmips_register_fixed_clocks(
- sclk->parent, 0,
- sclk->rate);
- if (IS_ERR(sclk->hw)) {
-+ ret = PTR_ERR(sclk->hw);
- pr_err("Couldn't register fixed clock %d\n", idx);
- goto err_clk_unreg;
- }
-@@ -342,6 +343,7 @@ static int mtmips_register_factor_clocks
- sclk->parent, sclk->flags,
- sclk->mult, sclk->div);
- if (IS_ERR(sclk->hw)) {
-+ ret = PTR_ERR(sclk->hw);
- pr_err("Couldn't register factor clock %d\n", idx);
- goto err_clk_unreg;
- }
+++ /dev/null
-From 670f77f76f650b1b341d31d009cc2fb03a4d1fcf Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Fri, 23 Jun 2023 08:17:48 +0800
-Subject: mips: ralink: match all supported system controller compatible
- strings
-
-Recently, A new clock and reset controller driver has been introduced to
-the ralink mips target[1]. It provides proper system control and adds more
-SoC specific compatible strings. In order to better initialize CPUs, this
-patch removes the outdated "ralink,mt7620a-sysc" and add all dt-binding
-documented compatible strings to the system controller match table.
-
-[1] https://lore.kernel.org/all/20230619040941.1340372-1-sergio.paracuellos@gmail.com/
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/ralink/of.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/arch/mips/ralink/of.c
-+++ b/arch/mips/ralink/of.c
-@@ -40,10 +40,15 @@ static const struct of_device_id mtmips_
-
- static const struct of_device_id mtmips_sysc_match[] = {
- { .compatible = "mediatek,mt7621-sysc" },
-- { .compatible = "ralink,mt7620a-sysc" },
-+ { .compatible = "ralink,mt7620-sysc" },
-+ { .compatible = "ralink,mt7628-sysc" },
-+ { .compatible = "ralink,mt7688-sysc" },
- { .compatible = "ralink,rt2880-sysc" },
- { .compatible = "ralink,rt3050-sysc" },
-+ { .compatible = "ralink,rt3052-sysc" },
-+ { .compatible = "ralink,rt3352-sysc" },
- { .compatible = "ralink,rt3883-sysc" },
-+ { .compatible = "ralink,rt5350-sysc" },
- {}
- };
-
+++ /dev/null
-From 783c7cb4659b53b5e1b809dac5e8cdf250145919 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Tue, 14 Feb 2023 11:39:35 +0100
-Subject: [PATCH 1/2] watchdog: mt7621-wdt: avoid static global declarations
-
-Instead of using static global definitions in driver code, refactor code
-introducing a new watchdog driver data structure and use it along the
-code.
-
-Reviewed-by: Guenter Roeck <linux@roeck-us.net>
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20230214103936.1061078-5-sergio.paracuellos@gmail.com
-[groeck: unsigned -> unsigned int]
-Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
----
- drivers/watchdog/mt7621_wdt.c | 102 +++++++++++++++++++++++++++---------------
- 1 file changed, 65 insertions(+), 37 deletions(-)
-
---- a/drivers/watchdog/mt7621_wdt.c
-+++ b/drivers/watchdog/mt7621_wdt.c
-@@ -31,8 +31,11 @@
- #define TMR1CTL_RESTART BIT(9)
- #define TMR1CTL_PRESCALE_SHIFT 16
-
--static void __iomem *mt7621_wdt_base;
--static struct reset_control *mt7621_wdt_reset;
-+struct mt7621_wdt_data {
-+ void __iomem *base;
-+ struct reset_control *rst;
-+ struct watchdog_device wdt;
-+};
-
- static bool nowayout = WATCHDOG_NOWAYOUT;
- module_param(nowayout, bool, 0);
-@@ -40,27 +43,31 @@ MODULE_PARM_DESC(nowayout,
- "Watchdog cannot be stopped once started (default="
- __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-
--static inline void rt_wdt_w32(unsigned reg, u32 val)
-+static inline void rt_wdt_w32(void __iomem *base, unsigned int reg, u32 val)
- {
-- iowrite32(val, mt7621_wdt_base + reg);
-+ iowrite32(val, base + reg);
- }
-
--static inline u32 rt_wdt_r32(unsigned reg)
-+static inline u32 rt_wdt_r32(void __iomem *base, unsigned int reg)
- {
-- return ioread32(mt7621_wdt_base + reg);
-+ return ioread32(base + reg);
- }
-
- static int mt7621_wdt_ping(struct watchdog_device *w)
- {
-- rt_wdt_w32(TIMER_REG_TMRSTAT, TMR1CTL_RESTART);
-+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
-+
-+ rt_wdt_w32(drvdata->base, TIMER_REG_TMRSTAT, TMR1CTL_RESTART);
-
- return 0;
- }
-
- static int mt7621_wdt_set_timeout(struct watchdog_device *w, unsigned int t)
- {
-+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
-+
- w->timeout = t;
-- rt_wdt_w32(TIMER_REG_TMR1LOAD, t * 1000);
-+ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1LOAD, t * 1000);
- mt7621_wdt_ping(w);
-
- return 0;
-@@ -68,29 +75,31 @@ static int mt7621_wdt_set_timeout(struct
-
- static int mt7621_wdt_start(struct watchdog_device *w)
- {
-+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
- u32 t;
-
- /* set the prescaler to 1ms == 1000us */
-- rt_wdt_w32(TIMER_REG_TMR1CTL, 1000 << TMR1CTL_PRESCALE_SHIFT);
-+ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, 1000 << TMR1CTL_PRESCALE_SHIFT);
-
- mt7621_wdt_set_timeout(w, w->timeout);
-
-- t = rt_wdt_r32(TIMER_REG_TMR1CTL);
-+ t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL);
- t |= TMR1CTL_ENABLE;
-- rt_wdt_w32(TIMER_REG_TMR1CTL, t);
-+ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t);
-
- return 0;
- }
-
- static int mt7621_wdt_stop(struct watchdog_device *w)
- {
-+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
- u32 t;
-
- mt7621_wdt_ping(w);
-
-- t = rt_wdt_r32(TIMER_REG_TMR1CTL);
-+ t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL);
- t &= ~TMR1CTL_ENABLE;
-- rt_wdt_w32(TIMER_REG_TMR1CTL, t);
-+ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t);
-
- return 0;
- }
-@@ -105,7 +114,9 @@ static int mt7621_wdt_bootcause(void)
-
- static int mt7621_wdt_is_running(struct watchdog_device *w)
- {
-- return !!(rt_wdt_r32(TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE);
-+ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w);
-+
-+ return !!(rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE);
- }
-
- static const struct watchdog_info mt7621_wdt_info = {
-@@ -121,30 +132,39 @@ static const struct watchdog_ops mt7621_
- .set_timeout = mt7621_wdt_set_timeout,
- };
-
--static struct watchdog_device mt7621_wdt_dev = {
-- .info = &mt7621_wdt_info,
-- .ops = &mt7621_wdt_ops,
-- .min_timeout = 1,
-- .max_timeout = 0xfffful / 1000,
--};
--
- static int mt7621_wdt_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-- mt7621_wdt_base = devm_platform_ioremap_resource(pdev, 0);
-- if (IS_ERR(mt7621_wdt_base))
-- return PTR_ERR(mt7621_wdt_base);
--
-- mt7621_wdt_reset = devm_reset_control_get_exclusive(dev, NULL);
-- if (!IS_ERR(mt7621_wdt_reset))
-- reset_control_deassert(mt7621_wdt_reset);
--
-- mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause();
--
-- watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout,
-- dev);
-- watchdog_set_nowayout(&mt7621_wdt_dev, nowayout);
-- if (mt7621_wdt_is_running(&mt7621_wdt_dev)) {
-+ struct watchdog_device *mt7621_wdt;
-+ struct mt7621_wdt_data *drvdata;
-+ int err;
-+
-+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
-+ if (!drvdata)
-+ return -ENOMEM;
-+
-+ drvdata->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(drvdata->base))
-+ return PTR_ERR(drvdata->base);
-+
-+ drvdata->rst = devm_reset_control_get_exclusive(dev, NULL);
-+ if (!IS_ERR(drvdata->rst))
-+ reset_control_deassert(drvdata->rst);
-+
-+ mt7621_wdt = &drvdata->wdt;
-+ mt7621_wdt->info = &mt7621_wdt_info;
-+ mt7621_wdt->ops = &mt7621_wdt_ops;
-+ mt7621_wdt->min_timeout = 1;
-+ mt7621_wdt->max_timeout = 0xfffful / 1000;
-+ mt7621_wdt->parent = dev;
-+
-+ mt7621_wdt->bootstatus = mt7621_wdt_bootcause();
-+
-+ watchdog_init_timeout(mt7621_wdt, mt7621_wdt->max_timeout, dev);
-+ watchdog_set_nowayout(mt7621_wdt, nowayout);
-+ watchdog_set_drvdata(mt7621_wdt, drvdata);
-+
-+ if (mt7621_wdt_is_running(mt7621_wdt)) {
- /*
- * Make sure to apply timeout from watchdog core, taking
- * the prescaler of this driver here into account (the
-@@ -154,17 +174,25 @@ static int mt7621_wdt_probe(struct platf
- * we first disable the watchdog, set the new prescaler
- * and timeout, and then re-enable the watchdog.
- */
-- mt7621_wdt_stop(&mt7621_wdt_dev);
-- mt7621_wdt_start(&mt7621_wdt_dev);
-- set_bit(WDOG_HW_RUNNING, &mt7621_wdt_dev.status);
-+ mt7621_wdt_stop(mt7621_wdt);
-+ mt7621_wdt_start(mt7621_wdt);
-+ set_bit(WDOG_HW_RUNNING, &mt7621_wdt->status);
- }
-
-- return devm_watchdog_register_device(dev, &mt7621_wdt_dev);
-+ err = devm_watchdog_register_device(dev, &drvdata->wdt);
-+ if (err)
-+ return err;
-+
-+ platform_set_drvdata(pdev, drvdata);
-+
-+ return 0;
- }
-
- static void mt7621_wdt_shutdown(struct platform_device *pdev)
- {
-- mt7621_wdt_stop(&mt7621_wdt_dev);
-+ struct mt7621_wdt_data *drvdata = platform_get_drvdata(pdev);
-+
-+ mt7621_wdt_stop(&drvdata->wdt);
- }
-
- static const struct of_device_id mt7621_wdt_match[] = {
+++ /dev/null
-From ff8ec4ac39ad413b580d611dbf68e1d8a82eba56 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Tue, 14 Feb 2023 11:39:36 +0100
-Subject: [PATCH 2/2] watchdog: mt7621-wdt: avoid ralink architecture dependent code
-
-MT7621 SoC has a system controller node. Watchdog need to access to reset
-status register. Ralink architecture and related driver are old and from
-the beggining they are using some architecture dependent operations for
-accessing this shared registers through 'asm/mach-ralink/ralink_regs.h'
-header file. However this is not ideal from a driver perspective which can
-just access to the system controller registers in an arch independent way
-using regmap syscon APIs. Update Kconfig accordingly to select new added
-dependencies and allow driver to be compile tested.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Reviewed-by: Guenter Roeck <linux@roeck-us.net>
-Link: https://lore.kernel.org/r/20230214103936.1061078-6-sergio.paracuellos@gmail.com
-Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
----
- drivers/watchdog/Kconfig | 4 +++-
- drivers/watchdog/mt7621_wdt.c | 22 +++++++++++++++++-----
- 2 files changed, 20 insertions(+), 6 deletions(-)
-
---- a/drivers/watchdog/Kconfig
-+++ b/drivers/watchdog/Kconfig
-@@ -1865,7 +1865,9 @@ config GXP_WATCHDOG
- config MT7621_WDT
- tristate "Mediatek SoC watchdog"
- select WATCHDOG_CORE
-- depends on SOC_MT7620 || SOC_MT7621
-+ select REGMAP_MMIO
-+ select MFD_SYSCON
-+ depends on SOC_MT7620 || SOC_MT7621 || COMPILE_TEST
- help
- Hardware driver for the Mediatek/Ralink MT7621/8 SoC Watchdog Timer.
-
---- a/drivers/watchdog/mt7621_wdt.c
-+++ b/drivers/watchdog/mt7621_wdt.c
-@@ -15,8 +15,8 @@
- #include <linux/moduleparam.h>
- #include <linux/platform_device.h>
- #include <linux/mod_devicetable.h>
--
--#include <asm/mach-ralink/ralink_regs.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/regmap.h>
-
- #define SYSC_RSTSTAT 0x38
- #define WDT_RST_CAUSE BIT(1)
-@@ -34,6 +34,7 @@
- struct mt7621_wdt_data {
- void __iomem *base;
- struct reset_control *rst;
-+ struct regmap *sysc;
- struct watchdog_device wdt;
- };
-
-@@ -104,9 +105,12 @@ static int mt7621_wdt_stop(struct watchd
- return 0;
- }
-
--static int mt7621_wdt_bootcause(void)
-+static int mt7621_wdt_bootcause(struct mt7621_wdt_data *d)
- {
-- if (rt_sysc_r32(SYSC_RSTSTAT) & WDT_RST_CAUSE)
-+ u32 val;
-+
-+ regmap_read(d->sysc, SYSC_RSTSTAT, &val);
-+ if (val & WDT_RST_CAUSE)
- return WDIOF_CARDRESET;
-
- return 0;
-@@ -134,6 +138,7 @@ static const struct watchdog_ops mt7621_
-
- static int mt7621_wdt_probe(struct platform_device *pdev)
- {
-+ struct device_node *np = pdev->dev.of_node;
- struct device *dev = &pdev->dev;
- struct watchdog_device *mt7621_wdt;
- struct mt7621_wdt_data *drvdata;
-@@ -143,6 +148,13 @@ static int mt7621_wdt_probe(struct platf
- if (!drvdata)
- return -ENOMEM;
-
-+ drvdata->sysc = syscon_regmap_lookup_by_phandle(np, "mediatek,sysctl");
-+ if (IS_ERR(drvdata->sysc)) {
-+ drvdata->sysc = syscon_regmap_lookup_by_compatible("mediatek,mt7621-sysc");
-+ if (IS_ERR(drvdata->sysc))
-+ return PTR_ERR(drvdata->sysc);
-+ }
-+
- drvdata->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(drvdata->base))
- return PTR_ERR(drvdata->base);
-@@ -158,7 +170,7 @@ static int mt7621_wdt_probe(struct platf
- mt7621_wdt->max_timeout = 0xfffful / 1000;
- mt7621_wdt->parent = dev;
-
-- mt7621_wdt->bootstatus = mt7621_wdt_bootcause();
-+ mt7621_wdt->bootstatus = mt7621_wdt_bootcause(drvdata);
-
- watchdog_init_timeout(mt7621_wdt, mt7621_wdt->max_timeout, dev);
- watchdog_set_nowayout(mt7621_wdt, nowayout);
+++ /dev/null
-From 9f9a035e6156a57d9da062b26d2a48d031744a1e Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Tue, 20 Jun 2023 18:43:22 +0800
-Subject: [PATCH 1/2] mips: pci-mt7620: do not print NFTS register value as
- error log
-
-These codes are used to read NFTS_TIMEOUT_DELAY register value and
-write it into kernel log after writing the register. they are only
-used for debugging during driver development, so there is no need
-to keep them now.
-
-Tested on MT7628AN router Motorola MWR03.
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/pci/pci-mt7620.c | 3 ---
- 1 file changed, 3 deletions(-)
-
---- a/arch/mips/pci/pci-mt7620.c
-+++ b/arch/mips/pci/pci-mt7620.c
-@@ -274,9 +274,6 @@ static int mt7628_pci_hw_init(struct pla
- val |= 0x50 << 8;
- pci_config_write(NULL, 0, 0x70c, 4, val);
-
-- pci_config_read(NULL, 0, 0x70c, 4, &val);
-- dev_err(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val);
--
- return 0;
- }
-
+++ /dev/null
-From 89ec9bbe60b61cc6ae3eddd6d4f43e128f8a88de Mon Sep 17 00:00:00 2001
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Tue, 20 Jun 2023 18:43:23 +0800
-Subject: [PATCH 2/2] mips: pci-mt7620: use dev_info() to log PCIe device
- detection result
-
-Usually, We only need to print the error log when there is a PCIe card but
-initialization fails. Whether the driver finds the PCIe card or not is the
-expected behavior. So it's better to log these information with dev_info().
-
-Tested on MT7628AN router Motorola MWR03.
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
-Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/pci/pci-mt7620.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/mips/pci/pci-mt7620.c
-+++ b/arch/mips/pci/pci-mt7620.c
-@@ -331,7 +331,7 @@ static int mt7620_pci_probe(struct platf
- rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
- if (ralink_soc == MT762X_SOC_MT7620A)
- rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
-- dev_err(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
-+ dev_info(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
- return -1;
- }
-
-@@ -374,7 +374,7 @@ int pcibios_map_irq(const struct pci_dev
- dev->bus->number, slot);
- return 0;
- }
-- dev_err(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n",
-+ dev_info(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n",
- dev->bus->number, slot, irq);
-
- /* configure the cache line size to 0x14 */
+++ /dev/null
-From 50233e105a0332ec0f3bc83180c416e6b200471e Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 24 Mar 2023 08:37:33 +0100
-Subject: PCI: mt7621: Use dev_info() to log PCIe card detection
-
-When there is no card plugged on a PCIe port a log reporting that
-the port will be disabled is flagged as an error (dev_err()).
-
-Since this is not an error at all, change the log level by using
-dev_info() instead.
-
-Link: https://lore.kernel.org/r/20230324073733.1596231-1-sergio.paracuellos@gmail.com
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
----
- drivers/pci/controller/pcie-mt7621.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/pci/controller/pcie-mt7621.c
-+++ b/drivers/pci/controller/pcie-mt7621.c
-@@ -378,8 +378,8 @@ static int mt7621_pcie_init_ports(struct
- u32 slot = port->slot;
-
- if (!mt7621_pcie_port_is_linkup(port)) {
-- dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n",
-- slot);
-+ dev_info(dev, "pcie%d no card, disable it (RST & CLK)\n",
-+ slot);
- mt7621_control_assert(port);
- port->enabled = false;
- num_disabled++;
+++ /dev/null
---- a/drivers/net/ethernet/Kconfig
-+++ b/drivers/net/ethernet/Kconfig
-@@ -166,6 +166,7 @@ source "drivers/net/ethernet/pensando/Kc
- source "drivers/net/ethernet/qlogic/Kconfig"
- source "drivers/net/ethernet/brocade/Kconfig"
- source "drivers/net/ethernet/qualcomm/Kconfig"
-+source "drivers/net/ethernet/ralink/Kconfig"
- source "drivers/net/ethernet/rdc/Kconfig"
- source "drivers/net/ethernet/realtek/Kconfig"
- source "drivers/net/ethernet/renesas/Kconfig"
---- a/drivers/net/ethernet/Makefile
-+++ b/drivers/net/ethernet/Makefile
-@@ -77,6 +77,7 @@ obj-$(CONFIG_NET_VENDOR_PACKET_ENGINES)
- obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
- obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
- obj-$(CONFIG_NET_VENDOR_QUALCOMM) += qualcomm/
-+obj-$(CONFIG_NET_VENDOR_RALINK) += ralink/
- obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
- obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/
- obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
+++ /dev/null
---- a/arch/mips/include/asm/mach-ralink/mt7620.h
-+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
-@@ -61,4 +61,16 @@ static inline int mt7620_get_eco(void)
- return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK;
- }
-
-+static inline int mt7620_get_chipver(void)
-+{
-+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_VER_SHIFT) &
-+ CHIP_REV_VER_MASK;
-+}
-+
-+static inline int mt7620_get_pkg(void)
-+{
-+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_PKG_SHIFT) &
-+ CHIP_REV_PKG_MASK;
-+}
-+
- #endif
+++ /dev/null
-From ce3d4a4111a5f7e6b4e74bceae5faa6ce388e8ec Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 14 Jul 2013 23:08:11 +0200
-Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k
- irq
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/ralink/Kconfig | 5 +++++
- 1 file changed, 5 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 @@
- #include <asm/time.h>
- #include <asm/cevt-r4k.h>
-
-+#ifdef CONFIG_CEVT_SYSTICK_QUIRK
-+static int mips_state_oneshot(struct clock_event_device *evt)
-+{
-+ unsigned long flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED;
-+ if (!cp0_timer_irq_installed) {
-+ cp0_timer_irq_installed = 1;
-+ if (request_irq(evt->irq, c0_compare_interrupt, flags, "timer",
-+ c0_compare_interrupt))
-+ pr_err("Failed to request irq %d (timer)\n", evt->irq);
-+ }
-+
-+ return 0;
-+}
-+
-+static int mips_state_shutdown(struct clock_event_device *evt)
-+{
-+ if (cp0_timer_irq_installed) {
-+ cp0_timer_irq_installed = 0;
-+ free_irq(evt->irq, NULL);
-+ }
-+
-+ return 0;
-+}
-+#endif
-+
- static int mips_next_event(unsigned long delta,
- struct clock_event_device *evt)
- {
-@@ -292,7 +317,9 @@ core_initcall(r4k_register_cpufreq_notif
-
- int r4k_clockevent_init(void)
- {
-+#ifndef CONFIG_CEVT_SYSTICK_QUIRK
- unsigned long flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED;
-+#endif
- 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)
- cd->rating = 300;
- cd->irq = irq;
- cd->cpumask = cpumask_of(cpu);
-+#ifdef CONFIG_CEVT_SYSTICK_QUIRK
-+ cd->set_state_shutdown = mips_state_shutdown;
-+ cd->set_state_oneshot = mips_state_oneshot;
-+#endif
- cd->set_next_event = mips_next_event;
- cd->event_handler = mips_event_handler;
-
- clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff);
-
-+#ifndef CONFIG_CEVT_SYSTICK_QUIRK
- if (cp0_timer_irq_installed)
- return 0;
-
-@@ -335,6 +367,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);
-+#endif
-
- return 0;
- }
+++ /dev/null
-From bd30f19a006fb52bac80c6463c49dd2f4159f4ac Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 28 Jul 2013 16:26:41 +0200
-Subject: [PATCH 06/53] MIPS: ralink: add cpu frequency scaling
-
-This feature will break udelay() and cause the delay loop to have longer delays
-when the frequency is scaled causing a performance hit.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/ralink/cevt-rt3352.c | 38 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/arch/mips/ralink/cevt-rt3352.c
-+++ b/arch/mips/ralink/cevt-rt3352.c
-@@ -29,6 +29,10 @@
- /* enable the counter */
- #define CFG_CNT_EN 0x1
-
-+/* mt7620 frequency scaling defines */
-+#define CLK_LUT_CFG 0x40
-+#define SLEEP_EN BIT(31)
-+
- struct systick_device {
- void __iomem *membase;
- struct clock_event_device dev;
-@@ -36,21 +40,53 @@ struct systick_device {
- int freq_scale;
- };
-
-+static void (*systick_freq_scaling)(struct systick_device *sdev, int status);
-+
- static int systick_set_oneshot(struct clock_event_device *evt);
- static int systick_shutdown(struct clock_event_device *evt);
-
-+static inline void mt7620_freq_scaling(struct systick_device *sdev, int status)
-+{
-+ if (sdev->freq_scale == status)
-+ return;
-+
-+ sdev->freq_scale = status;
-+
-+ pr_info("%s: %s autosleep mode\n", sdev->dev.name,
-+ (status) ? ("enable") : ("disable"));
-+ if (status)
-+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) | SLEEP_EN, CLK_LUT_CFG);
-+ else
-+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) & ~SLEEP_EN, CLK_LUT_CFG);
-+}
-+
-+static inline unsigned int read_count(struct systick_device *sdev)
-+{
-+ return ioread32(sdev->membase + SYSTICK_COUNT);
-+}
-+
-+static inline unsigned int read_compare(struct systick_device *sdev)
-+{
-+ return ioread32(sdev->membase + SYSTICK_COMPARE);
-+}
-+
-+static inline void write_compare(struct systick_device *sdev, unsigned int val)
-+{
-+ iowrite32(val, sdev->membase + SYSTICK_COMPARE);
-+}
-+
- static int systick_next_event(unsigned long delta,
- struct clock_event_device *evt)
- {
- struct systick_device *sdev;
-- u32 count;
-+ int res;
-
- sdev = container_of(evt, struct systick_device, dev);
-- count = ioread32(sdev->membase + SYSTICK_COUNT);
-- count = (count + delta) % SYSTICK_FREQ;
-- iowrite32(count, sdev->membase + SYSTICK_COMPARE);
-+ delta += read_count(sdev);
-+ write_compare(sdev, delta);
-+ res = ((int)(read_count(sdev) - delta) >= 0) ? -ETIME : 0;
-
-- return 0;
-+ return res;
- }
-
- static void systick_event_handler(struct clock_event_device *dev)
-@@ -60,20 +96,25 @@ static void systick_event_handler(struct
-
- static irqreturn_t systick_interrupt(int irq, void *dev_id)
- {
-- struct clock_event_device *dev = (struct clock_event_device *) dev_id;
-+ int ret = 0;
-+ struct clock_event_device *cdev;
-+ struct systick_device *sdev;
-
-- dev->event_handler(dev);
-+ if (read_c0_cause() & STATUSF_IP7) {
-+ cdev = (struct clock_event_device *) dev_id;
-+ sdev = container_of(cdev, struct systick_device, dev);
-+
-+ /* Clear Count/Compare Interrupt */
-+ write_compare(sdev, read_compare(sdev));
-+ cdev->event_handler(cdev);
-+ ret = 1;
-+ }
-
-- return IRQ_HANDLED;
-+ return IRQ_RETVAL(ret);
- }
-
- static struct systick_device systick = {
- .dev = {
-- /*
-- * cevt-r4k uses 300, make sure systick
-- * gets used if available
-- */
-- .rating = 310,
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .set_next_event = systick_next_event,
- .set_state_shutdown = systick_shutdown,
-@@ -91,7 +132,13 @@ static int systick_shutdown(struct clock
- if (sdev->irq_requested)
- free_irq(systick.dev.irq, &systick.dev);
- sdev->irq_requested = 0;
-- iowrite32(0, systick.membase + SYSTICK_CONFIG);
-+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
-+
-+ if (systick_freq_scaling)
-+ systick_freq_scaling(sdev, 0);
-+
-+ if (systick_freq_scaling)
-+ systick_freq_scaling(sdev, 1);
-
- return 0;
- }
-@@ -116,33 +163,46 @@ static int systick_set_oneshot(struct cl
- return 0;
- }
-
-+static const struct of_device_id systick_match[] = {
-+ { .compatible = "ralink,mt7620a-systick", .data = mt7620_freq_scaling},
-+ {},
-+};
-+
- static int __init ralink_systick_init(struct device_node *np)
- {
-- int ret;
-+ const struct of_device_id *match;
-+ int rating = 200;
-
- systick.membase = of_iomap(np, 0);
- if (!systick.membase)
- return -ENXIO;
-
-- systick.dev.name = np->name;
-- clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
-- systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
-- systick.dev.max_delta_ticks = 0x7fff;
-- systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
-- systick.dev.min_delta_ticks = 0x3;
-+ match = of_match_node(systick_match, np);
-+ if (match) {
-+ systick_freq_scaling = match->data;
-+ /*
-+ * cevt-r4k uses 300, make sure systick
-+ * gets used if available
-+ */
-+ rating = 310;
-+ }
-+
-+ /* enable counter than register clock source */
-+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
-+ clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
-+ SYSTICK_FREQ, rating, 16, clocksource_mmio_readl_up);
-+
-+ /* register clock event */
- systick.dev.irq = irq_of_parse_and_map(np, 0);
- if (!systick.dev.irq) {
- pr_err("%pOFn: request_irq failed", np);
- return -EINVAL;
- }
-
-- ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
-- SYSTICK_FREQ, 301, 16,
-- clocksource_mmio_readl_up);
-- if (ret)
-- return ret;
--
-- clockevents_register_device(&systick.dev);
-+ systick.dev.name = np->name;
-+ systick.dev.rating = rating;
-+ systick.dev.cpumask = cpumask_of(0);
-+ clockevents_config_and_register(&systick.dev, SYSTICK_FREQ, 0x3, 0x7fff);
-
- pr_info("%pOFn: running - mult: %d, shift: %d\n",
- np, systick.dev.mult, systick.dev.shift);
+++ /dev/null
-From f15d27f9c90ede4b16eb37f9ae573ef81c2b6996 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 31 Dec 2020 18:49:12 +0100
-Subject: [PATCH] MIPS: add bootargs-override property
-
-Add support for the bootargs-override property to the chosen node
-similar to the one used on ipq806x or mpc85xx.
-
-This is necessary, as the U-Boot used on some boards, notably the
-Ubiquiti UniFi 6 Lite, overwrite the bootargs property of the chosen
-node leading to a kernel panic when loading OpenWrt.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/mips/kernel/setup.c | 30 ++++++++++++++++++++++++++++++
- 1 file changed, 30 insertions(+)
-
---- a/arch/mips/kernel/setup.c
-+++ b/arch/mips/kernel/setup.c
-@@ -557,8 +557,28 @@ static int __init bootcmdline_scan_chose
-
- #endif /* CONFIG_OF_EARLY_FLATTREE */
-
-+static int __init bootcmdline_scan_chosen_override(unsigned long node, const char *uname,
-+ int depth, void *data)
-+{
-+ bool *dt_bootargs = data;
-+ const char *p;
-+ int l;
-+
-+ if (depth != 1 || !data || strcmp(uname, "chosen") != 0)
-+ return 0;
-+
-+ p = of_get_flat_dt_prop(node, "bootargs-override", &l);
-+ if (p != NULL && l > 0) {
-+ strlcpy(boot_command_line, p, COMMAND_LINE_SIZE);
-+ *dt_bootargs = true;
-+ }
-+
-+ return 1;
-+}
-+
- static void __init bootcmdline_init(void)
- {
-+ bool dt_bootargs_override = false;
- bool dt_bootargs = false;
-
- /*
-@@ -572,6 +592,14 @@ static void __init bootcmdline_init(void
- }
-
- /*
-+ * If bootargs-override in the chosen node is set, use this as the
-+ * command line
-+ */
-+ of_scan_flat_dt(bootcmdline_scan_chosen_override, &dt_bootargs_override);
-+ if (dt_bootargs_override)
-+ return;
-+
-+ /*
- * If the user specified a built-in command line &
- * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
- * prepended to arguments from the bootloader or DT so we'll copy them
+++ /dev/null
-From 5ede027f6c4a57ed25da872420508b7f1168b36b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 7 Dec 2015 17:15:32 +0100
-Subject: [PATCH 13/53] owrt: hack: fix mt7688 cache issue
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/kernel/setup.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/kernel/setup.c
-+++ b/arch/mips/kernel/setup.c
-@@ -699,7 +699,6 @@ static void __init arch_mem_init(char **
- mips_reserve_vmcore();
-
- mips_parse_crashkernel();
-- device_tree_init();
-
- /*
- * In order to reduce the possibility of kernel panic when failed to
-@@ -834,6 +833,7 @@ void __init setup_arch(char **cmdline_p)
-
- cpu_cache_init();
- paging_init();
-+ device_tree_init();
-
- memblock_dump_all();
-
+++ /dev/null
-From 9e6ce539092a1dd605a20bf73c655a9de58d8641 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 7 Dec 2015 17:18:05 +0100
-Subject: [PATCH 15/53] arch: mips: do not select illegal access driver by
- default
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/ralink/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/mips/ralink/Kconfig
-+++ b/arch/mips/ralink/Kconfig
-@@ -14,9 +14,9 @@ config CLKEVT_RT3352
- select CEVT_SYSTICK_QUIRK
-
- config RALINK_ILL_ACC
-- bool
-+ bool "illegal access irq"
- depends on SOC_RT305X
-- default y
-+ default n
-
- config IRQ_INTC
- bool
+++ /dev/null
-From 6decd1aad15f56b169217789630a0098b496de0e Mon Sep 17 00:00:00 2001
-From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
-Date: Wed, 7 Apr 2021 13:07:38 -0700
-Subject: [PATCH] MIPS: add support for buggy MT7621S core detection
-
-Most MT7621 SoCs have 2 cores, which is detected and supported properly
-by CPS.
-
-Unfortunately, MT7621 SoC has a less common S variant with only one core.
-On MT7621S, GCR_CONFIG still reports 2 cores, which leads to hangs when
-starting SMP. CPULAUNCH registers can be used in that case to detect the
-absence of the second core and override the GCR_CONFIG PCORES field.
-
-Rework a long-standing OpenWrt patch to override the value of
-mips_cps_numcores on single-core MT7621 systems.
-
-Tested on a dual-core MT7621 device (Ubiquiti ER-X) and a single-core
-MT7621 device (Netgear R6220).
-
-Original 4.14 OpenWrt patch:
-Link: https://git.openwrt.org/?p=openwrt/openwrt.git;a=commitdiff;h=4cdbc90a376dd0555201c1434a2081e055e9ceb7
-Current 5.10 OpenWrt patch:
-Link: https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=target/linux/ramips/patches-5.10/320-mt7621-core-detect-hack.patch;h=c63f0f4c1ec742e24d8480e80553863744b58f6a;hb=10267e17299806f9885d086147878f6c492cb904
-
-Suggested-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/include/asm/mips-cps.h | 23 ++++++++++++++++++++++-
- 1 file changed, 22 insertions(+), 1 deletion(-)
-
---- a/arch/mips/include/asm/mips-cps.h
-+++ b/arch/mips/include/asm/mips-cps.h
-@@ -11,6 +11,8 @@
- #include <linux/io.h>
- #include <linux/types.h>
-
-+#include <asm/mips-boards/launch.h>
-+
- extern unsigned long __cps_access_bad_size(void)
- __compiletime_error("Bad size for CPS accessor");
-
-@@ -162,12 +164,31 @@ static inline uint64_t mips_cps_cluster_
- */
- static inline unsigned int mips_cps_numcores(unsigned int cluster)
- {
-+ unsigned int ncores;
-+
- if (!mips_cm_present())
- return 0;
-
- /* Add one before masking to handle 0xff indicating no cores */
-- return FIELD_GET(CM_GCR_CONFIG_PCORES,
-+ ncores = FIELD_GET(CM_GCR_CONFIG_PCORES,
- mips_cps_cluster_config(cluster) + 1);
-+
-+ if (IS_ENABLED(CONFIG_SOC_MT7621)) {
-+ struct cpulaunch *launch;
-+
-+ /*
-+ * Ralink MT7621S SoC is single core, but the GCR_CONFIG method
-+ * always reports 2 cores. Check the second core's LAUNCH_FREADY
-+ * flag to detect if the second core is missing. This method
-+ * only works before the core has been started.
-+ */
-+ launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
-+ launch += 2; /* MT7621 has 2 VPEs per core */
-+ if (!(launch->flags & LAUNCH_FREADY))
-+ ncores = 1;
-+ }
-+
-+ return ncores;
- }
-
- /**
+++ /dev/null
---- a/arch/mips/ralink/irq-gic.c
-+++ b/arch/mips/ralink/irq-gic.c
-@@ -13,6 +13,12 @@
-
- int get_c0_perfcount_int(void)
- {
-+ /*
-+ * Performance counter events are routed through GIC.
-+ * Prevent them from firing on CPU IRQ7 as well
-+ */
-+ clear_c0_status(IE_SW0 << 7);
-+
- return gic_get_c0_perfcount_int();
- }
- EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+++ /dev/null
-From ee9081b2726a5ca8cde5497afdc5425e21ff8f8b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 15 Jul 2013 00:39:21 +0200
-Subject: [PATCH 37/53] mtd: cfi cmdset 0002 force word write
-
----
- drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -40,7 +40,7 @@
- #include <linux/mtd/xip.h>
-
- #define AMD_BOOTLOC_BUG
--#define FORCE_WORD_WRITE 0
-+#define FORCE_WORD_WRITE 1
-
- #define MAX_RETRIES 3
-
+++ /dev/null
-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)
-+ NO_SFDP_FLAGS(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
-@@ -1620,6 +1620,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
-@@ -617,6 +617,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;
+++ /dev/null
-From e84e2430ee0e483842b4ff013ae8a6e7e2fa2734 Mon Sep 17 00:00:00 2001
-From: Weijie Gao <weijie.gao@mediatek.com>
-Date: Wed, 1 Apr 2020 02:07:58 +0800
-Subject: [PATCH 1/2] mtd: rawnand: add driver support for MT7621 nand
- flash controller
-
-This patch adds NAND flash controller driver for MediaTek MT7621 SoC.
-
-The NAND flash controller is similar with controllers described in
-mtk_nand.c, except that the controller from MT7621 doesn't support DMA
-transmission, and some registers' offset and fields are different.
-
-Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
----
- drivers/mtd/nand/raw/Kconfig | 8 +
- drivers/mtd/nand/raw/Makefile | 1 +
- drivers/mtd/nand/raw/mt7621_nand.c | 1348 ++++++++++++++++++++++++++++++++++++
- 3 files changed, 1357 insertions(+)
- create mode 100644 drivers/mtd/nand/raw/mt7621_nand.c
-
---- a/drivers/mtd/nand/raw/Kconfig
-+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -352,6 +352,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.
-
-+config MTD_NAND_MT7621
-+ tristate "MT7621 NAND controller"
-+ depends on SOC_MT7621 || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ Enables support for NAND controller on MT7621 SoC.
-+ This driver uses PIO mode for data transmission instead of DMA mode.
-+
- config MTD_NAND_MTK
- tristate "MTK NAND controller"
- depends on MTD_NAND_ECC_MEDIATEK
---- a/drivers/mtd/nand/raw/Makefile
-+++ b/drivers/mtd/nand/raw/Makefile
-@@ -48,6 +48,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n
- obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
- obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
- obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o
-+obj-$(CONFIG_MTD_NAND_MT7621) += mt7621_nand.o
- obj-$(CONFIG_MTD_NAND_MTK) += mtk_nand.o
- obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o
- obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
+++ /dev/null
-From 3d5f4da8296b23eb3abf8b13122b0d06a215e79c Mon Sep 17 00:00:00 2001
-From: Weijie Gao <weijie.gao@mediatek.com>
-Date: Wed, 1 Apr 2020 02:07:59 +0800
-Subject: [PATCH 2/2] dt-bindings: add documentation for mt7621-nand driver
-
-This patch adds documentation for MediaTek MT7621 NAND flash controller
-driver.
-
-Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
----
- .../bindings/mtd/mediatek,mt7621-nfc.yaml | 68 ++++++++++++++++++++++
- 1 file changed, 68 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml
-@@ -0,0 +1,68 @@
-+# SPDX-License-Identifier: GPL-2.0
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/mtd/mediatek,mt7621-nfc.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MediaTek MT7621 SoC NAND Flash Controller (NFC) DT binding
-+
-+maintainers:
-+ - Weijie Gao <weijie.gao@mediatek.com>
-+
-+description: |
-+ This driver uses a single node to describe both NAND Flash controller
-+ interface (NFI) and ECC engine for MT7621 SoC.
-+ MT7621 supports only one chip select.
-+
-+properties:
-+ "#address-cells": false
-+ "#size-cells": false
-+
-+ compatible:
-+ enum:
-+ - mediatek,mt7621-nfc
-+
-+ reg:
-+ items:
-+ - description: Register base of NFI core
-+ - description: Register base of ECC engine
-+
-+ reg-names:
-+ items:
-+ - const: nfi
-+ - const: ecc
-+
-+ clocks:
-+ items:
-+ - description: Source clock for NFI core, fixed 125MHz
-+
-+ clock-names:
-+ items:
-+ - const: nfi_clk
-+
-+required:
-+ - compatible
-+ - reg
-+ - reg-names
-+ - clocks
-+ - clock-names
-+
-+examples:
-+ - |
-+ nficlock: nficlock {
-+ #clock-cells = <0>;
-+ compatible = "fixed-clock";
-+
-+ clock-frequency = <125000000>;
-+ };
-+
-+ nand@1e003000 {
-+ compatible = "mediatek,mt7621-nfc";
-+
-+ reg = <0x1e003000 0x800
-+ 0x1e003800 0x800>;
-+ reg-names = "nfi", "ecc";
-+
-+ clocks = <&nficlock>;
-+ clock-names = "nfi_clk";
-+ };
+++ /dev/null
-From bd0f89de5476ca25e73fae829ba3e1dafae1d90d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
-Date: Fri, 21 Jun 2019 10:04:05 +0200
-Subject: [PATCH] net: ethernet: mediatek: support net-labels
-
-With this patch, device name can be set within dts file in the same way as dsa
-port can.
-Add: label = "wan"; to GMAC node.
-
-Signed-off-by: René van Dorst <opensource@vdorst.com>
----
- 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
-@@ -4643,6 +4643,7 @@ static const struct net_device_ops mtk_n
-
- static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
- {
-+ const char *name = of_get_property(np, "label", NULL);
- const __be32 *_id = of_get_property(np, "reg", NULL);
- struct device_node *pcs_np;
- phy_interface_t phy_mode;
-@@ -4840,6 +4841,9 @@ static int mtk_add_mac(struct mtk_eth *e
- register_netdevice_notifier(&mac->device_notifier);
- }
-
-+ if (name)
-+ strlcpy(eth->netdev[id]->name, name, IFNAMSIZ);
-+
- return 0;
-
- free_netdev:
+++ /dev/null
-From ffbb1b37a3e1ce1a5c574a6bd4f5aede8bc468ac Mon Sep 17 00:00:00 2001
-From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
-Date: Sat, 27 Feb 2021 20:20:07 -0800
-Subject: [PATCH] Revert "net: phy: simplify phy_link_change arguments"
-
-This reverts commit a307593a644443db12888f45eed0dafb5869e2cc.
-
-This brings back the do_carrier flags used by the (hacky) next patch,
-still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
----
- drivers/net/phy/phy.c | 12 ++++++------
- drivers/net/phy/phy_device.c | 12 +++++++-----
- drivers/net/phy/phylink.c | 3 ++-
- include/linux/phy.h | 2 +-
- 4 files changed, 16 insertions(+), 13 deletions(-)
-
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -71,13 +71,13 @@ static void phy_process_state_change(str
-
- static void phy_link_up(struct phy_device *phydev)
- {
-- phydev->phy_link_change(phydev, true);
-+ phydev->phy_link_change(phydev, true, true);
- phy_led_trigger_change_speed(phydev);
- }
-
--static void phy_link_down(struct phy_device *phydev)
-+static void phy_link_down(struct phy_device *phydev, bool do_carrier)
- {
-- phydev->phy_link_change(phydev, false);
-+ phydev->phy_link_change(phydev, false, do_carrier);
- phy_led_trigger_change_speed(phydev);
- }
-
-@@ -595,7 +595,7 @@ int phy_start_cable_test(struct phy_devi
- goto out;
-
- /* Mark the carrier down until the test is complete */
-- phy_link_down(phydev);
-+ phy_link_down(phydev, true);
-
- netif_testing_on(dev);
- err = phydev->drv->cable_test_start(phydev);
-@@ -666,7 +666,7 @@ int phy_start_cable_test_tdr(struct phy_
- goto out;
-
- /* Mark the carrier down until the test is complete */
-- phy_link_down(phydev);
-+ phy_link_down(phydev, true);
-
- netif_testing_on(dev);
- err = phydev->drv->cable_test_tdr_start(phydev, config);
-@@ -738,7 +738,7 @@ static int phy_check_link_status(struct
- phy_link_up(phydev);
- } else if (!phydev->link && phydev->state != PHY_NOLINK) {
- phydev->state = PHY_NOLINK;
-- phy_link_down(phydev);
-+ phy_link_down(phydev, true);
- }
-
- return 0;
-@@ -1224,7 +1224,7 @@ void phy_state_machine(struct work_struc
- case PHY_HALTED:
- if (phydev->link) {
- phydev->link = 0;
-- phy_link_down(phydev);
-+ phy_link_down(phydev, true);
- }
- do_suspend = true;
- break;
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -1037,14 +1037,16 @@ struct phy_device *phy_find_first(struct
- }
- EXPORT_SYMBOL(phy_find_first);
-
--static void phy_link_change(struct phy_device *phydev, bool up)
-+static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier)
- {
- struct net_device *netdev = phydev->attached_dev;
-
-- if (up)
-- netif_carrier_on(netdev);
-- else
-- netif_carrier_off(netdev);
-+ if (do_carrier) {
-+ if (up)
-+ netif_carrier_on(netdev);
-+ else
-+ netif_carrier_off(netdev);
-+ }
- phydev->adjust_link(netdev);
- if (phydev->mii_ts && phydev->mii_ts->link_state)
- phydev->mii_ts->link_state(phydev->mii_ts, phydev);
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -1687,7 +1687,8 @@ bool phylink_expects_phy(struct phylink
- }
- EXPORT_SYMBOL_GPL(phylink_expects_phy);
-
--static void phylink_phy_change(struct phy_device *phydev, bool up)
-+static void phylink_phy_change(struct phy_device *phydev, bool up,
-+ bool do_carrier)
- {
- struct phylink *pl = phydev->phylink;
- bool tx_pause, rx_pause;
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -739,7 +739,7 @@ struct phy_device {
-
- int pma_extable;
-
-- void (*phy_link_change)(struct phy_device *phydev, bool up);
-+ void (*phy_link_change)(struct phy_device *, bool up, bool do_carrier);
- void (*adjust_link)(struct net_device *dev);
-
- #if IS_ENABLED(CONFIG_MACSEC)
+++ /dev/null
-From 0b6eb1e68290243d439ee330ea8d0b239a5aec69 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 27 Jul 2014 09:38:50 +0100
-Subject: [PATCH 34/53] NET: multi phy support
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/phy/phy.c | 9 ++++++---
- include/linux/phy.h | 1 +
- 2 files changed, 7 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -738,7 +738,10 @@ static int phy_check_link_status(struct
- phy_link_up(phydev);
- } else if (!phydev->link && phydev->state != PHY_NOLINK) {
- phydev->state = PHY_NOLINK;
-- phy_link_down(phydev, true);
-+ if (!phydev->no_auto_carrier_off)
-+ phy_link_down(phydev, true);
-+ else
-+ phy_link_down(phydev, false);
- }
-
- return 0;
-@@ -1224,7 +1227,10 @@ void phy_state_machine(struct work_struc
- case PHY_HALTED:
- if (phydev->link) {
- phydev->link = 0;
-- phy_link_down(phydev, true);
-+ if (!phydev->no_auto_carrier_off)
-+ phy_link_down(phydev, true);
-+ else
-+ phy_link_down(phydev, false);
- }
- do_suspend = true;
- break;
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -647,6 +647,7 @@ struct phy_device {
- unsigned downshifted_rate:1;
- unsigned is_on_sfp_module:1;
- unsigned mac_managed_pm:1;
-+ unsigned no_auto_carrier_off:1;
-
- unsigned autoneg:1;
- /* The most recently read link state */
+++ /dev/null
-From d94fc5ce1dc395747c3934ecffcdec0396583755 Mon Sep 17 00:00:00 2001
-From: Nick Hainke <vincent@systemli.org>
-Date: Fri, 26 May 2023 19:46:33 +0200
-Subject: [PATCH] dmaengine: mediatek: add HSDMA support for mt7621
-
-Commit 87dd67f496f7 ("staging: mt7621-dma: remove driver from tree")
-removed the mt7621-dma driver. Move the driver from staging to the
-folder "drivers/dma/mediatek" containing already other mediatek dma
-driver implementations and maintain it downstream in OpenWrt.
-
-This patch will not be sent to upstream linux. It is just a workaround.
-
-Signed-off-by: Nick Hainke <vincent@systemli.org>
----
- drivers/dma/mediatek/Kconfig | 6 ++++++
- drivers/dma/mediatek/Makefile | 1 +
- 2 files changed, 7 insertions(+)
-
---- a/drivers/dma/mediatek/Kconfig
-+++ b/drivers/dma/mediatek/Kconfig
-@@ -36,3 +36,9 @@ config MTK_UART_APDMA
- When SERIAL_8250_MT6577 is enabled, and if you want to use DMA,
- you can enable the config. The DMA engine can only be used
- with MediaTek SoCs.
-+
-+config MTK_HSDMA
-+ tristate "MTK HSDMA support"
-+ depends on RALINK && SOC_MT7621
-+ select DMA_ENGINE
-+ select DMA_VIRTUAL_CHANNELS
---- a/drivers/dma/mediatek/Makefile
-+++ b/drivers/dma/mediatek/Makefile
-@@ -2,3 +2,4 @@
- obj-$(CONFIG_MTK_UART_APDMA) += mtk-uart-apdma.o
- obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
- obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o
-+obj-$(CONFIG_MTK_HSDMA) += hsdma-mt7621.o
+++ /dev/null
-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
-
-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(+)
- create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
-@@ -0,0 +1,40 @@
-+Ralink SoC GPIO controller bindings
-+
-+Required properties:
-+- compatible:
-+ - "ralink,rt2880-gpio" for Ralink controllers
-+- #gpio-cells : Should be two.
-+ - first cell is the pin number
-+ - second cell is used to specify optional parameters (unused)
-+- gpio-controller : Marks the device node as a GPIO controller
-+- reg : Physical base address and length of the controller's registers
-+- interrupt-parent: phandle to the INTC device node
-+- interrupts : Specify the INTC interrupt number
-+- ngpios : Specify the number of GPIOs
-+- 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 ]
-+
-+Optional properties:
-+- ralink,gpio-base : Specify the GPIO chips base number
-+
-+Example:
-+
-+ gpio0: gpio@600 {
-+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
-+
-+ #gpio-cells = <2>;
-+ gpio-controller;
-+
-+ reg = <0x600 0x34>;
-+
-+ interrupt-parent = <&intc>;
-+ interrupts = <6>;
-+
-+ ngpios = <24>;
-+ ralink,gpio-base = <0>;
-+ ralink,register-map = [ 00 04 08 0c
-+ 20 24 28 2c
-+ 30 34 ];
-+
-+ };
+++ /dev/null
-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
-
-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
- 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
-@@ -585,6 +585,12 @@ 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
-+ help
-+ Say yes here to support the Ralink SoC GPIO device
-+
- config GPIO_SPEAR_SPICS
- bool "ST SPEAr13xx SPI Chip Select as GPIO support"
- depends on PLAT_SPEAR
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -122,6 +122,7 @@ obj-$(CONFIG_GPIO_PISOSR) += gpio-pisos
- obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
- obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o
- obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
-+obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o
- obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
- obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
- obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
---- /dev/null
-+++ b/drivers/gpio/gpio-ralink.c
-@@ -0,0 +1,341 @@
-+/*
-+ * 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-2011 Gabor Juhos <juhosg@openwrt.org>
-+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/io.h>
-+#include <linux/gpio.h>
-+#include <linux/spinlock.h>
-+#include <linux/platform_device.h>
-+#include <linux/of_irq.h>
-+#include <linux/irqdomain.h>
-+#include <linux/interrupt.h>
-+
-+enum ralink_gpio_reg {
-+ GPIO_REG_INT = 0,
-+ GPIO_REG_EDGE,
-+ GPIO_REG_RENA,
-+ GPIO_REG_FENA,
-+ GPIO_REG_DATA,
-+ GPIO_REG_DIR,
-+ GPIO_REG_POL,
-+ GPIO_REG_SET,
-+ GPIO_REG_RESET,
-+ GPIO_REG_TOGGLE,
-+ GPIO_REG_MAX
-+};
-+
-+struct ralink_gpio_chip {
-+ struct gpio_chip chip;
-+ u8 regs[GPIO_REG_MAX];
-+
-+ spinlock_t lock;
-+ void __iomem *membase;
-+ struct irq_domain *domain;
-+ int irq;
-+
-+ u32 rising;
-+ u32 falling;
-+};
-+
-+#define MAP_MAX 4
-+static struct irq_domain *irq_map[MAP_MAX];
-+static int irq_map_count;
-+static atomic_t irq_refcount = ATOMIC_INIT(0);
-+
-+static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip)
-+{
-+ struct ralink_gpio_chip *rg;
-+
-+ rg = container_of(chip, struct ralink_gpio_chip, chip);
-+
-+ return rg;
-+}
-+
-+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val)
-+{
-+ iowrite32(val, rg->membase + rg->regs[reg]);
-+}
-+
-+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg)
-+{
-+ 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);
-+
-+ if (rg->irq < 1)
-+ return -1;
-+
-+ return irq_create_mapping(rg->domain, pin);
-+}
-+
-+static void ralink_gpio_irq_handler(struct irq_desc *desc)
-+{
-+ int i;
-+
-+ for (i = 0; i < irq_map_count; i++) {
-+ struct irq_domain *domain = irq_map[i];
-+ struct ralink_gpio_chip *rg;
-+ unsigned long pending;
-+ int bit;
-+
-+ rg = (struct ralink_gpio_chip *) domain->host_data;
-+ pending = rt_gpio_r32(rg, GPIO_REG_INT);
-+
-+ for_each_set_bit(bit, &pending, rg->chip.ngpio) {
-+ u32 map = irq_find_mapping(domain, bit);
-+ generic_handle_irq(map);
-+ rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit));
-+ }
-+ }
-+}
-+
-+static void ralink_gpio_irq_unmask(struct irq_data *d)
-+{
-+ struct ralink_gpio_chip *rg;
-+ unsigned long flags;
-+ u32 rise, fall;
-+
-+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
-+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
-+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
-+
-+ spin_lock_irqsave(&rg->lock, flags);
-+ rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising));
-+ rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling));
-+ spin_unlock_irqrestore(&rg->lock, flags);
-+}
-+
-+static void ralink_gpio_irq_mask(struct irq_data *d)
-+{
-+ struct ralink_gpio_chip *rg;
-+ unsigned long flags;
-+ u32 rise, fall;
-+
-+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
-+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
-+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
-+
-+ spin_lock_irqsave(&rg->lock, flags);
-+ rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq));
-+ rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq));
-+ spin_unlock_irqrestore(&rg->lock, flags);
-+}
-+
-+static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type)
-+{
-+ struct ralink_gpio_chip *rg;
-+ u32 mask = BIT(d->hwirq);
-+
-+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
-+
-+ if (type == IRQ_TYPE_PROBE) {
-+ if ((rg->rising | rg->falling) & mask)
-+ return 0;
-+
-+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
-+ }
-+
-+ if (type & IRQ_TYPE_EDGE_RISING)
-+ rg->rising |= mask;
-+ else
-+ rg->rising &= ~mask;
-+
-+ if (type & IRQ_TYPE_EDGE_FALLING)
-+ rg->falling |= mask;
-+ else
-+ rg->falling &= ~mask;
-+
-+ return 0;
-+}
-+
-+static struct irq_chip ralink_gpio_irq_chip = {
-+ .name = "GPIO",
-+ .irq_unmask = ralink_gpio_irq_unmask,
-+ .irq_mask = ralink_gpio_irq_mask,
-+ .irq_mask_ack = ralink_gpio_irq_mask,
-+ .irq_set_type = ralink_gpio_irq_type,
-+};
-+
-+static int gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
-+{
-+ irq_set_chip_and_handler(irq, &ralink_gpio_irq_chip, handle_level_irq);
-+ irq_set_handler_data(irq, d);
-+
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops irq_domain_ops = {
-+ .xlate = irq_domain_xlate_onecell,
-+ .map = gpio_map,
-+};
-+
-+static void ralink_gpio_irq_init(struct device_node *np,
-+ struct ralink_gpio_chip *rg)
-+{
-+ if (irq_map_count >= MAP_MAX)
-+ return;
-+
-+ rg->irq = irq_of_parse_and_map(np, 0);
-+ if (!rg->irq)
-+ return;
-+
-+ rg->domain = irq_domain_add_linear(np, rg->chip.ngpio,
-+ &irq_domain_ops, rg);
-+ if (!rg->domain) {
-+ dev_err(rg->chip.parent, "irq_domain_add_linear failed\n");
-+ return;
-+ }
-+
-+ irq_map[irq_map_count++] = rg->domain;
-+
-+ rt_gpio_w32(rg, GPIO_REG_RENA, 0x0);
-+ rt_gpio_w32(rg, GPIO_REG_FENA, 0x0);
-+
-+ if (!atomic_read(&irq_refcount))
-+ irq_set_chained_handler(rg->irq, ralink_gpio_irq_handler);
-+ atomic_inc(&irq_refcount);
-+
-+ dev_info(rg->chip.parent, "registering %d irq handlers\n", rg->chip.ngpio);
-+}
-+
-+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 ralink_gpio_chip *rg;
-+ const __be32 *ngpio, *gpiobase;
-+
-+ if (!res) {
-+ dev_err(&pdev->dev, "failed to find resource\n");
-+ return -ENOMEM;
-+ }
-+
-+ rg = devm_kzalloc(&pdev->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;
-+ }
-+
-+ 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");
-+ 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.of_node = 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;
-+ rg->chip.request = gpiochip_generic_request;
-+ rg->chip.to_irq = ralink_gpio_to_irq;
-+ rg->chip.free = gpiochip_generic_free;
-+
-+ /* 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);
-+}
-+
-+static const struct of_device_id ralink_gpio_match[] = {
-+ { .compatible = "ralink,rt2880-gpio" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ralink_gpio_match);
-+
-+static struct platform_driver ralink_gpio_driver = {
-+ .probe = ralink_gpio_probe,
-+ .driver = {
-+ .name = "rt2880_gpio",
-+ .owner = THIS_MODULE,
-+ .of_match_table = ralink_gpio_match,
-+ },
-+};
-+
-+static int __init ralink_gpio_init(void)
-+{
-+ return platform_driver_register(&ralink_gpio_driver);
-+}
-+
-+subsys_initcall(ralink_gpio_init);
+++ /dev/null
-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
-
-Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
----
- Documentation/devicetree/bindings/gpio/gpio-ralink.txt | 6 ++++++
- drivers/gpio/gpio-ralink.c | 2 +-
- 2 files changed, 7 insertions(+), 1 deletion(-)
-
---- 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
-+- 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:
-
- reg = <0x600 0x34>;
-
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+
- interrupt-parent = <&intc>;
- interrupts = <6>;
-
---- a/drivers/gpio/gpio-ralink.c
-+++ b/drivers/gpio/gpio-ralink.c
-@@ -220,7 +220,7 @@ static int gpio_map(struct irq_domain *d
- }
-
- static const struct irq_domain_ops irq_domain_ops = {
-- .xlate = irq_domain_xlate_onecell,
-+ .xlate = irq_domain_xlate_twocell,
- .map = gpio_map,
- };
-
+++ /dev/null
-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
+++ /dev/null
-From: Shiji Yang <yangshiji66@outlook.com>
-Date: Wed, 26 Jul 2023 01:32:55 +0800
-Subject: [PATCH] pinctrl: mtmips: support requesting different functions for
- same group
-
-Sometimes pinctrl consumers may request different functions for the
-same pin group in different situations. This patch can help to reset
-the group function flag when requesting a different function.
-
-Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
----
- drivers/pinctrl/ralink/pinctrl-ralink.c | 21 +++++++++++++++++----
- 1 file changed, 17 insertions(+), 4 deletions(-)
-
---- a/drivers/pinctrl/ralink/pinctrl-ralink.c
-+++ b/drivers/pinctrl/ralink/pinctrl-ralink.c
-@@ -123,11 +123,24 @@ static int ralink_pmx_group_enable(struc
- int i;
- int shift;
-
-- /* dont allow double use */
-+ /*
-+ * for the same pin group, if request a different function,
-+ * then clear the group function flag and continue, else exit.
-+ */
- if (p->groups[group].enabled) {
-- dev_err(p->dev, "%s is already enabled\n",
-- p->groups[group].name);
-- return 0;
-+ for (i = 0; i < p->groups[group].func_count; i++) {
-+ if (p->groups[group].func[i].enabled == 1) {
-+ if (!strcmp(p->func[func]->name,
-+ p->groups[group].func[i].name))
-+ return 0;
-+ p->groups[group].func[i].enabled = 0;
-+ break;
-+ }
-+ }
-+
-+ /* exit if request the "gpio" function again */
-+ if (i == p->groups[group].func_count && func == 0)
-+ return 0;
- }
-
- p->groups[group].enabled = 1;
+++ /dev/null
-From 975e76214cd2516eb6cfff4c3eec581872645e88 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 19 Sep 2013 01:50:59 +0200
-Subject: [PATCH 31/53] uvc: add iPassion iP2970 support
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/media/usb/uvc/uvc_driver.c | 12 +++
- drivers/media/usb/uvc/uvc_status.c | 2 +
- drivers/media/usb/uvc/uvc_video.c | 147 ++++++++++++++++++++++++++++++++++++
- drivers/media/usb/uvc/uvcvideo.h | 5 +-
- 4 files changed, 165 insertions(+), 1 deletion(-)
-
---- a/drivers/media/usb/uvc/uvc_driver.c
-+++ b/drivers/media/usb/uvc/uvc_driver.c
-@@ -2981,6 +2981,18 @@ static const struct usb_device_id uvc_id
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
-+ /* iPassion iP2970 */
-+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
-+ | USB_DEVICE_ID_MATCH_INT_INFO,
-+ .idVendor = 0x1B3B,
-+ .idProduct = 0x2970,
-+ .bInterfaceClass = USB_CLASS_VIDEO,
-+ .bInterfaceSubClass = 1,
-+ .bInterfaceProtocol = 0,
-+ .driver_info = UVC_QUIRK_PROBE_MINMAX
-+ | UVC_QUIRK_STREAM_NO_FID
-+ | UVC_QUIRK_MOTION
-+ | UVC_QUIRK_SINGLE_ISO },
- /* Generic USB Video Class */
- { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
- { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
---- a/drivers/media/usb/uvc/uvc_status.c
-+++ b/drivers/media/usb/uvc/uvc_status.c
-@@ -223,6 +223,7 @@ static void uvc_status_complete(struct u
- if (uvc_event_control(urb, status, len))
- /* The URB will be resubmitted in work context. */
- return;
-+ dev->motion = 1;
- break;
- }
-
-@@ -271,6 +272,7 @@ int uvc_status_init(struct uvc_device *d
- }
-
- pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
-+ dev->motion = 0;
-
- /*
- * For high-speed interrupt endpoints, the bInterval value is used as
---- a/drivers/media/usb/uvc/uvc_video.c
-+++ b/drivers/media/usb/uvc/uvc_video.c
-@@ -19,6 +19,11 @@
- #include <linux/wait.h>
- #include <linux/atomic.h>
- #include <asm/unaligned.h>
-+#include <linux/skbuff.h>
-+#include <linux/kobject.h>
-+#include <linux/netlink.h>
-+#include <linux/kobject.h>
-+#include <linux/workqueue.h>
-
- #include <media/v4l2-common.h>
-
-@@ -1231,9 +1236,149 @@ static void uvc_video_decode_data(struct
- uvc_urb->async_operations++;
- }
-
-+struct bh_priv {
-+ unsigned long seen;
-+};
-+
-+struct bh_event {
-+ const char *name;
-+ struct sk_buff *skb;
-+ struct work_struct work;
-+};
-+
-+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, "webcam", ##args )
-+#define BH_DBG(fmt, args...) do {} while (0)
-+#define BH_SKB_SIZE 2048
-+
-+extern u64 uevent_next_seqnum(void);
-+static int seen = 0;
-+
-+static int bh_event_add_var(struct bh_event *event, int argv,
-+ const char *format, ...)
-+{
-+ static char buf[128];
-+ char *s;
-+ va_list args;
-+ int len;
-+
-+ if (argv)
-+ return 0;
-+
-+ va_start(args, format);
-+ len = vsnprintf(buf, sizeof(buf), format, args);
-+ va_end(args);
-+
-+ if (len >= sizeof(buf)) {
-+ BH_ERR("buffer size too small\n");
-+ WARN_ON(1);
-+ return -ENOMEM;
-+ }
-+
-+ s = skb_put(event->skb, len + 1);
-+ strcpy(s, buf);
-+
-+ BH_DBG("added variable '%s'\n", s);
-+
-+ return 0;
-+}
-+
-+static int motion_hotplug_fill_event(struct bh_event *event)
-+{
-+ int s = jiffies;
-+ int ret;
-+
-+ if (!seen)
-+ seen = jiffies;
-+
-+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
-+ if (ret)
-+ return ret;
-+
-+ ret = bh_event_add_var(event, 0, "PATH=%s",
-+ "/sbin:/bin:/usr/sbin:/usr/bin");
-+ if (ret)
-+ return ret;
-+
-+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=usb");
-+ if (ret)
-+ return ret;
-+
-+ ret = bh_event_add_var(event, 0, "ACTION=motion");
-+ if (ret)
-+ return ret;
-+
-+ ret = bh_event_add_var(event, 0, "SEEN=%d", s - seen);
-+ if (ret)
-+ return ret;
-+ seen = s;
-+
-+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
-+
-+ return ret;
-+}
-+
-+static void motion_hotplug_work(struct work_struct *work)
-+{
-+ struct bh_event *event = container_of(work, struct bh_event, work);
-+ int ret = 0;
-+
-+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
-+ if (!event->skb)
-+ goto out_free_event;
-+
-+ ret = bh_event_add_var(event, 0, "%s@", "add");
-+ if (ret)
-+ goto out_free_skb;
-+
-+ ret = motion_hotplug_fill_event(event);
-+ if (ret)
-+ goto out_free_skb;
-+
-+ NETLINK_CB(event->skb).dst_group = 1;
-+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
-+
-+out_free_skb:
-+ if (ret) {
-+ BH_ERR("work error %d\n", ret);
-+ kfree_skb(event->skb);
-+ }
-+out_free_event:
-+ kfree(event);
-+}
-+
-+static int motion_hotplug_create_event(void)
-+{
-+ struct bh_event *event;
-+
-+ event = kzalloc(sizeof(*event), GFP_KERNEL);
-+ if (!event)
-+ return -ENOMEM;
-+
-+ event->name = "motion";
-+
-+ INIT_WORK(&event->work, (void *)(void *)motion_hotplug_work);
-+ schedule_work(&event->work);
-+
-+ return 0;
-+}
-+
-+#define MOTION_FLAG_OFFSET 4
- static void uvc_video_decode_end(struct uvc_streaming *stream,
- struct uvc_buffer *buf, const u8 *data, int len)
- {
-+ if ((stream->dev->quirks & UVC_QUIRK_MOTION) &&
-+ (data[len - 2] == 0xff) && (data[len - 1] == 0xd9)) {
-+ u8 *mem;
-+ buf->state = UVC_BUF_STATE_READY;
-+ mem = (u8 *) (buf->mem + MOTION_FLAG_OFFSET);
-+ if ( stream->dev->motion ) {
-+ stream->dev->motion = 0;
-+ motion_hotplug_create_event();
-+ } else {
-+ *mem &= 0x7f;
-+ }
-+ }
-+
- /* 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");
-@@ -1815,6 +1960,8 @@ static int uvc_init_video_isoc(struct uv
- if (npackets == 0)
- return -ENOMEM;
-
-+ if (stream->dev->quirks & UVC_QUIRK_SINGLE_ISO)
-+ npackets = 1;
- size = npackets * psize;
-
- for_each_uvc_urb(uvc_urb, stream) {
---- a/drivers/media/usb/uvc/uvcvideo.h
-+++ b/drivers/media/usb/uvc/uvcvideo.h
-@@ -75,6 +75,8 @@
- #define UVC_QUIRK_FORCE_Y8 0x00000800
- #define UVC_QUIRK_FORCE_BPP 0x00001000
- #define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000
-+#define UVC_QUIRK_MOTION 0x00004000
-+#define UVC_QUIRK_SINGLE_ISO 0x00008000
-
- /* Format flags */
- #define UVC_FMT_FLAG_COMPRESSED 0x00000001
-@@ -562,6 +564,7 @@ struct uvc_device {
- u8 *status;
- struct input_dev *input;
- char input_phys[64];
-+ int motion;
-
- struct uvc_ctrl_work {
- struct work_struct work;
+++ /dev/null
-From da6015e7f19d749f135f7ac55c4ec47b06faa868 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 9 Aug 2013 20:12:59 +0200
-Subject: [PATCH 41/53] DT: Add documentation for spi-rt2880
-
-Describe the SPI master found on the MIPS based Ralink RT2880 SoC.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- .../devicetree/bindings/spi/spi-rt2880.txt | 28 ++++++++++++++++++++
- 1 file changed, 28 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/spi/spi-rt2880.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/spi/spi-rt2880.txt
-@@ -0,0 +1,28 @@
-+Ralink SoC RT2880 SPI master controller.
-+
-+This SPI controller is found on most wireless SoCs made by ralink.
-+
-+Required properties:
-+- compatible : "ralink,rt2880-spi"
-+- reg : The register base for the controller.
-+- #address-cells : <1>, as required by generic SPI binding.
-+- #size-cells : <0>, also as required by generic SPI binding.
-+
-+Child nodes as per the generic SPI binding.
-+
-+Example:
-+
-+ spi@b00 {
-+ compatible = "ralink,rt2880-spi";
-+ reg = <0xb00 0x100>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ m25p80@0 {
-+ compatible = "m25p80";
-+ reg = <0>;
-+ spi-max-frequency = <10000000>;
-+ };
-+ };
-+
+++ /dev/null
-From 683af4ebb91a1600df1946ac4769d916b8a1be65 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 27 Jul 2014 11:15:12 +0100
-Subject: [PATCH 42/53] SPI: ralink: add Ralink SoC spi driver
-
-Add the driver needed to make SPI work on Ralink SoC.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: John Crispin <blogic@openwrt.org>
----
- drivers/spi/Kconfig | 6 +
- drivers/spi/Makefile | 1 +
- drivers/spi/spi-rt2880.c | 530 ++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 537 insertions(+)
- create mode 100644 drivers/spi/spi-rt2880.c
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -823,6 +823,12 @@ config SPI_QCOM_GENI
- This driver can also be built as a module. If so, the module
- will be called spi-geni-qcom.
-
-+config SPI_RT2880
-+ tristate "Ralink RT288x SPI Controller"
-+ depends on RALINK
-+ help
-+ This selects a driver for the Ralink RT288x/RT305x SPI Controller.
-+
- config SPI_S3C24XX
- tristate "Samsung S3C24XX series SPI"
- depends on ARCH_S3C24XX
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -110,6 +110,7 @@ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
- obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
- obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
- obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
-+obj-$(CONFIG_SPI_RT2880) += spi-rt2880.o
- obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
- spi-s3c24xx-hw-y := spi-s3c24xx.o
- obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o
---- /dev/null
-+++ b/drivers/spi/spi-rt2880.c
-@@ -0,0 +1,535 @@
-+/*
-+ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver
-+ *
-+ * Copyright (C) 2011 Sergiy <piratfm@gmail.com>
-+ * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
-+ *
-+ * Some parts are based on spi-orion.c:
-+ * Author: Shadi Ammouri <shadi@marvell.com>
-+ * Copyright (C) 2007-2008 Marvell Ltd.
-+ *
-+ * 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/module.h>
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/delay.h>
-+#include <linux/io.h>
-+#include <linux/reset.h>
-+#include <linux/spi/spi.h>
-+#include <linux/platform_device.h>
-+#include <linux/gpio.h>
-+
-+#define DRIVER_NAME "spi-rt2880"
-+
-+#define RAMIPS_SPI_STAT 0x00
-+#define RAMIPS_SPI_CFG 0x10
-+#define RAMIPS_SPI_CTL 0x14
-+#define RAMIPS_SPI_DATA 0x20
-+#define RAMIPS_SPI_ADDR 0x24
-+#define RAMIPS_SPI_BS 0x28
-+#define RAMIPS_SPI_USER 0x2C
-+#define RAMIPS_SPI_TXFIFO 0x30
-+#define RAMIPS_SPI_RXFIFO 0x34
-+#define RAMIPS_SPI_FIFO_STAT 0x38
-+#define RAMIPS_SPI_MODE 0x3C
-+#define RAMIPS_SPI_DEV_OFFSET 0x40
-+#define RAMIPS_SPI_DMA 0x80
-+#define RAMIPS_SPI_DMASTAT 0x84
-+#define RAMIPS_SPI_ARBITER 0xF0
-+
-+/* SPISTAT register bit field */
-+#define SPISTAT_BUSY BIT(0)
-+
-+/* SPICFG register bit field */
-+#define SPICFG_ADDRMODE BIT(12)
-+#define SPICFG_RXENVDIS BIT(11)
-+#define SPICFG_RXCAP BIT(10)
-+#define SPICFG_SPIENMODE BIT(9)
-+#define SPICFG_MSBFIRST BIT(8)
-+#define SPICFG_SPICLKPOL BIT(6)
-+#define SPICFG_RXCLKEDGE_FALLING BIT(5)
-+#define SPICFG_TXCLKEDGE_FALLING BIT(4)
-+#define SPICFG_HIZSPI BIT(3)
-+#define SPICFG_SPICLK_PRESCALE_MASK 0x7
-+#define SPICFG_SPICLK_DIV2 0
-+#define SPICFG_SPICLK_DIV4 1
-+#define SPICFG_SPICLK_DIV8 2
-+#define SPICFG_SPICLK_DIV16 3
-+#define SPICFG_SPICLK_DIV32 4
-+#define SPICFG_SPICLK_DIV64 5
-+#define SPICFG_SPICLK_DIV128 6
-+#define SPICFG_SPICLK_DISABLE 7
-+
-+/* SPICTL register bit field */
-+#define SPICTL_START BIT(4)
-+#define SPICTL_HIZSDO BIT(3)
-+#define SPICTL_STARTWR BIT(2)
-+#define SPICTL_STARTRD BIT(1)
-+#define SPICTL_SPIENA BIT(0)
-+
-+/* SPIUSER register bit field */
-+#define SPIUSER_USERMODE BIT(21)
-+#define SPIUSER_INSTR_PHASE BIT(20)
-+#define SPIUSER_ADDR_PHASE_MASK 0x7
-+#define SPIUSER_ADDR_PHASE_OFFSET 17
-+#define SPIUSER_MODE_PHASE BIT(16)
-+#define SPIUSER_DUMMY_PHASE_MASK 0x3
-+#define SPIUSER_DUMMY_PHASE_OFFSET 14
-+#define SPIUSER_DATA_PHASE_MASK 0x3
-+#define SPIUSER_DATA_PHASE_OFFSET 12
-+#define SPIUSER_DATA_READ (BIT(0) << SPIUSER_DATA_PHASE_OFFSET)
-+#define SPIUSER_DATA_WRITE (BIT(1) << SPIUSER_DATA_PHASE_OFFSET)
-+#define SPIUSER_ADDR_TYPE_OFFSET 9
-+#define SPIUSER_MODE_TYPE_OFFSET 6
-+#define SPIUSER_DUMMY_TYPE_OFFSET 3
-+#define SPIUSER_DATA_TYPE_OFFSET 0
-+#define SPIUSER_TRANSFER_MASK 0x7
-+#define SPIUSER_TRANSFER_SINGLE BIT(0)
-+#define SPIUSER_TRANSFER_DUAL BIT(1)
-+#define SPIUSER_TRANSFER_QUAD BIT(2)
-+
-+#define SPIUSER_TRANSFER_TYPE(type) ( \
-+ (type << SPIUSER_ADDR_TYPE_OFFSET) | \
-+ (type << SPIUSER_MODE_TYPE_OFFSET) | \
-+ (type << SPIUSER_DUMMY_TYPE_OFFSET) | \
-+ (type << SPIUSER_DATA_TYPE_OFFSET) \
-+)
-+
-+/* SPIFIFOSTAT register bit field */
-+#define SPIFIFOSTAT_TXEMPTY BIT(19)
-+#define SPIFIFOSTAT_RXEMPTY BIT(18)
-+#define SPIFIFOSTAT_TXFULL BIT(17)
-+#define SPIFIFOSTAT_RXFULL BIT(16)
-+#define SPIFIFOSTAT_FIFO_MASK 0xff
-+#define SPIFIFOSTAT_TX_OFFSET 8
-+#define SPIFIFOSTAT_RX_OFFSET 0
-+
-+#define SPI_FIFO_DEPTH 16
-+
-+/* SPIMODE register bit field */
-+#define SPIMODE_MODE_OFFSET 24
-+#define SPIMODE_DUMMY_OFFSET 0
-+
-+/* SPIARB register bit field */
-+#define SPICTL_ARB_EN BIT(31)
-+#define SPICTL_CSCTL1 BIT(16)
-+#define SPI1_POR BIT(1)
-+#define SPI0_POR BIT(0)
-+
-+#define RT2880_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | \
-+ SPI_CS_HIGH)
-+
-+static atomic_t hw_reset_count = ATOMIC_INIT(0);
-+
-+struct rt2880_spi {
-+ struct spi_master *master;
-+ void __iomem *base;
-+ u32 speed;
-+ u16 wait_loops;
-+ u16 mode;
-+ struct clk *clk;
-+};
-+
-+static inline struct rt2880_spi *spidev_to_rt2880_spi(struct spi_device *spi)
-+{
-+ return spi_master_get_devdata(spi->master);
-+}
-+
-+static inline u32 rt2880_spi_read(struct rt2880_spi *rs, u32 reg)
-+{
-+ return ioread32(rs->base + reg);
-+}
-+
-+static inline void rt2880_spi_write(struct rt2880_spi *rs, u32 reg,
-+ const u32 val)
-+{
-+ iowrite32(val, rs->base + reg);
-+}
-+
-+static inline void rt2880_spi_setbits(struct rt2880_spi *rs, u32 reg, u32 mask)
-+{
-+ void __iomem *addr = rs->base + reg;
-+
-+ iowrite32((ioread32(addr) | mask), addr);
-+}
-+
-+static inline void rt2880_spi_clrbits(struct rt2880_spi *rs, u32 reg, u32 mask)
-+{
-+ void __iomem *addr = rs->base + reg;
-+
-+ iowrite32((ioread32(addr) & ~mask), addr);
-+}
-+
-+static u32 rt2880_spi_baudrate_get(struct spi_device *spi, unsigned int speed)
-+{
-+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
-+ u32 rate;
-+ u32 prescale;
-+
-+ /*
-+ * the supported rates are: 2, 4, 8, ... 128
-+ * round up as we look for equal or less speed
-+ */
-+ rate = DIV_ROUND_UP(clk_get_rate(rs->clk), speed);
-+ rate = roundup_pow_of_two(rate);
-+
-+ /* Convert the rate to SPI clock divisor value. */
-+ prescale = ilog2(rate / 2);
-+
-+ /* some tolerance. double and add 100 */
-+ rs->wait_loops = (8 * HZ * loops_per_jiffy) /
-+ (clk_get_rate(rs->clk) / rate);
-+ rs->wait_loops = (rs->wait_loops << 1) + 100;
-+ rs->speed = speed;
-+
-+ dev_dbg(&spi->dev, "speed: %lu/%u, rate: %u, prescal: %u, loops: %hu\n",
-+ clk_get_rate(rs->clk) / rate, speed, rate, prescale,
-+ rs->wait_loops);
-+
-+ return prescale;
-+}
-+
-+static u32 get_arbiter_offset(struct spi_master *master)
-+{
-+ u32 offset;
-+
-+ offset = RAMIPS_SPI_ARBITER;
-+ if (master->bus_num == 1)
-+ offset -= RAMIPS_SPI_DEV_OFFSET;
-+
-+ return offset;
-+}
-+
-+static void rt2880_spi_set_cs(struct spi_device *spi, bool enable)
-+{
-+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
-+
-+ if (enable)
-+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
-+ else
-+ rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
-+}
-+
-+static int rt2880_spi_wait_ready(struct rt2880_spi *rs, int len)
-+{
-+ int loop = rs->wait_loops * len;
-+
-+ while ((rt2880_spi_read(rs, RAMIPS_SPI_STAT) & SPISTAT_BUSY) && --loop)
-+ cpu_relax();
-+
-+ if (loop)
-+ return 0;
-+
-+ return -ETIMEDOUT;
-+}
-+
-+static void rt2880_dump_reg(struct spi_master *master)
-+{
-+ struct rt2880_spi *rs = spi_master_get_devdata(master);
-+
-+ dev_dbg(&master->dev, "stat: %08x, cfg: %08x, ctl: %08x, " \
-+ "data: %08x, arb: %08x\n",
-+ rt2880_spi_read(rs, RAMIPS_SPI_STAT),
-+ rt2880_spi_read(rs, RAMIPS_SPI_CFG),
-+ rt2880_spi_read(rs, RAMIPS_SPI_CTL),
-+ rt2880_spi_read(rs, RAMIPS_SPI_DATA),
-+ rt2880_spi_read(rs, get_arbiter_offset(master)));
-+}
-+
-+static int rt2880_spi_transfer_one(struct spi_master *master,
-+ struct spi_device *spi, struct spi_transfer *xfer)
-+{
-+ struct rt2880_spi *rs = spi_master_get_devdata(master);
-+ unsigned len;
-+ const u8 *tx = xfer->tx_buf;
-+ u8 *rx = xfer->rx_buf;
-+ int err = 0;
-+
-+ /* change clock speed */
-+ if (unlikely(rs->speed != xfer->speed_hz)) {
-+ u32 reg;
-+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
-+ reg &= ~SPICFG_SPICLK_PRESCALE_MASK;
-+ reg |= rt2880_spi_baudrate_get(spi, xfer->speed_hz);
-+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
-+ }
-+
-+ if (tx) {
-+ len = xfer->len;
-+ while (len-- > 0) {
-+ rt2880_spi_write(rs, RAMIPS_SPI_DATA, *tx++);
-+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR);
-+ err = rt2880_spi_wait_ready(rs, 1);
-+ if (err) {
-+ dev_err(&spi->dev, "TX failed, err=%d\n", err);
-+ goto out;
-+ }
-+ }
-+ }
-+
-+ if (rx) {
-+ len = xfer->len;
-+ while (len-- > 0) {
-+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD);
-+ err = rt2880_spi_wait_ready(rs, 1);
-+ if (err) {
-+ dev_err(&spi->dev, "RX failed, err=%d\n", err);
-+ goto out;
-+ }
-+ *rx++ = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA);
-+ }
-+ }
-+
-+out:
-+ return err;
-+}
-+
-+/* copy from spi.c */
-+static void spi_set_cs(struct spi_device *spi, bool enable)
-+{
-+ if (spi->mode & SPI_CS_HIGH)
-+ enable = !enable;
-+
-+ if (spi->cs_gpiod)
-+ gpiod_set_value(spi->cs_gpiod, !enable);
-+ else if (spi->master->set_cs)
-+ spi->master->set_cs(spi, !enable);
-+}
-+
-+static int rt2880_spi_setup(struct spi_device *spi)
-+{
-+ struct spi_master *master = spi->master;
-+ struct rt2880_spi *rs = spi_master_get_devdata(master);
-+ u32 reg, old_reg, arbit_off;
-+
-+ if ((spi->max_speed_hz > master->max_speed_hz) ||
-+ (spi->max_speed_hz < master->min_speed_hz)) {
-+ dev_err(&spi->dev, "invalide requested speed %d Hz\n",
-+ spi->max_speed_hz);
-+ return -EINVAL;
-+ }
-+
-+ if (!(master->bits_per_word_mask &
-+ BIT(spi->bits_per_word - 1))) {
-+ dev_err(&spi->dev, "invalide bits_per_word %d\n",
-+ spi->bits_per_word);
-+ return -EINVAL;
-+ }
-+
-+ /* the hardware seems can't work on mode0 force it to mode3 */
-+ if ((spi->mode & (SPI_CPOL | SPI_CPHA)) == SPI_MODE_0) {
-+ dev_warn(&spi->dev, "force spi mode3\n");
-+ spi->mode |= SPI_MODE_3;
-+ }
-+
-+ /* chip polarity */
-+ arbit_off = get_arbiter_offset(master);
-+ reg = old_reg = rt2880_spi_read(rs, arbit_off);
-+ if (spi->mode & SPI_CS_HIGH) {
-+ switch (master->bus_num) {
-+ case 1:
-+ reg |= SPI1_POR;
-+ break;
-+ default:
-+ reg |= SPI0_POR;
-+ break;
-+ }
-+ } else {
-+ switch (master->bus_num) {
-+ case 1:
-+ reg &= ~SPI1_POR;
-+ break;
-+ default:
-+ reg &= ~SPI0_POR;
-+ break;
-+ }
-+ }
-+
-+ /* enable spi1 */
-+ if (master->bus_num == 1)
-+ reg |= SPICTL_ARB_EN;
-+
-+ if (reg != old_reg)
-+ rt2880_spi_write(rs, arbit_off, reg);
-+
-+ /* deselected the spi device */
-+ spi_set_cs(spi, false);
-+
-+ rt2880_dump_reg(master);
-+
-+ return 0;
-+}
-+
-+static int rt2880_spi_prepare_message(struct spi_master *master,
-+ struct spi_message *msg)
-+{
-+ struct rt2880_spi *rs = spi_master_get_devdata(master);
-+ struct spi_device *spi = msg->spi;
-+ u32 reg;
-+
-+ if ((rs->mode == spi->mode) && (rs->speed == spi->max_speed_hz))
-+ return 0;
-+
-+#if 0
-+ /* set spido to tri-state */
-+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO);
-+#endif
-+
-+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
-+
-+ reg &= ~(SPICFG_MSBFIRST | SPICFG_SPICLKPOL |
-+ SPICFG_RXCLKEDGE_FALLING |
-+ SPICFG_TXCLKEDGE_FALLING |
-+ SPICFG_SPICLK_PRESCALE_MASK);
-+
-+ /* MSB */
-+ if (!(spi->mode & SPI_LSB_FIRST))
-+ reg |= SPICFG_MSBFIRST;
-+
-+ /* spi mode */
-+ switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
-+ case SPI_MODE_0:
-+ reg |= SPICFG_TXCLKEDGE_FALLING;
-+ break;
-+ case SPI_MODE_1:
-+ reg |= SPICFG_RXCLKEDGE_FALLING;
-+ break;
-+ case SPI_MODE_2:
-+ reg |= SPICFG_SPICLKPOL | SPICFG_RXCLKEDGE_FALLING;
-+ break;
-+ case SPI_MODE_3:
-+ reg |= SPICFG_SPICLKPOL | SPICFG_TXCLKEDGE_FALLING;
-+ break;
-+ }
-+ rs->mode = spi->mode;
-+
-+#if 0
-+ /* set spiclk and spiena to tri-state */
-+ reg |= SPICFG_HIZSPI;
-+#endif
-+
-+ /* clock divide */
-+ reg |= rt2880_spi_baudrate_get(spi, spi->max_speed_hz);
-+
-+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
-+
-+ return 0;
-+}
-+
-+static int rt2880_spi_probe(struct platform_device *pdev)
-+{
-+ struct spi_master *master;
-+ struct rt2880_spi *rs;
-+ void __iomem *base;
-+ struct resource *r;
-+ struct clk *clk;
-+ int ret;
-+
-+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(&pdev->dev, r);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ clk = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(clk)) {
-+ dev_err(&pdev->dev, "unable to get SYS clock\n");
-+ return PTR_ERR(clk);
-+ }
-+
-+ ret = clk_prepare_enable(clk);
-+ if (ret)
-+ goto err_clk;
-+
-+ master = spi_alloc_master(&pdev->dev, sizeof(*rs));
-+ if (master == NULL) {
-+ dev_dbg(&pdev->dev, "master allocation failed\n");
-+ ret = -ENOMEM;
-+ goto err_clk;
-+ }
-+
-+ master->dev.of_node = pdev->dev.of_node;
-+ master->mode_bits = RT2880_SPI_MODE_BITS;
-+ master->bits_per_word_mask = SPI_BPW_MASK(8);
-+ master->min_speed_hz = clk_get_rate(clk) / 128;
-+ master->max_speed_hz = clk_get_rate(clk) / 2;
-+ master->flags = SPI_MASTER_HALF_DUPLEX;
-+ master->setup = rt2880_spi_setup;
-+ master->prepare_message = rt2880_spi_prepare_message;
-+ master->set_cs = rt2880_spi_set_cs;
-+ master->transfer_one = rt2880_spi_transfer_one,
-+
-+ dev_set_drvdata(&pdev->dev, master);
-+
-+ rs = spi_master_get_devdata(master);
-+ rs->master = master;
-+ rs->base = base;
-+ rs->clk = clk;
-+
-+ if (atomic_inc_return(&hw_reset_count) == 1) {
-+ ret = device_reset(&pdev->dev);
-+ if (ret) {
-+ dev_err(&pdev->dev, "device_reset error.\n");
-+ goto err_master;
-+ }
-+ }
-+
-+ ret = devm_spi_register_master(&pdev->dev, master);
-+ if (ret < 0) {
-+ dev_err(&pdev->dev, "devm_spi_register_master error.\n");
-+ goto err_master;
-+ }
-+
-+ return ret;
-+
-+err_master:
-+ spi_master_put(master);
-+ kfree(master);
-+err_clk:
-+ clk_disable_unprepare(clk);
-+
-+ return ret;
-+}
-+
-+static int rt2880_spi_remove(struct platform_device *pdev)
-+{
-+ struct spi_master *master;
-+ struct rt2880_spi *rs;
-+
-+ master = dev_get_drvdata(&pdev->dev);
-+ rs = spi_master_get_devdata(master);
-+
-+ clk_disable_unprepare(rs->clk);
-+ atomic_dec(&hw_reset_count);
-+
-+ return 0;
-+}
-+
-+MODULE_ALIAS("platform:" DRIVER_NAME);
-+
-+static const struct of_device_id rt2880_spi_match[] = {
-+ { .compatible = "ralink,rt2880-spi" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, rt2880_spi_match);
-+
-+static struct platform_driver rt2880_spi_driver = {
-+ .driver = {
-+ .name = DRIVER_NAME,
-+ .owner = THIS_MODULE,
-+ .of_match_table = rt2880_spi_match,
-+ },
-+ .probe = rt2880_spi_probe,
-+ .remove = rt2880_spi_remove,
-+};
-+
-+module_platform_driver(rt2880_spi_driver);
-+
-+MODULE_DESCRIPTION("Ralink SPI driver");
-+MODULE_AUTHOR("Sergiy <piratfm@gmail.com>");
-+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
-+MODULE_LICENSE("GPL");
+++ /dev/null
-From 723b8beaabf3c3c4b1ce69480141f1e926f3f3b2 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 27 Jul 2014 09:52:56 +0100
-Subject: [PATCH 44/53] i2c: MIPS: adds ralink I2C driver
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- .../devicetree/bindings/i2c/i2c-ralink.txt | 27 ++
- drivers/i2c/busses/Kconfig | 4 +
- drivers/i2c/busses/Makefile | 1 +
- drivers/i2c/busses/i2c-ralink.c | 327 ++++++++++++++++++++
- 4 files changed, 359 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/i2c/i2c-ralink.txt
- create mode 100644 drivers/i2c/busses/i2c-ralink.c
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt
-@@ -0,0 +1,27 @@
-+I2C for Ralink platforms
-+
-+Required properties :
-+- compatible : Must be "link,rt3052-i2c"
-+- reg: physical base address of the controller and length of memory mapped
-+ region.
-+- #address-cells = <1>;
-+- #size-cells = <0>;
-+
-+Optional properties:
-+- Child nodes conforming to i2c bus binding
-+
-+Example :
-+
-+palmbus@10000000 {
-+ i2c@900 {
-+ compatible = "link,rt3052-i2c";
-+ reg = <0x900 0x100>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ hwmon@4b {
-+ compatible = "national,lm92";
-+ reg = <0x4b>;
-+ };
-+ };
-+};
---- a/drivers/i2c/busses/Kconfig
-+++ b/drivers/i2c/busses/Kconfig
-@@ -998,6 +998,11 @@ config I2C_RK3X
- This driver can also be built as a module. If so, the module will
- be called i2c-rk3x.
-
-+config I2C_RALINK
-+ tristate "Ralink I2C Controller"
-+ depends on RALINK && !SOC_MT7621
-+ select OF_I2C
-+
- config I2C_RZV2M
- tristate "Renesas RZ/V2M adapter"
- depends on ARCH_RENESAS || COMPILE_TEST
---- a/drivers/i2c/busses/Makefile
-+++ b/drivers/i2c/busses/Makefile
-@@ -95,6 +95,7 @@ obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pc
- obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
- obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
- obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
-+obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o
- obj-$(CONFIG_I2C_QCOM_CCI) += i2c-qcom-cci.o
- obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom-geni.o
- obj-$(CONFIG_I2C_QUP) += i2c-qup.o
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-ralink.c
-@@ -0,0 +1,440 @@
-+/*
-+ * drivers/i2c/busses/i2c-ralink.c
-+ *
-+ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com>
-+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com>
-+ *
-+ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus.
-+ * (C) 2014 Sittisak <sittisaks@hotmail.com>
-+ *
-+ * 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/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/reset.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/platform_device.h>
-+#include <linux/of_platform.h>
-+#include <linux/i2c.h>
-+#include <linux/io.h>
-+#include <linux/err.h>
-+#include <linux/clk.h>
-+
-+#define REG_CONFIG_REG 0x00
-+#define REG_CLKDIV_REG 0x04
-+#define REG_DEVADDR_REG 0x08
-+#define REG_ADDR_REG 0x0C
-+#define REG_DATAOUT_REG 0x10
-+#define REG_DATAIN_REG 0x14
-+#define REG_STATUS_REG 0x18
-+#define REG_STARTXFR_REG 0x1C
-+#define REG_BYTECNT_REG 0x20
-+
-+/* REG_CONFIG_REG */
-+#define I2C_ADDRLEN_OFFSET 5
-+#define I2C_DEVADLEN_OFFSET 2
-+#define I2C_ADDRLEN_MASK 0x3
-+#define I2C_ADDR_DIS BIT(1)
-+#define I2C_DEVADDR_DIS BIT(0)
-+#define I2C_ADDRLEN_8 (7 << I2C_ADDRLEN_OFFSET)
-+#define I2C_DEVADLEN_7 (6 << I2C_DEVADLEN_OFFSET)
-+#define I2C_CONF_DEFAULT (I2C_ADDRLEN_8 | I2C_DEVADLEN_7)
-+
-+/* REG_CLKDIV_REG */
-+#define I2C_CLKDIV_MASK 0xffff
-+
-+/* REG_DEVADDR_REG */
-+#define I2C_DEVADDR_MASK 0x7f
-+
-+/* REG_ADDR_REG */
-+#define I2C_ADDR_MASK 0xff
-+
-+/* REG_STATUS_REG */
-+#define I2C_STARTERR BIT(4)
-+#define I2C_ACKERR BIT(3)
-+#define I2C_DATARDY BIT(2)
-+#define I2C_SDOEMPTY BIT(1)
-+#define I2C_BUSY BIT(0)
-+
-+/* REG_STARTXFR_REG */
-+#define NOSTOP_CMD BIT(2)
-+#define NODATA_CMD BIT(1)
-+#define READ_CMD BIT(0)
-+
-+/* REG_BYTECNT_REG */
-+#define BYTECNT_MAX 64
-+#define SET_BYTECNT(x) (x - 1)
-+
-+/* timeout waiting for I2C devices to respond (clock streching) */
-+#define TIMEOUT_MS 1000
-+#define DELAY_INTERVAL_US 100
-+
-+struct rt_i2c {
-+ void __iomem *base;
-+ struct clk *clk;
-+ struct device *dev;
-+ struct i2c_adapter adap;
-+ u32 cur_clk;
-+ u32 clk_div;
-+ u32 flags;
-+};
-+
-+static void rt_i2c_w32(struct rt_i2c *i2c, u32 val, unsigned reg)
-+{
-+ iowrite32(val, i2c->base + reg);
-+}
-+
-+static u32 rt_i2c_r32(struct rt_i2c *i2c, unsigned reg)
-+{
-+ return ioread32(i2c->base + reg);
-+}
-+
-+static int poll_down_timeout(void __iomem *addr, u32 mask)
-+{
-+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
-+
-+ do {
-+ if (!(readl_relaxed(addr) & mask))
-+ return 0;
-+
-+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
-+ } while (time_before(jiffies, timeout));
-+
-+ return (readl_relaxed(addr) & mask) ? -EAGAIN : 0;
-+}
-+
-+static int rt_i2c_wait_idle(struct rt_i2c *i2c)
-+{
-+ int ret;
-+
-+ ret = poll_down_timeout(i2c->base + REG_STATUS_REG, I2C_BUSY);
-+ if (ret < 0)
-+ dev_dbg(i2c->dev, "idle err(%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static int poll_up_timeout(void __iomem *addr, u32 mask)
-+{
-+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
-+ u32 status;
-+
-+ do {
-+ status = readl_relaxed(addr);
-+
-+ /* check error status */
-+ if (status & I2C_STARTERR)
-+ return -EAGAIN;
-+ else if (status & I2C_ACKERR)
-+ return -ENXIO;
-+ else if (status & mask)
-+ return 0;
-+
-+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
-+ } while (time_before(jiffies, timeout));
-+
-+ return -ETIMEDOUT;
-+}
-+
-+static int rt_i2c_wait_rx_done(struct rt_i2c *i2c)
-+{
-+ int ret;
-+
-+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_DATARDY);
-+ if (ret < 0)
-+ dev_dbg(i2c->dev, "rx err(%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static int rt_i2c_wait_tx_done(struct rt_i2c *i2c)
-+{
-+ int ret;
-+
-+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_SDOEMPTY);
-+ if (ret < 0)
-+ dev_dbg(i2c->dev, "tx err(%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static void rt_i2c_reset(struct rt_i2c *i2c)
-+{
-+ int ret;
-+
-+ ret = device_reset(i2c->adap.dev.parent);
-+ if (ret)
-+ dev_err(i2c->dev, "Failed to reset device");
-+
-+ barrier();
-+ rt_i2c_w32(i2c, i2c->clk_div, REG_CLKDIV_REG);
-+}
-+
-+static void rt_i2c_dump_reg(struct rt_i2c *i2c)
-+{
-+ dev_dbg(i2c->dev, "conf %08x, clkdiv %08x, devaddr %08x, " \
-+ "addr %08x, dataout %08x, datain %08x, " \
-+ "status %08x, startxfr %08x, bytecnt %08x\n",
-+ rt_i2c_r32(i2c, REG_CONFIG_REG),
-+ rt_i2c_r32(i2c, REG_CLKDIV_REG),
-+ rt_i2c_r32(i2c, REG_DEVADDR_REG),
-+ rt_i2c_r32(i2c, REG_ADDR_REG),
-+ rt_i2c_r32(i2c, REG_DATAOUT_REG),
-+ rt_i2c_r32(i2c, REG_DATAIN_REG),
-+ rt_i2c_r32(i2c, REG_STATUS_REG),
-+ rt_i2c_r32(i2c, REG_STARTXFR_REG),
-+ rt_i2c_r32(i2c, REG_BYTECNT_REG));
-+}
-+
-+static int rt_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
-+ int num)
-+{
-+ struct rt_i2c *i2c;
-+ struct i2c_msg *pmsg;
-+ unsigned char addr;
-+ int i, j, ret;
-+ u32 cmd;
-+
-+ i2c = i2c_get_adapdata(adap);
-+
-+ for (i = 0; i < num; i++) {
-+ pmsg = &msgs[i];
-+ if (i == (num - 1))
-+ cmd = 0;
-+ else
-+ cmd = NOSTOP_CMD;
-+
-+ dev_dbg(i2c->dev, "addr: 0x%x, len: %d, flags: 0x%x, stop: %d\n",
-+ pmsg->addr, pmsg->len, pmsg->flags,
-+ (cmd == 0)? 1 : 0);
-+
-+ /* wait hardware idle */
-+ if ((ret = rt_i2c_wait_idle(i2c)))
-+ goto err_timeout;
-+
-+ if (pmsg->flags & I2C_M_TEN) {
-+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT, REG_CONFIG_REG);
-+ /* 10 bits address */
-+ addr = 0x78 | ((pmsg->addr >> 8) & 0x03);
-+ rt_i2c_w32(i2c, addr & I2C_DEVADDR_MASK,
-+ REG_DEVADDR_REG);
-+ rt_i2c_w32(i2c, pmsg->addr & I2C_ADDR_MASK,
-+ REG_ADDR_REG);
-+ } else {
-+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT | I2C_ADDR_DIS,
-+ REG_CONFIG_REG);
-+ /* 7 bits address */
-+ rt_i2c_w32(i2c, pmsg->addr & I2C_DEVADDR_MASK,
-+ REG_DEVADDR_REG);
-+ }
-+
-+ /* buffer length */
-+ if (pmsg->len == 0)
-+ cmd |= NODATA_CMD;
-+ else
-+ rt_i2c_w32(i2c, SET_BYTECNT(pmsg->len),
-+ REG_BYTECNT_REG);
-+
-+ j = 0;
-+ if (pmsg->flags & I2C_M_RD) {
-+ cmd |= READ_CMD;
-+ /* start transfer */
-+ barrier();
-+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
-+ do {
-+ /* wait */
-+ if ((ret = rt_i2c_wait_rx_done(i2c)))
-+ goto err_timeout;
-+ /* read data */
-+ if (pmsg->len)
-+ pmsg->buf[j] = rt_i2c_r32(i2c,
-+ REG_DATAIN_REG);
-+ j++;
-+ } while (j < pmsg->len);
-+ } else {
-+ do {
-+ /* write data */
-+ if (pmsg->len)
-+ rt_i2c_w32(i2c, pmsg->buf[j],
-+ REG_DATAOUT_REG);
-+ /* start transfer */
-+ if (j == 0) {
-+ barrier();
-+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
-+ }
-+ /* wait */
-+ if ((ret = rt_i2c_wait_tx_done(i2c)))
-+ goto err_timeout;
-+ j++;
-+ } while (j < pmsg->len);
-+ }
-+ }
-+ /* the return value is number of executed messages */
-+ ret = i;
-+
-+ return ret;
-+
-+err_timeout:
-+ rt_i2c_dump_reg(i2c);
-+ rt_i2c_reset(i2c);
-+ return ret;
-+}
-+
-+static u32 rt_i2c_func(struct i2c_adapter *a)
-+{
-+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-+}
-+
-+static const struct i2c_algorithm rt_i2c_algo = {
-+ .master_xfer = rt_i2c_master_xfer,
-+ .functionality = rt_i2c_func,
-+};
-+
-+static const struct of_device_id i2c_rt_dt_ids[] = {
-+ { .compatible = "ralink,rt2880-i2c" },
-+ { /* sentinel */ }
-+};
-+
-+MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids);
-+
-+static struct i2c_adapter_quirks rt_i2c_quirks = {
-+ .max_write_len = BYTECNT_MAX,
-+ .max_read_len = BYTECNT_MAX,
-+};
-+
-+static int rt_i2c_init(struct rt_i2c *i2c)
-+{
-+ u32 reg;
-+
-+ /* i2c_sclk = periph_clk / ((2 * clk_div) + 5) */
-+ i2c->clk_div = (clk_get_rate(i2c->clk) - (5 * i2c->cur_clk)) /
-+ (2 * i2c->cur_clk);
-+ if (i2c->clk_div < 8)
-+ i2c->clk_div = 8;
-+ if (i2c->clk_div > I2C_CLKDIV_MASK)
-+ i2c->clk_div = I2C_CLKDIV_MASK;
-+
-+ /* check support combinde/repeated start message */
-+ rt_i2c_w32(i2c, NOSTOP_CMD, REG_STARTXFR_REG);
-+ reg = rt_i2c_r32(i2c, REG_STARTXFR_REG) & NOSTOP_CMD;
-+
-+ rt_i2c_reset(i2c);
-+
-+ return reg;
-+}
-+
-+static int rt_i2c_probe(struct platform_device *pdev)
-+{
-+ struct resource *res;
-+ struct rt_i2c *i2c;
-+ struct i2c_adapter *adap;
-+ const struct of_device_id *match;
-+ int ret, 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);
-+ if (!i2c) {
-+ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n");
-+ return -ENOMEM;
-+ }
-+
-+ i2c->base = devm_ioremap_resource(&pdev->dev, res);
-+ 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;
-+
-+ 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;
-+ i2c_set_adapdata(adap, i2c);
-+ adap->dev.of_node = pdev->dev.of_node;
-+ strlcpy(adap->name, dev_name(&pdev->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",
-+ 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;
-+}
-+
-+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_AUTHOR("Steven Liu <steven_liu@mediatek.com>");
-+MODULE_DESCRIPTION("Ralink I2c host driver");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:Ralink-I2C");
+++ /dev/null
-From 23147af14531cbdada194b94120ef8774f46292d Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 13 Nov 2014 19:08:40 +0100
-Subject: [PATCH 46/53] mmc: MIPS: ralink: add sdhci for mt7620a SoC
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/mmc/host/Kconfig | 2 +
- drivers/mmc/host/Makefile | 1 +
- drivers/mmc/host/mtk-mmc/Kconfig | 16 +
- drivers/mmc/host/mtk-mmc/Makefile | 42 +
- drivers/mmc/host/mtk-mmc/board.h | 137 ++
- drivers/mmc/host/mtk-mmc/dbg.c | 347 ++++
- drivers/mmc/host/mtk-mmc/dbg.h | 156 ++
- drivers/mmc/host/mtk-mmc/mt6575_sd.h | 1001 +++++++++++
- drivers/mmc/host/mtk-mmc/sd.c | 3060 ++++++++++++++++++++++++++++++++++
- 9 files changed, 4762 insertions(+)
- create mode 100644 drivers/mmc/host/mtk-mmc/Kconfig
- create mode 100644 drivers/mmc/host/mtk-mmc/Makefile
- create mode 100644 drivers/mmc/host/mtk-mmc/board.h
- create mode 100644 drivers/mmc/host/mtk-mmc/dbg.c
- create mode 100644 drivers/mmc/host/mtk-mmc/dbg.h
- create mode 100644 drivers/mmc/host/mtk-mmc/mt6575_sd.h
- create mode 100644 drivers/mmc/host/mtk-mmc/sd.c
-
---- a/drivers/mmc/host/Kconfig
-+++ b/drivers/mmc/host/Kconfig
-@@ -1102,6 +1102,8 @@ config MMC_OWL
- config MMC_SDHCI_EXTERNAL_DMA
- bool
-
-+source "drivers/mmc/host/mtk-mmc/Kconfig"
-+
- config MMC_LITEX
- tristate "LiteX MMC Host Controller support"
- depends on ((PPC_MICROWATT || LITEX) && OF && HAVE_CLK) || COMPILE_TEST
---- a/drivers/mmc/host/Makefile
-+++ b/drivers/mmc/host/Makefile
-@@ -3,6 +3,7 @@
- # Makefile for MMC/SD host controller drivers
- #
-
-+obj-$(CONFIG_MTK_MMC) += mtk-mmc/
- obj-$(CONFIG_MMC_ARMMMCI) += armmmci.o
- armmmci-y := mmci.o
- armmmci-$(CONFIG_MMC_QCOM_DML) += mmci_qcom_dml.o
+++ /dev/null
-From 7f29222b1731e8182ba94a331531dec18865a1e4 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 27 Jul 2014 09:31:47 +0100
-Subject: [PATCH 48/53] asoc: add mt7620 support
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/ralink/of.c | 2 +
- sound/soc/Kconfig | 1 +
- sound/soc/Makefile | 1 +
- sound/soc/ralink/Kconfig | 15 ++
- sound/soc/ralink/Makefile | 11 +
- sound/soc/ralink/mt7620-i2s.c | 436 ++++++++++++++++++++++++++++++++++++++
- sound/soc/ralink/mt7620-wm8960.c | 233 ++++++++++++++++++++
- 7 files changed, 699 insertions(+)
- create mode 100644 sound/soc/ralink/Kconfig
- create mode 100644 sound/soc/ralink/Makefile
- create mode 100644 sound/soc/ralink/mt7620-i2s.c
- create mode 100644 sound/soc/ralink/mt7620-wm8960.c
-
---- a/sound/soc/Kconfig
-+++ b/sound/soc/Kconfig
-@@ -86,6 +86,7 @@ source "sound/soc/mxs/Kconfig"
- source "sound/soc/pxa/Kconfig"
- source "sound/soc/qcom/Kconfig"
- source "sound/soc/rockchip/Kconfig"
-+source "sound/soc/ralink/Kconfig"
- source "sound/soc/samsung/Kconfig"
- source "sound/soc/sh/Kconfig"
- source "sound/soc/sof/Kconfig"
---- a/sound/soc/Makefile
-+++ b/sound/soc/Makefile
-@@ -54,6 +54,7 @@ obj-$(CONFIG_SND_SOC) += kirkwood/
- obj-$(CONFIG_SND_SOC) += pxa/
- obj-$(CONFIG_SND_SOC) += qcom/
- obj-$(CONFIG_SND_SOC) += rockchip/
-+obj-$(CONFIG_SND_SOC) += ralink/
- obj-$(CONFIG_SND_SOC) += samsung/
- obj-$(CONFIG_SND_SOC) += sh/
- obj-$(CONFIG_SND_SOC) += sof/
---- /dev/null
-+++ b/sound/soc/ralink/Kconfig
-@@ -0,0 +1,8 @@
-+config SND_RALINK_SOC_I2S
-+ depends on RALINK && SND_SOC && !SOC_RT288X
-+ select SND_SOC_GENERIC_DMAENGINE_PCM
-+ select REGMAP_MMIO
-+ tristate "SoC Audio (I2S protocol) for Ralink SoC"
-+ help
-+ Say Y if you want to use I2S protocol and I2S codec on Ralink/MediaTek
-+ based boards.
---- /dev/null
-+++ b/sound/soc/ralink/Makefile
-@@ -0,0 +1,6 @@
-+#
-+# Ralink/MediaTek Platform Support
-+#
-+snd-soc-ralink-i2s-objs := ralink-i2s.o
-+
-+obj-$(CONFIG_SND_RALINK_SOC_I2S) += snd-soc-ralink-i2s.o
---- /dev/null
-+++ b/sound/soc/ralink/ralink-i2s.c
-@@ -0,0 +1,968 @@
-+/*
-+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
-+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.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.
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/clk.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/debugfs.h>
-+#include <linux/of_device.h>
-+#include <sound/pcm_params.h>
-+#include <sound/dmaengine_pcm.h>
-+
-+#include <asm/mach-ralink/ralink_regs.h>
-+
-+#define DRV_NAME "ralink-i2s"
-+
-+#define I2S_REG_CFG0 0x00
-+#define I2S_REG_INT_STATUS 0x04
-+#define I2S_REG_INT_EN 0x08
-+#define I2S_REG_FF_STATUS 0x0c
-+#define I2S_REG_WREG 0x10
-+#define I2S_REG_RREG 0x14
-+#define I2S_REG_CFG1 0x18
-+#define I2S_REG_DIVCMP 0x20
-+#define I2S_REG_DIVINT 0x24
-+
-+/* I2S_REG_CFG0 */
-+#define I2S_REG_CFG0_EN BIT(31)
-+#define I2S_REG_CFG0_DMA_EN BIT(30)
-+#define I2S_REG_CFG0_BYTE_SWAP BIT(28)
-+#define I2S_REG_CFG0_TX_EN BIT(24)
-+#define I2S_REG_CFG0_RX_EN BIT(20)
-+#define I2S_REG_CFG0_SLAVE BIT(16)
-+#define I2S_REG_CFG0_RX_THRES 12
-+#define I2S_REG_CFG0_TX_THRES 4
-+#define I2S_REG_CFG0_THRES_MASK (0xf << I2S_REG_CFG0_RX_THRES) | \
-+ (4 << I2S_REG_CFG0_TX_THRES)
-+#define I2S_REG_CFG0_DFT_THRES (4 << I2S_REG_CFG0_RX_THRES) | \
-+ (4 << I2S_REG_CFG0_TX_THRES)
-+/* RT305x */
-+#define I2S_REG_CFG0_CLK_DIS BIT(8)
-+#define I2S_REG_CFG0_TXCH_SWAP BIT(3)
-+#define I2S_REG_CFG0_TXCH1_OFF BIT(2)
-+#define I2S_REG_CFG0_TXCH0_OFF BIT(1)
-+#define I2S_REG_CFG0_SLAVE_EN BIT(0)
-+/* RT3883 */
-+#define I2S_REG_CFG0_RXCH_SWAP BIT(11)
-+#define I2S_REG_CFG0_RXCH1_OFF BIT(10)
-+#define I2S_REG_CFG0_RXCH0_OFF BIT(9)
-+#define I2S_REG_CFG0_WS_INV BIT(0)
-+/* MT7628 */
-+#define I2S_REG_CFG0_FMT_LE BIT(29)
-+#define I2S_REG_CFG0_SYS_BE BIT(28)
-+#define I2S_REG_CFG0_NORM_24 BIT(18)
-+#define I2S_REG_CFG0_DATA_24 BIT(17)
-+
-+/* I2S_REG_INT_STATUS */
-+#define I2S_REG_INT_RX_FAULT BIT(7)
-+#define I2S_REG_INT_RX_OVRUN BIT(6)
-+#define I2S_REG_INT_RX_UNRUN BIT(5)
-+#define I2S_REG_INT_RX_THRES BIT(4)
-+#define I2S_REG_INT_TX_FAULT BIT(3)
-+#define I2S_REG_INT_TX_OVRUN BIT(2)
-+#define I2S_REG_INT_TX_UNRUN BIT(1)
-+#define I2S_REG_INT_TX_THRES BIT(0)
-+#define I2S_REG_INT_TX_MASK 0xf
-+#define I2S_REG_INT_RX_MASK 0xf0
-+
-+/* I2S_REG_INT_STATUS */
-+#define I2S_RX_AVCNT(x) ((x >> 4) & 0xf)
-+#define I2S_TX_AVCNT(x) (x & 0xf)
-+/* MT7628 */
-+#define MT7628_I2S_RX_AVCNT(x) ((x >> 8) & 0x1f)
-+#define MT7628_I2S_TX_AVCNT(x) (x & 0x1f)
-+
-+/* I2S_REG_CFG1 */
-+#define I2S_REG_CFG1_LBK BIT(31)
-+#define I2S_REG_CFG1_EXTLBK BIT(30)
-+/* RT3883 */
-+#define I2S_REG_CFG1_LEFT_J BIT(0)
-+#define I2S_REG_CFG1_RIGHT_J BIT(1)
-+#define I2S_REG_CFG1_FMT_MASK 0x3
-+
-+/* I2S_REG_DIVCMP */
-+#define I2S_REG_DIVCMP_CLKEN BIT(31)
-+#define I2S_REG_DIVCMP_DIVCOMP_MASK 0x1ff
-+
-+/* I2S_REG_DIVINT */
-+#define I2S_REG_DIVINT_MASK 0x3ff
-+
-+/* BCLK dividers */
-+#define RALINK_I2S_DIVCMP 0
-+#define RALINK_I2S_DIVINT 1
-+
-+/* FIFO */
-+#define RALINK_I2S_FIFO_SIZE 32
-+
-+/* feature flags */
-+#define RALINK_FLAGS_TXONLY BIT(0)
-+#define RALINK_FLAGS_LEFT_J BIT(1)
-+#define RALINK_FLAGS_RIGHT_J BIT(2)
-+#define RALINK_FLAGS_ENDIAN BIT(3)
-+#define RALINK_FLAGS_24BIT BIT(4)
-+
-+#define RALINK_I2S_INT_EN 0
-+
-+struct ralink_i2s_stats {
-+ u32 dmafault;
-+ u32 overrun;
-+ u32 underrun;
-+ u32 belowthres;
-+};
-+
-+struct ralink_i2s {
-+ struct device *dev;
-+ void __iomem *regs;
-+ struct clk *clk;
-+ struct regmap *regmap;
-+ u32 flags;
-+ unsigned int fmt;
-+ u16 txdma_req;
-+ u16 rxdma_req;
-+
-+ struct snd_dmaengine_dai_dma_data playback_dma_data;
-+ struct snd_dmaengine_dai_dma_data capture_dma_data;
-+
-+ struct dentry *dbg_dir;
-+ struct dentry *dbg_stats;
-+ struct ralink_i2s_stats txstats;
-+ struct ralink_i2s_stats rxstats;
-+};
-+
-+static void ralink_i2s_dump_regs(struct ralink_i2s *i2s)
-+{
-+ u32 buf[10];
-+ int ret;
-+
-+ ret = regmap_bulk_read(i2s->regmap, I2S_REG_CFG0,
-+ buf, ARRAY_SIZE(buf));
-+
-+ dev_dbg(i2s->dev, "CFG0: %08x, INTSTAT: %08x, INTEN: %08x, " \
-+ "FFSTAT: %08x, WREG: %08x, RREG: %08x, " \
-+ "CFG1: %08x, DIVCMP: %08x, DIVINT: %08x\n",
-+ buf[0], buf[1], buf[2], buf[3], buf[4],
-+ buf[5], buf[6], buf[8], buf[9]);
-+}
-+
-+static int ralink_i2s_set_sysclk(struct snd_soc_dai *dai,
-+ int clk_id, unsigned int freq, int dir)
-+{
-+ return 0;
-+}
-+
-+static int ralink_i2s_set_sys_bclk(struct snd_soc_dai *dai, int width, int rate)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ unsigned long clk = clk_get_rate(i2s->clk);
-+ int div;
-+ uint32_t data;
-+
-+ /* disable clock at slave mode */
-+ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
-+ SND_SOC_DAIFMT_CBM_CFM) {
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_CLK_DIS,
-+ I2S_REG_CFG0_CLK_DIS);
-+ return 0;
-+ }
-+
-+ /* FREQOUT = FREQIN / (I2S_CLK_DIV + 1) */
-+ div = (clk / rate ) - 1;
-+
-+ data = rt_sysc_r32(0x30);
-+ data &= (0xff << 8);
-+ data |= (0x1 << 15) | (div << 8);
-+ rt_sysc_w32(data, 0x30);
-+
-+ /* enable clock */
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_CLK_DIS, 0);
-+
-+ dev_dbg(i2s->dev, "clk: %lu, rate: %u, div: %d\n",
-+ clk, rate, div);
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_set_bclk(struct snd_soc_dai *dai, int width, int rate)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ unsigned long clk = clk_get_rate(i2s->clk);
-+ int divint, divcomp;
-+
-+ /* disable clock at slave mode */
-+ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
-+ SND_SOC_DAIFMT_CBM_CFM) {
-+ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP,
-+ I2S_REG_DIVCMP_CLKEN, 0);
-+ return 0;
-+ }
-+
-+ /* FREQOUT = FREQIN * (1/2) * (1/(DIVINT + DIVCOMP/512)) */
-+ clk = clk / (2 * 2 * width);
-+ divint = clk / rate;
-+ divcomp = ((clk % rate) * 512) / rate;
-+
-+ if ((divint > I2S_REG_DIVINT_MASK) ||
-+ (divcomp > I2S_REG_DIVCMP_DIVCOMP_MASK))
-+ return -EINVAL;
-+
-+ regmap_update_bits(i2s->regmap, I2S_REG_DIVINT,
-+ I2S_REG_DIVINT_MASK, divint);
-+ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP,
-+ I2S_REG_DIVCMP_DIVCOMP_MASK, divcomp);
-+
-+ /* enable clock */
-+ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, I2S_REG_DIVCMP_CLKEN,
-+ I2S_REG_DIVCMP_CLKEN);
-+
-+ dev_dbg(i2s->dev, "clk: %lu, rate: %u, int: %d, comp: %d\n",
-+ clk_get_rate(i2s->clk), rate, divint, divcomp);
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ unsigned int cfg0 = 0, cfg1 = 0;
-+
-+ /* set master/slave audio interface */
-+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-+ case SND_SOC_DAIFMT_CBM_CFM:
-+ if (i2s->flags & RALINK_FLAGS_TXONLY)
-+ cfg0 |= I2S_REG_CFG0_SLAVE_EN;
-+ else
-+ cfg0 |= I2S_REG_CFG0_SLAVE;
-+ break;
-+ case SND_SOC_DAIFMT_CBS_CFS:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ /* interface format */
-+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-+ case SND_SOC_DAIFMT_I2S:
-+ break;
-+ case SND_SOC_DAIFMT_RIGHT_J:
-+ if (i2s->flags & RALINK_FLAGS_RIGHT_J) {
-+ cfg1 |= I2S_REG_CFG1_RIGHT_J;
-+ break;
-+ }
-+ return -EINVAL;
-+ case SND_SOC_DAIFMT_LEFT_J:
-+ if (i2s->flags & RALINK_FLAGS_LEFT_J) {
-+ cfg1 |= I2S_REG_CFG1_LEFT_J;
-+ break;
-+ }
-+ return -EINVAL;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ /* clock inversion */
-+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
-+ case SND_SOC_DAIFMT_NB_NF:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (i2s->flags & RALINK_FLAGS_TXONLY) {
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_SLAVE_EN, cfg0);
-+ } else {
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_SLAVE, cfg0);
-+ }
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG1,
-+ I2S_REG_CFG1_FMT_MASK, cfg1);
-+ i2s->fmt = fmt;
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_startup(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+
-+ if (snd_soc_dai_active(dai))
-+ return 0;
-+
-+ /* setup status interrupt */
-+#if (RALINK_I2S_INT_EN)
-+ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0xff);
-+#else
-+ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0x0);
-+#endif
-+
-+ /* enable */
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN |
-+ I2S_REG_CFG0_THRES_MASK,
-+ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN |
-+ I2S_REG_CFG0_DFT_THRES);
-+
-+ return 0;
-+}
-+
-+static void ralink_i2s_shutdown(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+
-+ /* If both streams are stopped, disable module and clock */
-+ if (snd_soc_dai_active(dai))
-+ return;
-+
-+ /*
-+ * datasheet mention when disable all control regs are cleared
-+ * to initial values. need reinit at startup.
-+ */
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_EN, 0);
-+}
-+
-+static int ralink_i2s_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ int width;
-+ int ret;
-+
-+ width = params_width(params);
-+ switch (width) {
-+ case 16:
-+ if (i2s->flags & RALINK_FLAGS_24BIT)
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_DATA_24, 0);
-+ break;
-+ case 24:
-+ if (i2s->flags & RALINK_FLAGS_24BIT) {
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_DATA_24,
-+ I2S_REG_CFG0_DATA_24);
-+ break;
-+ }
-+ return -EINVAL;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ switch (params_channels(params)) {
-+ case 2:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (i2s->flags & RALINK_FLAGS_ENDIAN) {
-+ /* system endian */
-+#ifdef SNDRV_LITTLE_ENDIAN
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_SYS_BE, 0);
-+#else
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_SYS_BE,
-+ I2S_REG_CFG0_SYS_BE);
-+#endif
-+
-+ /* data endian */
-+ switch (params_format(params)) {
-+ case SNDRV_PCM_FORMAT_S16_LE:
-+ case SNDRV_PCM_FORMAT_S24_LE:
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_FMT_LE,
-+ I2S_REG_CFG0_FMT_LE);
-+ break;
-+ case SNDRV_PCM_FORMAT_S16_BE:
-+ case SNDRV_PCM_FORMAT_S24_BE:
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_FMT_LE, 0);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+
-+ /* setup bclk rate */
-+ if (i2s->flags & RALINK_FLAGS_TXONLY)
-+ ret = ralink_i2s_set_sys_bclk(dai, width, params_rate(params));
-+ else
-+ ret = ralink_i2s_set_bclk(dai, width, params_rate(params));
-+
-+ return ret;
-+}
-+
-+static int ralink_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
-+ struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ unsigned int mask, val;
-+
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-+ mask = I2S_REG_CFG0_TX_EN;
-+ else
-+ mask = I2S_REG_CFG0_RX_EN;
-+
-+ switch (cmd) {
-+ case SNDRV_PCM_TRIGGER_START:
-+ case SNDRV_PCM_TRIGGER_RESUME:
-+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-+ val = mask;
-+ break;
-+ case SNDRV_PCM_TRIGGER_STOP:
-+ case SNDRV_PCM_TRIGGER_SUSPEND:
-+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-+ val = 0;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, mask, val);
-+
-+ return 0;
-+}
-+
-+static void ralink_i2s_init_dma_data(struct ralink_i2s *i2s,
-+ struct resource *res)
-+{
-+ struct snd_dmaengine_dai_dma_data *dma_data;
-+
-+ /* Playback */
-+ dma_data = &i2s->playback_dma_data;
-+ dma_data->addr = res->start + I2S_REG_WREG;
-+ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-+ dma_data->maxburst = 1;
-+
-+ if (i2s->flags & RALINK_FLAGS_TXONLY)
-+ return;
-+
-+ /* Capture */
-+ dma_data = &i2s->capture_dma_data;
-+ dma_data->addr = res->start + I2S_REG_RREG;
-+ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-+ dma_data->maxburst = 1;
-+}
-+
-+static int ralink_i2s_dai_probe(struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+
-+ snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
-+ &i2s->capture_dma_data);
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_dai_remove(struct snd_soc_dai *dai)
-+{
-+ return 0;
-+}
-+
-+static const struct snd_soc_dai_ops ralink_i2s_dai_ops = {
-+ .set_sysclk = ralink_i2s_set_sysclk,
-+ .set_fmt = ralink_i2s_set_fmt,
-+ .startup = ralink_i2s_startup,
-+ .shutdown = ralink_i2s_shutdown,
-+ .hw_params = ralink_i2s_hw_params,
-+ .trigger = ralink_i2s_trigger,
-+};
-+
-+static struct snd_soc_dai_driver ralink_i2s_dai = {
-+ .name = DRV_NAME,
-+ .probe = ralink_i2s_dai_probe,
-+ .remove = ralink_i2s_dai_remove,
-+ .ops = &ralink_i2s_dai_ops,
-+ .capture = {
-+ .stream_name = "I2S Capture",
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .rate_min = 5512,
-+ .rate_max = 192000,
-+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
-+ },
-+ .playback = {
-+ .stream_name = "I2S Playback",
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .rate_min = 5512,
-+ .rate_max = 192000,
-+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
-+ },
-+ .symmetric_rate = 1,
-+};
-+
-+static struct snd_pcm_hardware ralink_pcm_hardware = {
-+ .info = SNDRV_PCM_INFO_MMAP |
-+ SNDRV_PCM_INFO_MMAP_VALID |
-+ SNDRV_PCM_INFO_INTERLEAVED |
-+ SNDRV_PCM_INFO_BLOCK_TRANSFER,
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .period_bytes_min = PAGE_SIZE,
-+ .period_bytes_max = PAGE_SIZE * 2,
-+ .periods_min = 2,
-+ .periods_max = 128,
-+ .buffer_bytes_max = 128 * 1024,
-+ .fifo_size = RALINK_I2S_FIFO_SIZE,
-+};
-+
-+static const struct snd_dmaengine_pcm_config ralink_dmaengine_pcm_config = {
-+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-+ .pcm_hardware = &ralink_pcm_hardware,
-+ .prealloc_buffer_size = 256 * PAGE_SIZE,
-+};
-+
-+static const struct snd_soc_component_driver ralink_i2s_component = {
-+ .name = DRV_NAME,
-+};
-+
-+static bool ralink_i2s_readable_reg(struct device *dev, unsigned int reg)
-+{
-+ return true;
-+}
-+
-+static bool ralink_i2s_volatile_reg(struct device *dev, unsigned int reg)
-+{
-+ switch (reg) {
-+ case I2S_REG_INT_STATUS:
-+ case I2S_REG_FF_STATUS:
-+ return true;
-+ }
-+ return false;
-+}
-+
-+static bool ralink_i2s_writeable_reg(struct device *dev, unsigned int reg)
-+{
-+ switch (reg) {
-+ case I2S_REG_FF_STATUS:
-+ case I2S_REG_RREG:
-+ return false;
-+ }
-+ return true;
-+}
-+
-+static const struct regmap_config ralink_i2s_regmap_config = {
-+ .reg_bits = 32,
-+ .reg_stride = 4,
-+ .val_bits = 32,
-+ .writeable_reg = ralink_i2s_writeable_reg,
-+ .readable_reg = ralink_i2s_readable_reg,
-+ .volatile_reg = ralink_i2s_volatile_reg,
-+ .max_register = I2S_REG_DIVINT,
-+};
-+
-+#if (RALINK_I2S_INT_EN)
-+static irqreturn_t ralink_i2s_irq(int irq, void *devid)
-+{
-+ struct ralink_i2s *i2s = devid;
-+ u32 status;
-+
-+ regmap_read(i2s->regmap, I2S_REG_INT_STATUS, &status);
-+ if (unlikely(!status))
-+ return IRQ_NONE;
-+
-+ /* tx stats */
-+ if (status & I2S_REG_INT_TX_MASK) {
-+ if (status & I2S_REG_INT_TX_THRES)
-+ i2s->txstats.belowthres++;
-+ if (status & I2S_REG_INT_TX_UNRUN)
-+ i2s->txstats.underrun++;
-+ if (status & I2S_REG_INT_TX_OVRUN)
-+ i2s->txstats.overrun++;
-+ if (status & I2S_REG_INT_TX_FAULT)
-+ i2s->txstats.dmafault++;
-+ }
-+
-+ /* rx stats */
-+ if (status & I2S_REG_INT_RX_MASK) {
-+ if (status & I2S_REG_INT_RX_THRES)
-+ i2s->rxstats.belowthres++;
-+ if (status & I2S_REG_INT_RX_UNRUN)
-+ i2s->rxstats.underrun++;
-+ if (status & I2S_REG_INT_RX_OVRUN)
-+ i2s->rxstats.overrun++;
-+ if (status & I2S_REG_INT_RX_FAULT)
-+ i2s->rxstats.dmafault++;
-+ }
-+
-+ /* clean status bits */
-+ regmap_write(i2s->regmap, I2S_REG_INT_STATUS, status);
-+
-+ return IRQ_HANDLED;
-+}
-+#endif
-+
-+#if IS_ENABLED(CONFIG_DEBUG_FS)
-+static int ralink_i2s_stats_show(struct seq_file *s, void *unused)
-+{
-+ struct ralink_i2s *i2s = s->private;
-+
-+ seq_printf(s, "tx stats\n");
-+ seq_printf(s, "\tbelow threshold\t%u\n", i2s->txstats.belowthres);
-+ seq_printf(s, "\tunder run\t%u\n", i2s->txstats.underrun);
-+ seq_printf(s, "\tover run\t%u\n", i2s->txstats.overrun);
-+ seq_printf(s, "\tdma fault\t%u\n", i2s->txstats.dmafault);
-+
-+ seq_printf(s, "rx stats\n");
-+ seq_printf(s, "\tbelow threshold\t%u\n", i2s->rxstats.belowthres);
-+ seq_printf(s, "\tunder run\t%u\n", i2s->rxstats.underrun);
-+ seq_printf(s, "\tover run\t%u\n", i2s->rxstats.overrun);
-+ seq_printf(s, "\tdma fault\t%u\n", i2s->rxstats.dmafault);
-+
-+ ralink_i2s_dump_regs(i2s);
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_stats_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, ralink_i2s_stats_show, inode->i_private);
-+}
-+
-+static const struct file_operations ralink_i2s_stats_ops = {
-+ .open = ralink_i2s_stats_open,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+ .release = single_release,
-+};
-+
-+static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s)
-+{
-+ i2s->dbg_dir = debugfs_create_dir(dev_name(i2s->dev), NULL);
-+ if (!i2s->dbg_dir)
-+ return -ENOMEM;
-+
-+ i2s->dbg_stats = debugfs_create_file("stats", S_IRUGO,
-+ i2s->dbg_dir, i2s, &ralink_i2s_stats_ops);
-+ if (!i2s->dbg_stats) {
-+ debugfs_remove(i2s->dbg_dir);
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-+
-+static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s)
-+{
-+ debugfs_remove(i2s->dbg_stats);
-+ debugfs_remove(i2s->dbg_dir);
-+}
-+#else
-+static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s)
-+{
-+ return 0;
-+}
-+
-+static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s)
-+{
-+}
-+#endif
-+
-+/*
-+ * TODO: these refclk setup functions should use
-+ * clock framework instead. hardcode it now.
-+ */
-+static void rt3350_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data |= (0x1 << 8);
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void rt3883_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0x3 << 13);
-+ data |= (0x1 << 13);
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void rt3552_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0xf << 8);
-+ data |= (0x3 << 8);
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void mt7620_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0x7 << 9);
-+ data |= 0x1 << 9;
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void mt7621_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0x1f << 18);
-+ data |= (0x19 << 18);
-+ data &= ~(0x1f << 12);
-+ data |= (0x1 << 12);
-+ data &= ~(0x7 << 9);
-+ data |= (0x5 << 9);
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void mt7628_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set i2s and refclk digital pad */
-+ data = rt_sysc_r32(0x3c);
-+ data |= 0x1f;
-+ rt_sysc_w32(data, 0x3c);
-+
-+ /* Adjust REFCLK0's driving strength */
-+ data = rt_sysc_r32(0x1354);
-+ data &= ~(0x1 << 5);
-+ rt_sysc_w32(data, 0x1354);
-+ data = rt_sysc_r32(0x1364);
-+ data |= ~(0x1 << 5);
-+ rt_sysc_w32(data, 0x1364);
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0x7 << 9);
-+ data |= 0x1 << 9;
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+struct rt_i2s_data {
-+ u32 flags;
-+ void (*refclk_setup)(void);
-+};
-+
-+struct rt_i2s_data rt3050_i2s_data = { .flags = RALINK_FLAGS_TXONLY };
-+struct rt_i2s_data rt3350_i2s_data = { .flags = RALINK_FLAGS_TXONLY,
-+ .refclk_setup = rt3350_refclk_setup };
-+struct rt_i2s_data rt3883_i2s_data = {
-+ .flags = (RALINK_FLAGS_LEFT_J | RALINK_FLAGS_RIGHT_J),
-+ .refclk_setup = rt3883_refclk_setup };
-+struct rt_i2s_data rt3352_i2s_data = { .refclk_setup = rt3552_refclk_setup};
-+struct rt_i2s_data mt7620_i2s_data = { .refclk_setup = mt7620_refclk_setup};
-+struct rt_i2s_data mt7621_i2s_data = { .refclk_setup = mt7621_refclk_setup};
-+struct rt_i2s_data mt7628_i2s_data = {
-+ .flags = (RALINK_FLAGS_ENDIAN | RALINK_FLAGS_24BIT |
-+ RALINK_FLAGS_LEFT_J),
-+ .refclk_setup = mt7628_refclk_setup};
-+
-+static const struct of_device_id ralink_i2s_match_table[] = {
-+ { .compatible = "ralink,rt3050-i2s",
-+ .data = (void *)&rt3050_i2s_data },
-+ { .compatible = "ralink,rt3350-i2s",
-+ .data = (void *)&rt3350_i2s_data },
-+ { .compatible = "ralink,rt3883-i2s",
-+ .data = (void *)&rt3883_i2s_data },
-+ { .compatible = "ralink,rt3352-i2s",
-+ .data = (void *)&rt3352_i2s_data },
-+ { .compatible = "mediatek,mt7620-i2s",
-+ .data = (void *)&mt7620_i2s_data },
-+ { .compatible = "mediatek,mt7621-i2s",
-+ .data = (void *)&mt7621_i2s_data },
-+ { .compatible = "mediatek,mt7628-i2s",
-+ .data = (void *)&mt7628_i2s_data },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ralink_i2s_match_table);
-+
-+static int ralink_i2s_probe(struct platform_device *pdev)
-+{
-+ const struct of_device_id *match;
-+ struct device_node *np = pdev->dev.of_node;
-+ struct ralink_i2s *i2s;
-+ struct resource *res;
-+ int irq, ret;
-+ u32 dma_req;
-+ struct rt_i2s_data *data;
-+
-+ i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
-+ if (!i2s)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, i2s);
-+ i2s->dev = &pdev->dev;
-+
-+ match = of_match_device(ralink_i2s_match_table, &pdev->dev);
-+ if (!match)
-+ return -EINVAL;
-+ data = (struct rt_i2s_data *)match->data;
-+ i2s->flags = data->flags;
-+ /* setup out 12Mhz refclk to codec as mclk */
-+ if (data->refclk_setup)
-+ data->refclk_setup();
-+
-+ if (of_property_read_u32(np, "txdma-req", &dma_req)) {
-+ dev_err(&pdev->dev, "no txdma-req define\n");
-+ return -EINVAL;
-+ }
-+ i2s->txdma_req = (u16)dma_req;
-+ if (!(i2s->flags & RALINK_FLAGS_TXONLY)) {
-+ if (of_property_read_u32(np, "rxdma-req", &dma_req)) {
-+ dev_err(&pdev->dev, "no rxdma-req define\n");
-+ return -EINVAL;
-+ }
-+ i2s->rxdma_req = (u16)dma_req;
-+ }
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ i2s->regs = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(i2s->regs))
-+ return PTR_ERR(i2s->regs);
-+
-+ i2s->regmap = devm_regmap_init_mmio(&pdev->dev, i2s->regs,
-+ &ralink_i2s_regmap_config);
-+ if (IS_ERR(i2s->regmap)) {
-+ dev_err(&pdev->dev, "regmap init failed\n");
-+ return PTR_ERR(i2s->regmap);
-+ }
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0) {
-+ dev_err(&pdev->dev, "failed to get irq\n");
-+ return -EINVAL;
-+ }
-+
-+#if (RALINK_I2S_INT_EN)
-+ ret = devm_request_irq(&pdev->dev, irq, ralink_i2s_irq,
-+ 0, dev_name(&pdev->dev), i2s);
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to request irq\n");
-+ return ret;
-+ }
-+#endif
-+
-+ i2s->clk = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(i2s->clk)) {
-+ dev_err(&pdev->dev, "no clock defined\n");
-+ return PTR_ERR(i2s->clk);
-+ }
-+
-+ ret = clk_prepare_enable(i2s->clk);
-+ if (ret)
-+ return ret;
-+
-+ ralink_i2s_init_dma_data(i2s, res);
-+
-+ ret = device_reset(&pdev->dev);
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to reset device\n");
-+ goto err_clk_disable;
-+ }
-+
-+ ret = ralink_i2s_debugfs_create(i2s);
-+ if (ret) {
-+ dev_err(&pdev->dev, "create debugfs failed\n");
-+ goto err_clk_disable;
-+ }
-+
-+ /* enable 24bits support */
-+ if (i2s->flags & RALINK_FLAGS_24BIT) {
-+ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S24_LE;
-+ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S24_LE;
-+ }
-+
-+ /* enable big endian support */
-+ if (i2s->flags & RALINK_FLAGS_ENDIAN) {
-+ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S16_BE;
-+ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S16_BE;
-+ ralink_pcm_hardware.formats |= SNDRV_PCM_FMTBIT_S16_BE;
-+ if (i2s->flags & RALINK_FLAGS_24BIT) {
-+ ralink_i2s_dai.capture.formats |=
-+ SNDRV_PCM_FMTBIT_S24_BE;
-+ ralink_i2s_dai.playback.formats |=
-+ SNDRV_PCM_FMTBIT_S24_BE;
-+ ralink_pcm_hardware.formats |=
-+ SNDRV_PCM_FMTBIT_S24_BE;
-+ }
-+ }
-+
-+ /* disable capture support */
-+ if (i2s->flags & RALINK_FLAGS_TXONLY)
-+ memset(&ralink_i2s_dai.capture, sizeof(ralink_i2s_dai.capture),
-+ 0);
-+
-+ ret = devm_snd_soc_register_component(&pdev->dev, &ralink_i2s_component,
-+ &ralink_i2s_dai, 1);
-+ if (ret)
-+ goto err_debugfs;
-+
-+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
-+ &ralink_dmaengine_pcm_config,
-+ SND_DMAENGINE_PCM_FLAG_COMPAT);
-+ if (ret)
-+ goto err_debugfs;
-+
-+ dev_info(i2s->dev, "mclk %luMHz\n", clk_get_rate(i2s->clk) / 1000000);
-+
-+ return 0;
-+
-+err_debugfs:
-+ ralink_i2s_debugfs_remove(i2s);
-+
-+err_clk_disable:
-+ clk_disable_unprepare(i2s->clk);
-+
-+ return ret;
-+}
-+
-+static int ralink_i2s_remove(struct platform_device *pdev)
-+{
-+ struct ralink_i2s *i2s = platform_get_drvdata(pdev);
-+
-+ ralink_i2s_debugfs_remove(i2s);
-+ clk_disable_unprepare(i2s->clk);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver ralink_i2s_driver = {
-+ .probe = ralink_i2s_probe,
-+ .remove = ralink_i2s_remove,
-+ .driver = {
-+ .name = DRV_NAME,
-+ .of_match_table = ralink_i2s_match_table,
-+ },
-+};
-+module_platform_driver(ralink_i2s_driver);
-+
-+MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
-+MODULE_DESCRIPTION("Ralink/MediaTek I2S driver");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:" DRV_NAME);
+++ /dev/null
-From a7eb46e0ea4a11e4dfb56ab129bf816d1059a6c5 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 7 Dec 2015 17:31:08 +0100
-Subject: [PATCH 51/53] serial: add ugly custom baud rate hack
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/tty/serial/serial_core.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/tty/serial/serial_core.c
-+++ b/drivers/tty/serial/serial_core.c
-@@ -445,6 +445,9 @@ uart_get_baud_rate(struct uart_port *por
- break;
- }
-
-+ if (tty_termios_baud_rate(termios) == 2500000)
-+ return 250000;
-+
- for (try = 0; try < 2; try++) {
- baud = tty_termios_baud_rate(termios);
-
+++ /dev/null
-From fc8f96309c21c1bc3276427309cd7d361347d66e Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 7 Dec 2015 17:16:50 +0100
-Subject: [PATCH 52/53] pwm: add mediatek support
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/pwm/Kconfig | 9 +++
- drivers/pwm/Makefile | 1 +
- drivers/pwm/pwm-mediatek.c | 173 ++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 183 insertions(+)
- create mode 100644 drivers/pwm/pwm-mediatek.c
-
---- a/drivers/pwm/Kconfig
-+++ b/drivers/pwm/Kconfig
-@@ -393,6 +393,15 @@ config PWM_MEDIATEK
- To compile this driver as a module, choose M here: the module
- will be called pwm-mediatek.
-
-+config PWM_MEDIATEK_RAMIPS
-+ tristate "Mediatek PWM support"
-+ depends on RALINK && OF
-+ help
-+ Generic PWM framework driver for Mediatek ARM SoC.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called pwm-mxs.
-+
- config PWM_MXS
- tristate "Freescale MXS PWM support"
- depends on ARCH_MXS || COMPILE_TEST
---- a/drivers/pwm/Makefile
-+++ b/drivers/pwm/Makefile
-@@ -34,6 +34,7 @@ obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-p
- obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
- obj-$(CONFIG_PWM_MESON) += pwm-meson.o
- obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o
-+obj-$(CONFIG_PWM_MEDIATEK_RAMIPS) += pwm-mediatek-ramips.o
- obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
- obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
- obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o
---- /dev/null
-+++ b/drivers/pwm/pwm-mediatek-ramips.c
-@@ -0,0 +1,197 @@
-+/*
-+ * Mediatek Pulse Width Modulator driver
-+ *
-+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2. This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/ioport.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pwm.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+
-+#define NUM_PWM 4
-+
-+/* PWM registers and bits definitions */
-+#define PWMCON 0x00
-+#define PWMHDUR 0x04
-+#define PWMLDUR 0x08
-+#define PWMGDUR 0x0c
-+#define PWMWAVENUM 0x28
-+#define PWMDWIDTH 0x2c
-+#define PWMTHRES 0x30
-+
-+/**
-+ * struct mtk_pwm_chip - struct representing pwm chip
-+ *
-+ * @mmio_base: base address of pwm chip
-+ * @chip: linux pwm chip representation
-+ */
-+struct mtk_pwm_chip {
-+ void __iomem *mmio_base;
-+ struct pwm_chip chip;
-+};
-+
-+static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
-+{
-+ return container_of(chip, struct mtk_pwm_chip, chip);
-+}
-+
-+static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
-+ unsigned long offset)
-+{
-+ return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset);
-+}
-+
-+static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
-+ unsigned int num, unsigned long offset,
-+ unsigned long val)
-+{
-+ iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset);
-+}
-+
-+static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-+ int duty_ns, int period_ns)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 resolution = 100 / 4;
-+ u32 clkdiv = 0;
-+
-+ while (period_ns / resolution > 8191) {
-+ clkdiv++;
-+ resolution *= 2;
-+ }
-+
-+ if (clkdiv > 7)
-+ return -1;
-+
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv);
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);
-+ return 0;
-+}
-+
-+static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 val;
-+
-+ val = ioread32(pc->mmio_base);
-+ val |= BIT(pwm->hwpwm);
-+ iowrite32(val, pc->mmio_base);
-+
-+ return 0;
-+}
-+
-+static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 val;
-+
-+ val = ioread32(pc->mmio_base);
-+ val &= ~BIT(pwm->hwpwm);
-+ iowrite32(val, pc->mmio_base);
-+}
-+
-+static int mtk_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
-+ const struct pwm_state *state)
-+{
-+ int err;
-+ bool enabled = pwm->state.enabled;
-+
-+ if (!state->enabled) {
-+ if (enabled)
-+ mtk_pwm_disable(chip, pwm);
-+
-+ return 0;
-+ }
-+
-+ err = mtk_pwm_config(pwm->chip, pwm,
-+ state->duty_cycle, state->period);
-+ if (err)
-+ return err;
-+
-+ if (!enabled)
-+ err = mtk_pwm_enable(chip, pwm);
-+
-+ return err;
-+}
-+
-+static const struct pwm_ops mtk_pwm_ops = {
-+ .apply = mtk_pwm_apply,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int mtk_pwm_probe(struct platform_device *pdev)
-+{
-+ struct mtk_pwm_chip *pc;
-+ struct resource *r;
-+ int ret;
-+
-+ pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
-+ if (!pc)
-+ return -ENOMEM;
-+
-+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
-+ if (IS_ERR(pc->mmio_base))
-+ return PTR_ERR(pc->mmio_base);
-+
-+ platform_set_drvdata(pdev, pc);
-+
-+ pc->chip.dev = &pdev->dev;
-+ pc->chip.ops = &mtk_pwm_ops;
-+ pc->chip.base = -1;
-+ pc->chip.npwm = NUM_PWM;
-+
-+ ret = pwmchip_add(&pc->chip);
-+ if (ret < 0)
-+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
-+
-+ return ret;
-+}
-+
-+static int mtk_pwm_remove(struct platform_device *pdev)
-+{
-+ struct mtk_pwm_chip *pc = platform_get_drvdata(pdev);
-+ int i;
-+
-+ for (i = 0; i < NUM_PWM; i++)
-+ pwm_disable(&pc->chip.pwms[i]);
-+
-+ pwmchip_remove(&pc->chip);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id mtk_pwm_of_match[] = {
-+ { .compatible = "mediatek,mt7628-pwm" },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
-+
-+static struct platform_driver mtk_pwm_driver = {
-+ .driver = {
-+ .name = "mtk-pwm",
-+ .owner = THIS_MODULE,
-+ .of_match_table = mtk_pwm_of_match,
-+ },
-+ .probe = mtk_pwm_probe,
-+ .remove = mtk_pwm_remove,
-+};
-+
-+module_platform_driver(mtk_pwm_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
-+MODULE_ALIAS("platform:mtk-pwm");
+++ /dev/null
---- a/drivers/usb/dwc2/platform.c
-+++ b/drivers/usb/dwc2/platform.c
-@@ -462,6 +462,12 @@ static int dwc2_driver_probe(struct plat
- if (retval)
- return retval;
-
-+ /* Enable USB port before any regs access */
-+ if (readl(hsotg->regs + PCGCTL) & 0x0f) {
-+ writel(0x00, hsotg->regs + PCGCTL);
-+ /* TODO: mdelay(25) here? vendor driver don't use it */
-+ }
-+
- hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
-
- retval = dwc2_get_dr_mode(hsotg);
+++ /dev/null
---- a/drivers/misc/Makefile
-+++ b/drivers/misc/Makefile
-@@ -50,6 +50,7 @@ obj-$(CONFIG_ECHO) += echo/
- obj-$(CONFIG_CXL_BASE) += cxl/
- obj-$(CONFIG_DW_XDATA_PCIE) += dw-xdata-pcie.o
- obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
-+obj-$(CONFIG_SOC_MT7620) += linkit.o
- obj-$(CONFIG_OCXL) += ocxl/
- obj-$(CONFIG_BCM_VK) += bcm-vk/
- obj-y += cardreader/
---- /dev/null
-+++ b/drivers/misc/linkit.c
-@@ -0,0 +1,84 @@
-+/*
-+ * 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
-+ * publishhed by the Free Software Foundation.
-+ *
-+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/gpio.h>
-+
-+#define LINKIT_LATCH_GPIO 11
-+
-+struct linkit_hw_data {
-+ char board[16];
-+ char rev[16];
-+};
-+
-+static void sanify_string(char *s)
-+{
-+ int i;
-+
-+ for (i = 0; i < 15; i++)
-+ if (s[i] <= 0x20)
-+ s[i] = '\0';
-+ s[15] = '\0';
-+}
-+
-+static int linkit_probe(struct platform_device *pdev)
-+{
-+ struct linkit_hw_data hw;
-+ struct mtd_info *mtd;
-+ size_t retlen;
-+ int ret;
-+
-+ mtd = get_mtd_device_nm("factory");
-+ if (IS_ERR(mtd))
-+ return PTR_ERR(mtd);
-+
-+ ret = mtd_read(mtd, 0x400, sizeof(hw), &retlen, (u_char *) &hw);
-+ put_mtd_device(mtd);
-+
-+ sanify_string(hw.board);
-+ sanify_string(hw.rev);
-+
-+ dev_info(&pdev->dev, "Version : %s\n", hw.board);
-+ dev_info(&pdev->dev, "Revision : %s\n", hw.rev);
-+
-+ if (!strcmp(hw.board, "LINKITS7688")) {
-+ dev_info(&pdev->dev, "setting up bootstrap latch\n");
-+
-+ if (devm_gpio_request(&pdev->dev, LINKIT_LATCH_GPIO, "bootstrap")) {
-+ dev_err(&pdev->dev, "failed to setup bootstrap gpio\n");
-+ return -1;
-+ }
-+ gpio_direction_output(LINKIT_LATCH_GPIO, 0);
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id linkit_match[] = {
-+ { .compatible = "mediatek,linkit" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, linkit_match);
-+
-+static struct platform_driver linkit_driver = {
-+ .probe = linkit_probe,
-+ .driver = {
-+ .name = "mtk-linkit",
-+ .owner = THIS_MODULE,
-+ .of_match_table = linkit_match,
-+ },
-+};
-+
-+int __init linkit_init(void)
-+{
-+ return platform_driver_register(&linkit_driver);
-+}
-+late_initcall_sync(linkit_init);
+++ /dev/null
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/Kconfig
-@@ -0,0 +1,64 @@
-+# SPDX-License-Identifier: GPL-2.0
-+config CRYPTO_DEV_EIP93_SKCIPHER
-+ tristate
-+
-+config CRYPTO_DEV_EIP93_HMAC
-+ tristate
-+
-+config CRYPTO_DEV_EIP93
-+ tristate "Support for EIP93 crypto HW accelerators"
-+ depends on SOC_MT7621 || COMPILE_TEST
-+ help
-+ EIP93 have various crypto HW accelerators. Select this if
-+ you want to use the EIP93 modules for any of the crypto algorithms.
-+
-+if CRYPTO_DEV_EIP93
-+
-+config CRYPTO_DEV_EIP93_AES
-+ bool "Register AES algorithm implementations with the Crypto API"
-+ default y
-+ select CRYPTO_DEV_EIP93_SKCIPHER
-+ select CRYPTO_LIB_AES
-+ select CRYPTO_SKCIPHER
-+ help
-+ Selecting this will offload AES - ECB, CBC and CTR crypto
-+ to the EIP-93 crypto engine.
-+
-+config CRYPTO_DEV_EIP93_DES
-+ bool "Register legacy DES / 3DES algorithm with the Crypto API"
-+ default y
-+ select CRYPTO_DEV_EIP93_SKCIPHER
-+ select CRYPTO_LIB_DES
-+ select CRYPTO_SKCIPHER
-+ help
-+ Selecting this will offload DES and 3DES ECB and CBC
-+ crypto to the EIP-93 crypto engine.
-+
-+config CRYPTO_DEV_EIP93_AEAD
-+ bool "Register AEAD algorithm with the Crypto API"
-+ default y
-+ select CRYPTO_DEV_EIP93_HMAC
-+ select CRYPTO_AEAD
-+ select CRYPTO_AUTHENC
-+ select CRYPTO_MD5
-+ select CRYPTO_SHA1
-+ select CRYPTO_SHA256
-+ help
-+ Selecting this will offload AEAD authenc(hmac(x), cipher(y))
-+ crypto to the EIP-93 crypto engine.
-+
-+config CRYPTO_DEV_EIP93_GENERIC_SW_MAX_LEN
-+ int "Max skcipher software fallback length"
-+ default 256
-+ help
-+ Max length of crypt request which
-+ will fallback to software crypt of skcipher *except* AES-128.
-+
-+config CRYPTO_DEV_EIP93_AES_128_SW_MAX_LEN
-+ int "Max AES-128 skcipher software fallback length"
-+ default 512
-+ help
-+ Max length of crypt request which
-+ will fallback to software crypt of AES-128 skcipher.
-+
-+endif
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/Makefile
-@@ -0,0 +1,7 @@
-+obj-$(CONFIG_CRYPTO_DEV_EIP93) += crypto-hw-eip93.o
-+
-+crypto-hw-eip93-y += eip93-main.o eip93-common.o
-+
-+crypto-hw-eip93-$(CONFIG_CRYPTO_DEV_EIP93_SKCIPHER) += eip93-cipher.o
-+crypto-hw-eip93-$(CONFIG_CRYPTO_DEV_EIP93_AEAD) += eip93-aead.o
-+
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-aead.c
-@@ -0,0 +1,768 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+
-+#include <crypto/aead.h>
-+#include <crypto/aes.h>
-+#include <crypto/authenc.h>
-+#include <crypto/ctr.h>
-+#include <crypto/hmac.h>
-+#include <crypto/internal/aead.h>
-+#include <crypto/md5.h>
-+#include <crypto/null.h>
-+#include <crypto/sha1.h>
-+#include <crypto/sha2.h>
-+
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+#include <crypto/internal/des.h>
-+#endif
-+
-+#include <linux/crypto.h>
-+#include <linux/dma-mapping.h>
-+
-+#include "eip93-aead.h"
-+#include "eip93-cipher.h"
-+#include "eip93-common.h"
-+#include "eip93-regs.h"
-+
-+void mtk_aead_handle_result(struct crypto_async_request *async, int err)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm);
-+ struct mtk_device *mtk = ctx->mtk;
-+ struct aead_request *req = aead_request_cast(async);
-+ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req);
-+
-+ mtk_unmap_dma(mtk, rctx, req->src, req->dst);
-+ mtk_handle_result(mtk, rctx, req->iv);
-+
-+ if (err == 1)
-+ err = -EBADMSG;
-+ /* let software handle anti-replay errors */
-+ if (err == 4)
-+ err = 0;
-+
-+ aead_request_complete(req, err);
-+}
-+
-+static int mtk_aead_send_req(struct crypto_async_request *async)
-+{
-+ struct aead_request *req = aead_request_cast(async);
-+ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req);
-+ int err;
-+
-+ err = check_valid_request(rctx);
-+ if (err) {
-+ aead_request_complete(req, err);
-+ return err;
-+ }
-+
-+ return mtk_send_req(async, req->iv, rctx);
-+}
-+
-+/* Crypto aead API functions */
-+static int mtk_aead_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
-+ struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg,
-+ struct mtk_alg_template, alg.aead.base);
-+ u32 flags = tmpl->flags;
-+ char *alg_base;
-+
-+ crypto_aead_set_reqsize(__crypto_aead_cast(tfm),
-+ sizeof(struct mtk_cipher_reqctx));
-+
-+ ctx->mtk = tmpl->mtk;
-+ ctx->in_first = true;
-+ ctx->out_first = true;
-+
-+ ctx->sa_in = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL);
-+ if (!ctx->sa_in)
-+ return -ENOMEM;
-+
-+ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+
-+ ctx->sa_out = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL);
-+ if (!ctx->sa_out)
-+ return -ENOMEM;
-+
-+ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+
-+ /* software workaround for now */
-+ if (IS_HASH_MD5(flags))
-+ alg_base = "md5";
-+ if (IS_HASH_SHA1(flags))
-+ alg_base = "sha1";
-+ if (IS_HASH_SHA224(flags))
-+ alg_base = "sha224";
-+ if (IS_HASH_SHA256(flags))
-+ alg_base = "sha256";
-+
-+ ctx->shash = crypto_alloc_shash(alg_base, 0, CRYPTO_ALG_NEED_FALLBACK);
-+
-+ if (IS_ERR(ctx->shash)) {
-+ dev_err(ctx->mtk->dev, "base driver %s could not be loaded.\n",
-+ alg_base);
-+ return PTR_ERR(ctx->shash);
-+ }
-+
-+ return 0;
-+}
-+
-+static void mtk_aead_cra_exit(struct crypto_tfm *tfm)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ if (ctx->shash)
-+ crypto_free_shash(ctx->shash);
-+
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ kfree(ctx->sa_in);
-+ kfree(ctx->sa_out);
-+}
-+
-+static int mtk_aead_setkey(struct crypto_aead *ctfm, const u8 *key,
-+ unsigned int len)
-+{
-+ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
-+ struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg,
-+ struct mtk_alg_template, alg.skcipher.base);
-+ u32 flags = tmpl->flags;
-+ u32 nonce = 0;
-+ struct crypto_authenc_keys keys;
-+ struct crypto_aes_ctx aes;
-+ struct saRecord_s *saRecord = ctx->sa_out;
-+ int sa_size = sizeof(struct saRecord_s);
-+ int err = -EINVAL;
-+
-+
-+ if (crypto_authenc_extractkeys(&keys, key, len))
-+ return err;
-+
-+ if (IS_RFC3686(flags)) {
-+ if (keys.enckeylen < CTR_RFC3686_NONCE_SIZE)
-+ return err;
-+
-+ keys.enckeylen -= CTR_RFC3686_NONCE_SIZE;
-+ memcpy(&nonce, keys.enckey + keys.enckeylen,
-+ CTR_RFC3686_NONCE_SIZE);
-+ }
-+
-+ switch ((flags & MTK_ALG_MASK)) {
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+ case MTK_ALG_DES:
-+ err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen);
-+ break;
-+ case MTK_ALG_3DES:
-+ if (keys.enckeylen != DES3_EDE_KEY_SIZE)
-+ return -EINVAL;
-+
-+ err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen);
-+ break;
-+#endif
-+ case MTK_ALG_AES:
-+ err = aes_expandkey(&aes, keys.enckey, keys.enckeylen);
-+ }
-+ if (err)
-+ return err;
-+
-+ ctx->blksize = crypto_aead_blocksize(ctfm);
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in, sa_size,
-+ DMA_TO_DEVICE);
-+
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out, sa_size,
-+ DMA_TO_DEVICE);
-+ /* Encryption key */
-+ mtk_set_saRecord(saRecord, keys.enckeylen, flags);
-+ saRecord->saCmd0.bits.opCode = 1;
-+ saRecord->saCmd0.bits.digestLength = ctx->authsize >> 2;
-+
-+ memcpy(saRecord->saKey, keys.enckey, keys.enckeylen);
-+ ctx->saNonce = nonce;
-+ saRecord->saNonce = nonce;
-+
-+ /* authentication key */
-+ err = mtk_authenc_setkey(ctx->shash, saRecord, keys.authkey,
-+ keys.authkeylen);
-+
-+ saRecord->saCmd0.bits.direction = 0;
-+ memcpy(ctx->sa_in, saRecord, sa_size);
-+ ctx->sa_in->saCmd0.bits.direction = 1;
-+ ctx->sa_in->saCmd1.bits.copyDigest = 0;
-+
-+ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out, sa_size,
-+ DMA_TO_DEVICE);
-+ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in, sa_size,
-+ DMA_TO_DEVICE);
-+ ctx->in_first = true;
-+ ctx->out_first = true;
-+
-+ return err;
-+}
-+
-+static int mtk_aead_setauthsize(struct crypto_aead *ctfm,
-+ unsigned int authsize)
-+{
-+ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+
-+ ctx->authsize = authsize;
-+ ctx->sa_in->saCmd0.bits.digestLength = ctx->authsize >> 2;
-+ ctx->sa_out->saCmd0.bits.digestLength = ctx->authsize >> 2;
-+
-+ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ return 0;
-+}
-+
-+static void mtk_aead_setassoc(struct mtk_crypto_ctx *ctx,
-+ struct aead_request *req, bool in)
-+{
-+ struct saRecord_s *saRecord;
-+
-+ if (in) {
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ saRecord = ctx->sa_in;
-+ saRecord->saCmd1.bits.hashCryptOffset = req->assoclen >> 2;
-+
-+ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ ctx->assoclen_in = req->assoclen;
-+ } else {
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ saRecord = ctx->sa_out;
-+ saRecord->saCmd1.bits.hashCryptOffset = req->assoclen >> 2;
-+
-+ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ ctx->assoclen_out = req->assoclen;
-+ }
-+}
-+
-+static int mtk_aead_crypt(struct aead_request *req)
-+{
-+ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req);
-+ struct crypto_async_request *async = &req->base;
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
-+ struct crypto_aead *aead = crypto_aead_reqtfm(req);
-+
-+ rctx->textsize = req->cryptlen;
-+ rctx->blksize = ctx->blksize;
-+ rctx->assoclen = req->assoclen;
-+ rctx->authsize = ctx->authsize;
-+ rctx->sg_src = req->src;
-+ rctx->sg_dst = req->dst;
-+ rctx->ivsize = crypto_aead_ivsize(aead);
-+ rctx->flags |= MTK_DESC_AEAD;
-+
-+ if IS_DECRYPT(rctx->flags)
-+ rctx->textsize -= rctx->authsize;
-+
-+ return mtk_aead_send_req(async);
-+}
-+
-+static int mtk_aead_encrypt(struct aead_request *req)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
-+ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req);
-+ struct mtk_alg_template *tmpl = container_of(req->base.tfm->__crt_alg,
-+ struct mtk_alg_template, alg.aead.base);
-+
-+ rctx->flags = tmpl->flags;
-+ rctx->flags |= MTK_ENCRYPT;
-+ if (ctx->out_first) {
-+ mtk_aead_setassoc(ctx, req, false);
-+ ctx->out_first = false;
-+ }
-+
-+ if (req->assoclen != ctx->assoclen_out) {
-+ dev_err(ctx->mtk->dev, "Request AAD length error\n");
-+ return -EINVAL;
-+ }
-+
-+ rctx->saRecord_base = ctx->sa_base_out;
-+
-+ return mtk_aead_crypt(req);
-+}
-+
-+static int mtk_aead_decrypt(struct aead_request *req)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
-+ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req);
-+ struct mtk_alg_template *tmpl = container_of(req->base.tfm->__crt_alg,
-+ struct mtk_alg_template, alg.aead.base);
-+
-+ rctx->flags = tmpl->flags;
-+ rctx->flags |= MTK_DECRYPT;
-+ if (ctx->in_first) {
-+ mtk_aead_setassoc(ctx, req, true);
-+ ctx->in_first = false;
-+ }
-+
-+ if (req->assoclen != ctx->assoclen_in) {
-+ dev_err(ctx->mtk->dev, "Request AAD length error\n");
-+ return -EINVAL;
-+ }
-+
-+ rctx->saRecord_base = ctx->sa_base_in;
-+
-+ return mtk_aead_crypt(req);
-+}
-+
-+/* Available authenc algorithms in this module */
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
-+struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_aes = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_MD5 | MTK_MODE_CBC | MTK_ALG_AES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = AES_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = MD5_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(md5),cbc(aes))",
-+ .cra_driver_name =
-+ "authenc(hmac(md5-eip93), cbc(aes-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_aes = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA1 | MTK_MODE_CBC | MTK_ALG_AES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = AES_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA1_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha1),cbc(aes))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha1-eip93),cbc(aes-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_aes = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA224 | MTK_MODE_CBC | MTK_ALG_AES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = AES_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA224_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha224),cbc(aes))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha224-eip93),cbc(aes-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_aes = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA256 | MTK_MODE_CBC | MTK_ALG_AES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = AES_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA256_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha256),cbc(aes))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha256-eip93),cbc(aes-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_md5_rfc3686_aes = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_MD5 |
-+ MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = CTR_RFC3686_IV_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = MD5_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(md5),rfc3686(ctr(aes)))",
-+ .cra_driver_name =
-+ "authenc(hmac(md5-eip93),rfc3686(ctr(aes-eip93)))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha1_rfc3686_aes = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA1 |
-+ MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = CTR_RFC3686_IV_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA1_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha1-eip93),rfc3686(ctr(aes-eip93)))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha224_rfc3686_aes = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA224 |
-+ MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = CTR_RFC3686_IV_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA224_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha224-eip93),rfc3686(ctr(aes-eip93)))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha256_rfc3686_aes = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA256 |
-+ MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = CTR_RFC3686_IV_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA256_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha256-eip93),rfc3686(ctr(aes-eip93)))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_des = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_MD5 | MTK_MODE_CBC | MTK_ALG_DES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = MD5_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(md5),cbc(des))",
-+ .cra_driver_name =
-+ "authenc(hmac(md5-eip93),cbc(des-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_des = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA1 | MTK_MODE_CBC | MTK_ALG_DES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA1_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha1),cbc(des))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha1-eip93),cbc(des-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_des = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA224 | MTK_MODE_CBC | MTK_ALG_DES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA224_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha224),cbc(des))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha224-eip93),cbc(des-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_des = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA256 | MTK_MODE_CBC | MTK_ALG_DES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA256_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha256),cbc(des))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha256-eip93),cbc(des-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_des3_ede = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_MD5 | MTK_MODE_CBC | MTK_ALG_3DES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = DES3_EDE_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = MD5_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(md5),cbc(des3_ede))",
-+ .cra_driver_name =
-+ "authenc(hmac(md5-eip93),cbc(des3_ede-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0x0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_des3_ede = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA1 | MTK_MODE_CBC | MTK_ALG_3DES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = DES3_EDE_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA1_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha1),cbc(des3_ede))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha1-eip93),cbc(des3_ede-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0x0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_des3_ede = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA224 | MTK_MODE_CBC | MTK_ALG_3DES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = DES3_EDE_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA224_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha224),cbc(des3_ede))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha224-eip93),cbc(des3_ede-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0x0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_des3_ede = {
-+ .type = MTK_ALG_TYPE_AEAD,
-+ .flags = MTK_HASH_HMAC | MTK_HASH_SHA256 | MTK_MODE_CBC | MTK_ALG_3DES,
-+ .alg.aead = {
-+ .setkey = mtk_aead_setkey,
-+ .encrypt = mtk_aead_encrypt,
-+ .decrypt = mtk_aead_decrypt,
-+ .ivsize = DES3_EDE_BLOCK_SIZE,
-+ .setauthsize = mtk_aead_setauthsize,
-+ .maxauthsize = SHA256_DIGEST_SIZE,
-+ .base = {
-+ .cra_name = "authenc(hmac(sha256),cbc(des3_ede))",
-+ .cra_driver_name =
-+ "authenc(hmac(sha256-eip93),cbc(des3_ede-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0x0,
-+ .cra_init = mtk_aead_cra_init,
-+ .cra_exit = mtk_aead_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+#endif
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-aead.h
-@@ -0,0 +1,31 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+#ifndef _EIP93_AEAD_H_
-+#define _EIP93_AEAD_H_
-+
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_aes;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_aes;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_aes;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_aes;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_md5_rfc3686_aes;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha1_rfc3686_aes;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha224_rfc3686_aes;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha256_rfc3686_aes;
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_des;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_des;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_des;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_des;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_des3_ede;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_des3_ede;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_des3_ede;
-+extern struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_des3_ede;
-+#endif
-+
-+void mtk_aead_handle_result(struct crypto_async_request *async, int err);
-+
-+#endif /* _EIP93_AEAD_H_ */
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-aes.h
-@@ -0,0 +1,15 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+#ifndef _EIP93_AES_H_
-+#define _EIP93_AES_H_
-+
-+extern struct mtk_alg_template mtk_alg_ecb_aes;
-+extern struct mtk_alg_template mtk_alg_cbc_aes;
-+extern struct mtk_alg_template mtk_alg_ctr_aes;
-+extern struct mtk_alg_template mtk_alg_rfc3686_aes;
-+
-+#endif /* _EIP93_AES_H_ */
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-cipher.c
-@@ -0,0 +1,483 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
-+#include <crypto/aes.h>
-+#include <crypto/ctr.h>
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+#include <crypto/internal/des.h>
-+#endif
-+#include <linux/dma-mapping.h>
-+
-+#include "eip93-cipher.h"
-+#include "eip93-common.h"
-+#include "eip93-regs.h"
-+
-+void mtk_skcipher_handle_result(struct crypto_async_request *async, int err)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm);
-+ struct mtk_device *mtk = ctx->mtk;
-+ struct skcipher_request *req = skcipher_request_cast(async);
-+ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req);
-+
-+ mtk_unmap_dma(mtk, rctx, req->src, req->dst);
-+ mtk_handle_result(mtk, rctx, req->iv);
-+
-+ skcipher_request_complete(req, err);
-+}
-+
-+static inline bool mtk_skcipher_is_fallback(const struct crypto_tfm *tfm,
-+ u32 flags)
-+{
-+ return (tfm->__crt_alg->cra_flags & CRYPTO_ALG_NEED_FALLBACK) &&
-+ !IS_RFC3686(flags);
-+}
-+
-+static int mtk_skcipher_send_req(struct crypto_async_request *async)
-+{
-+ struct skcipher_request *req = skcipher_request_cast(async);
-+ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req);
-+ int err;
-+
-+ err = check_valid_request(rctx);
-+
-+ if (err) {
-+ skcipher_request_complete(req, err);
-+ return err;
-+ }
-+
-+ return mtk_send_req(async, req->iv, rctx);
-+}
-+
-+/* Crypto skcipher API functions */
-+static int mtk_skcipher_cra_init(struct crypto_tfm *tfm)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
-+ struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg,
-+ struct mtk_alg_template, alg.skcipher.base);
-+ bool fallback = mtk_skcipher_is_fallback(tfm, tmpl->flags);
-+
-+ if (fallback) {
-+ ctx->fallback = crypto_alloc_skcipher(
-+ crypto_tfm_alg_name(tfm), 0, CRYPTO_ALG_NEED_FALLBACK);
-+ if (IS_ERR(ctx->fallback))
-+ return PTR_ERR(ctx->fallback);
-+ }
-+
-+ crypto_skcipher_set_reqsize(
-+ __crypto_skcipher_cast(tfm),
-+ sizeof(struct mtk_cipher_reqctx) +
-+ (fallback ? crypto_skcipher_reqsize(ctx->fallback) :
-+ 0));
-+
-+ ctx->mtk = tmpl->mtk;
-+
-+ ctx->sa_in = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL);
-+ if (!ctx->sa_in)
-+ return -ENOMEM;
-+
-+ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+
-+ ctx->sa_out = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL);
-+ if (!ctx->sa_out)
-+ return -ENOMEM;
-+
-+ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ return 0;
-+}
-+
-+static void mtk_skcipher_cra_exit(struct crypto_tfm *tfm)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
-+
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out,
-+ sizeof(struct saRecord_s), DMA_TO_DEVICE);
-+ kfree(ctx->sa_in);
-+ kfree(ctx->sa_out);
-+
-+ crypto_free_skcipher(ctx->fallback);
-+}
-+
-+static int mtk_skcipher_setkey(struct crypto_skcipher *ctfm, const u8 *key,
-+ unsigned int len)
-+{
-+ struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
-+ struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg,
-+ struct mtk_alg_template, alg.skcipher.base);
-+ struct saRecord_s *saRecord = ctx->sa_out;
-+ u32 flags = tmpl->flags;
-+ u32 nonce = 0;
-+ unsigned int keylen = len;
-+ int sa_size = sizeof(struct saRecord_s);
-+ int err = -EINVAL;
-+
-+ if (!key || !keylen)
-+ return err;
-+
-+ ctx->keylen = keylen;
-+
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
-+ if (IS_RFC3686(flags)) {
-+ if (len < CTR_RFC3686_NONCE_SIZE)
-+ return err;
-+
-+ keylen = len - CTR_RFC3686_NONCE_SIZE;
-+ memcpy(&nonce, key + keylen, CTR_RFC3686_NONCE_SIZE);
-+ }
-+#endif
-+
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+ if (flags & MTK_ALG_DES) {
-+ ctx->blksize = DES_BLOCK_SIZE;
-+ err = verify_skcipher_des_key(ctfm, key);
-+ }
-+ if (flags & MTK_ALG_3DES) {
-+ ctx->blksize = DES3_EDE_BLOCK_SIZE;
-+ err = verify_skcipher_des3_key(ctfm, key);
-+ }
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
-+ if (flags & MTK_ALG_AES) {
-+ struct crypto_aes_ctx aes;
-+ bool fallback = mtk_skcipher_is_fallback(tfm, flags);
-+
-+ if (fallback && !IS_RFC3686(flags)) {
-+ err = crypto_skcipher_setkey(ctx->fallback, key,
-+ keylen);
-+ if (err)
-+ return err;
-+ }
-+
-+ ctx->blksize = AES_BLOCK_SIZE;
-+ err = aes_expandkey(&aes, key, keylen);
-+ }
-+#endif
-+ if (err)
-+ return err;
-+
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in, sa_size,
-+ DMA_TO_DEVICE);
-+
-+ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out, sa_size,
-+ DMA_TO_DEVICE);
-+
-+ mtk_set_saRecord(saRecord, keylen, flags);
-+
-+ memcpy(saRecord->saKey, key, keylen);
-+ ctx->saNonce = nonce;
-+ saRecord->saNonce = nonce;
-+ saRecord->saCmd0.bits.direction = 0;
-+
-+ memcpy(ctx->sa_in, saRecord, sa_size);
-+ ctx->sa_in->saCmd0.bits.direction = 1;
-+
-+ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out, sa_size,
-+ DMA_TO_DEVICE);
-+
-+ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in, sa_size,
-+ DMA_TO_DEVICE);
-+ return err;
-+}
-+
-+static int mtk_skcipher_crypt(struct skcipher_request *req, bool encrypt)
-+{
-+ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req);
-+ struct crypto_async_request *async = &req->base;
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
-+ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
-+ bool fallback = mtk_skcipher_is_fallback(req->base.tfm, rctx->flags);
-+
-+ if (!req->cryptlen)
-+ return 0;
-+
-+ /*
-+ * ECB and CBC algorithms require message lengths to be
-+ * multiples of block size.
-+ */
-+ if (IS_ECB(rctx->flags) || IS_CBC(rctx->flags))
-+ if (!IS_ALIGNED(req->cryptlen,
-+ crypto_skcipher_blocksize(skcipher)))
-+ return -EINVAL;
-+
-+ if (fallback &&
-+ req->cryptlen <= (AES_KEYSIZE_128 ?
-+ CONFIG_CRYPTO_DEV_EIP93_AES_128_SW_MAX_LEN :
-+ CONFIG_CRYPTO_DEV_EIP93_GENERIC_SW_MAX_LEN)) {
-+ skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback);
-+ skcipher_request_set_callback(&rctx->fallback_req,
-+ req->base.flags,
-+ req->base.complete,
-+ req->base.data);
-+ skcipher_request_set_crypt(&rctx->fallback_req, req->src,
-+ req->dst, req->cryptlen, req->iv);
-+ return encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) :
-+ crypto_skcipher_decrypt(&rctx->fallback_req);
-+ }
-+
-+ rctx->assoclen = 0;
-+ rctx->textsize = req->cryptlen;
-+ rctx->authsize = 0;
-+ rctx->sg_src = req->src;
-+ rctx->sg_dst = req->dst;
-+ rctx->ivsize = crypto_skcipher_ivsize(skcipher);
-+ rctx->blksize = ctx->blksize;
-+ rctx->flags |= MTK_DESC_SKCIPHER;
-+ if (!IS_ECB(rctx->flags))
-+ rctx->flags |= MTK_DESC_DMA_IV;
-+
-+ return mtk_skcipher_send_req(async);
-+}
-+
-+static int mtk_skcipher_encrypt(struct skcipher_request *req)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
-+ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req);
-+ struct mtk_alg_template *tmpl = container_of(req->base.tfm->__crt_alg,
-+ struct mtk_alg_template, alg.skcipher.base);
-+
-+ rctx->flags = tmpl->flags;
-+ rctx->flags |= MTK_ENCRYPT;
-+ rctx->saRecord_base = ctx->sa_base_out;
-+
-+ return mtk_skcipher_crypt(req, true);
-+}
-+
-+static int mtk_skcipher_decrypt(struct skcipher_request *req)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
-+ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req);
-+ struct mtk_alg_template *tmpl = container_of(req->base.tfm->__crt_alg,
-+ struct mtk_alg_template, alg.skcipher.base);
-+
-+ rctx->flags = tmpl->flags;
-+ rctx->flags |= MTK_DECRYPT;
-+ rctx->saRecord_base = ctx->sa_base_in;
-+
-+ return mtk_skcipher_crypt(req, false);
-+}
-+
-+/* Available algorithms in this module */
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
-+struct mtk_alg_template mtk_alg_ecb_aes = {
-+ .type = MTK_ALG_TYPE_SKCIPHER,
-+ .flags = MTK_MODE_ECB | MTK_ALG_AES,
-+ .alg.skcipher = {
-+ .setkey = mtk_skcipher_setkey,
-+ .encrypt = mtk_skcipher_encrypt,
-+ .decrypt = mtk_skcipher_decrypt,
-+ .min_keysize = AES_MIN_KEY_SIZE,
-+ .max_keysize = AES_MAX_KEY_SIZE,
-+ .ivsize = 0,
-+ .base = {
-+ .cra_name = "ecb(aes)",
-+ .cra_driver_name = "ecb(aes-eip93)",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_NEED_FALLBACK |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0xf,
-+ .cra_init = mtk_skcipher_cra_init,
-+ .cra_exit = mtk_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_cbc_aes = {
-+ .type = MTK_ALG_TYPE_SKCIPHER,
-+ .flags = MTK_MODE_CBC | MTK_ALG_AES,
-+ .alg.skcipher = {
-+ .setkey = mtk_skcipher_setkey,
-+ .encrypt = mtk_skcipher_encrypt,
-+ .decrypt = mtk_skcipher_decrypt,
-+ .min_keysize = AES_MIN_KEY_SIZE,
-+ .max_keysize = AES_MAX_KEY_SIZE,
-+ .ivsize = AES_BLOCK_SIZE,
-+ .base = {
-+ .cra_name = "cbc(aes)",
-+ .cra_driver_name = "cbc(aes-eip93)",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_NEED_FALLBACK |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = AES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0xf,
-+ .cra_init = mtk_skcipher_cra_init,
-+ .cra_exit = mtk_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_ctr_aes = {
-+ .type = MTK_ALG_TYPE_SKCIPHER,
-+ .flags = MTK_MODE_CTR | MTK_ALG_AES,
-+ .alg.skcipher = {
-+ .setkey = mtk_skcipher_setkey,
-+ .encrypt = mtk_skcipher_encrypt,
-+ .decrypt = mtk_skcipher_decrypt,
-+ .min_keysize = AES_MIN_KEY_SIZE,
-+ .max_keysize = AES_MAX_KEY_SIZE,
-+ .ivsize = AES_BLOCK_SIZE,
-+ .base = {
-+ .cra_name = "ctr(aes)",
-+ .cra_driver_name = "ctr(aes-eip93)",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_NEED_FALLBACK |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0xf,
-+ .cra_init = mtk_skcipher_cra_init,
-+ .cra_exit = mtk_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_rfc3686_aes = {
-+ .type = MTK_ALG_TYPE_SKCIPHER,
-+ .flags = MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES,
-+ .alg.skcipher = {
-+ .setkey = mtk_skcipher_setkey,
-+ .encrypt = mtk_skcipher_encrypt,
-+ .decrypt = mtk_skcipher_decrypt,
-+ .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
-+ .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
-+ .ivsize = CTR_RFC3686_IV_SIZE,
-+ .base = {
-+ .cra_name = "rfc3686(ctr(aes))",
-+ .cra_driver_name = "rfc3686(ctr(aes-eip93))",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_NEED_FALLBACK |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = 1,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0xf,
-+ .cra_init = mtk_skcipher_cra_init,
-+ .cra_exit = mtk_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+struct mtk_alg_template mtk_alg_ecb_des = {
-+ .type = MTK_ALG_TYPE_SKCIPHER,
-+ .flags = MTK_MODE_ECB | MTK_ALG_DES,
-+ .alg.skcipher = {
-+ .setkey = mtk_skcipher_setkey,
-+ .encrypt = mtk_skcipher_encrypt,
-+ .decrypt = mtk_skcipher_decrypt,
-+ .min_keysize = DES_KEY_SIZE,
-+ .max_keysize = DES_KEY_SIZE,
-+ .ivsize = 0,
-+ .base = {
-+ .cra_name = "ecb(des)",
-+ .cra_driver_name = "ebc(des-eip93)",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_skcipher_cra_init,
-+ .cra_exit = mtk_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_cbc_des = {
-+ .type = MTK_ALG_TYPE_SKCIPHER,
-+ .flags = MTK_MODE_CBC | MTK_ALG_DES,
-+ .alg.skcipher = {
-+ .setkey = mtk_skcipher_setkey,
-+ .encrypt = mtk_skcipher_encrypt,
-+ .decrypt = mtk_skcipher_decrypt,
-+ .min_keysize = DES_KEY_SIZE,
-+ .max_keysize = DES_KEY_SIZE,
-+ .ivsize = DES_BLOCK_SIZE,
-+ .base = {
-+ .cra_name = "cbc(des)",
-+ .cra_driver_name = "cbc(des-eip93)",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_skcipher_cra_init,
-+ .cra_exit = mtk_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_ecb_des3_ede = {
-+ .type = MTK_ALG_TYPE_SKCIPHER,
-+ .flags = MTK_MODE_ECB | MTK_ALG_3DES,
-+ .alg.skcipher = {
-+ .setkey = mtk_skcipher_setkey,
-+ .encrypt = mtk_skcipher_encrypt,
-+ .decrypt = mtk_skcipher_decrypt,
-+ .min_keysize = DES3_EDE_KEY_SIZE,
-+ .max_keysize = DES3_EDE_KEY_SIZE,
-+ .ivsize = 0,
-+ .base = {
-+ .cra_name = "ecb(des3_ede)",
-+ .cra_driver_name = "ecb(des3_ede-eip93)",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_skcipher_cra_init,
-+ .cra_exit = mtk_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+
-+struct mtk_alg_template mtk_alg_cbc_des3_ede = {
-+ .type = MTK_ALG_TYPE_SKCIPHER,
-+ .flags = MTK_MODE_CBC | MTK_ALG_3DES,
-+ .alg.skcipher = {
-+ .setkey = mtk_skcipher_setkey,
-+ .encrypt = mtk_skcipher_encrypt,
-+ .decrypt = mtk_skcipher_decrypt,
-+ .min_keysize = DES3_EDE_KEY_SIZE,
-+ .max_keysize = DES3_EDE_KEY_SIZE,
-+ .ivsize = DES3_EDE_BLOCK_SIZE,
-+ .base = {
-+ .cra_name = "cbc(des3_ede)",
-+ .cra_driver_name = "cbc(des3_ede-eip93)",
-+ .cra_priority = MTK_CRA_PRIORITY,
-+ .cra_flags = CRYPTO_ALG_ASYNC |
-+ CRYPTO_ALG_KERN_DRIVER_ONLY,
-+ .cra_blocksize = DES3_EDE_BLOCK_SIZE,
-+ .cra_ctxsize = sizeof(struct mtk_crypto_ctx),
-+ .cra_alignmask = 0,
-+ .cra_init = mtk_skcipher_cra_init,
-+ .cra_exit = mtk_skcipher_cra_exit,
-+ .cra_module = THIS_MODULE,
-+ },
-+ },
-+};
-+#endif
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-cipher.h
-@@ -0,0 +1,66 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+#ifndef _EIP93_CIPHER_H_
-+#define _EIP93_CIPHER_H_
-+
-+#include "eip93-main.h"
-+
-+struct mtk_crypto_ctx {
-+ struct mtk_device *mtk;
-+ struct saRecord_s *sa_in;
-+ dma_addr_t sa_base_in;
-+ struct saRecord_s *sa_out;
-+ dma_addr_t sa_base_out;
-+ uint32_t saNonce;
-+ int blksize;
-+ /* AEAD specific */
-+ unsigned int authsize;
-+ unsigned int assoclen_in;
-+ unsigned int assoclen_out;
-+ bool in_first;
-+ bool out_first;
-+ struct crypto_shash *shash;
-+ unsigned int keylen;
-+ struct crypto_skcipher *fallback;
-+};
-+
-+struct mtk_cipher_reqctx {
-+ unsigned long flags;
-+ unsigned int blksize;
-+ unsigned int ivsize;
-+ unsigned int textsize;
-+ unsigned int assoclen;
-+ unsigned int authsize;
-+ dma_addr_t saRecord_base;
-+ struct saState_s *saState;
-+ dma_addr_t saState_base;
-+ uint32_t saState_idx;
-+ struct eip93_descriptor_s *cdesc;
-+ struct scatterlist *sg_src;
-+ struct scatterlist *sg_dst;
-+ int src_nents;
-+ int dst_nents;
-+ struct saState_s *saState_ctr;
-+ dma_addr_t saState_base_ctr;
-+ uint32_t saState_ctr_idx;
-+ struct skcipher_request fallback_req; // keep at the end
-+};
-+
-+int check_valid_request(struct mtk_cipher_reqctx *rctx);
-+
-+void mtk_unmap_dma(struct mtk_device *mtk, struct mtk_cipher_reqctx *rctx,
-+ struct scatterlist *reqsrc, struct scatterlist *reqdst);
-+
-+void mtk_skcipher_handle_result(struct crypto_async_request *async, int err);
-+
-+int mtk_send_req(struct crypto_async_request *async,
-+ const u8 *reqiv, struct mtk_cipher_reqctx *rctx);
-+
-+void mtk_handle_result(struct mtk_device *mtk, struct mtk_cipher_reqctx *rctx,
-+ u8 *reqiv);
-+
-+#endif /* _EIP93_CIPHER_H_ */
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-common.c
-@@ -0,0 +1,749 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+
-+#include <crypto/aes.h>
-+#include <crypto/ctr.h>
-+#include <crypto/hmac.h>
-+#include <crypto/sha1.h>
-+#include <crypto/sha2.h>
-+#include <linux/delay.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/scatterlist.h>
-+
-+#include "eip93-cipher.h"
-+#include "eip93-common.h"
-+#include "eip93-main.h"
-+#include "eip93-regs.h"
-+
-+inline void *mtk_ring_next_wptr(struct mtk_device *mtk,
-+ struct mtk_desc_ring *ring)
-+{
-+ void *ptr = ring->write;
-+
-+ if ((ring->write == ring->read - ring->offset) ||
-+ (ring->read == ring->base && ring->write == ring->base_end))
-+ return ERR_PTR(-ENOMEM);
-+
-+ if (ring->write == ring->base_end)
-+ ring->write = ring->base;
-+ else
-+ ring->write += ring->offset;
-+
-+ return ptr;
-+}
-+
-+inline void *mtk_ring_next_rptr(struct mtk_device *mtk,
-+ struct mtk_desc_ring *ring)
-+{
-+ void *ptr = ring->read;
-+
-+ if (ring->write == ring->read)
-+ return ERR_PTR(-ENOENT);
-+
-+ if (ring->read == ring->base_end)
-+ ring->read = ring->base;
-+ else
-+ ring->read += ring->offset;
-+
-+ return ptr;
-+}
-+
-+inline int mtk_put_descriptor(struct mtk_device *mtk,
-+ struct eip93_descriptor_s *desc)
-+{
-+ struct eip93_descriptor_s *cdesc;
-+ struct eip93_descriptor_s *rdesc;
-+ unsigned long irqflags;
-+
-+ spin_lock_irqsave(&mtk->ring->write_lock, irqflags);
-+
-+ rdesc = mtk_ring_next_wptr(mtk, &mtk->ring->rdr);
-+
-+ if (IS_ERR(rdesc)) {
-+ spin_unlock_irqrestore(&mtk->ring->write_lock, irqflags);
-+ return -ENOENT;
-+ }
-+
-+ cdesc = mtk_ring_next_wptr(mtk, &mtk->ring->cdr);
-+
-+ if (IS_ERR(cdesc)) {
-+ spin_unlock_irqrestore(&mtk->ring->write_lock, irqflags);
-+ return -ENOENT;
-+ }
-+
-+ memset(rdesc, 0, sizeof(struct eip93_descriptor_s));
-+ memcpy(cdesc, desc, sizeof(struct eip93_descriptor_s));
-+
-+ atomic_dec(&mtk->ring->free);
-+ spin_unlock_irqrestore(&mtk->ring->write_lock, irqflags);
-+
-+ return 0;
-+}
-+
-+inline void *mtk_get_descriptor(struct mtk_device *mtk)
-+{
-+ struct eip93_descriptor_s *cdesc;
-+ void *ptr;
-+ unsigned long irqflags;
-+
-+ spin_lock_irqsave(&mtk->ring->read_lock, irqflags);
-+
-+ cdesc = mtk_ring_next_rptr(mtk, &mtk->ring->cdr);
-+
-+ if (IS_ERR(cdesc)) {
-+ spin_unlock_irqrestore(&mtk->ring->read_lock, irqflags);
-+ return ERR_PTR(-ENOENT);
-+ }
-+
-+ memset(cdesc, 0, sizeof(struct eip93_descriptor_s));
-+
-+ ptr = mtk_ring_next_rptr(mtk, &mtk->ring->rdr);
-+ if (IS_ERR(ptr)) {
-+ spin_unlock_irqrestore(&mtk->ring->read_lock, irqflags);
-+ return ERR_PTR(-ENOENT);
-+ }
-+
-+ atomic_inc(&mtk->ring->free);
-+ spin_unlock_irqrestore(&mtk->ring->read_lock, irqflags);
-+
-+ return ptr;
-+}
-+
-+inline int mtk_get_free_saState(struct mtk_device *mtk)
-+{
-+ struct mtk_state_pool *saState_pool;
-+ int i;
-+
-+ for (i = 0; i < MTK_RING_SIZE; i++) {
-+ saState_pool = &mtk->ring->saState_pool[i];
-+ if (saState_pool->in_use == false) {
-+ saState_pool->in_use = true;
-+ return i;
-+ }
-+
-+ }
-+
-+ return -ENOENT;
-+}
-+
-+static inline void mtk_free_sg_copy(const int len, struct scatterlist **sg)
-+{
-+ if (!*sg || !len)
-+ return;
-+
-+ free_pages((unsigned long)sg_virt(*sg), get_order(len));
-+ kfree(*sg);
-+ *sg = NULL;
-+}
-+
-+static inline int mtk_make_sg_copy(struct scatterlist *src,
-+ struct scatterlist **dst,
-+ const uint32_t len, const bool copy)
-+{
-+ void *pages;
-+
-+ *dst = kmalloc(sizeof(**dst), GFP_KERNEL);
-+ if (!*dst)
-+ return -ENOMEM;
-+
-+
-+ pages = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA,
-+ get_order(len));
-+
-+ if (!pages) {
-+ kfree(*dst);
-+ *dst = NULL;
-+ return -ENOMEM;
-+ }
-+
-+ sg_init_table(*dst, 1);
-+ sg_set_buf(*dst, pages, len);
-+
-+ /* copy only as requested */
-+ if (copy)
-+ sg_copy_to_buffer(src, sg_nents(src), pages, len);
-+
-+ return 0;
-+}
-+
-+static inline bool mtk_is_sg_aligned(struct scatterlist *sg, u32 len,
-+ const int blksize)
-+{
-+ int nents;
-+
-+ for (nents = 0; sg; sg = sg_next(sg), ++nents) {
-+ if (!IS_ALIGNED(sg->offset, 4))
-+ return false;
-+
-+ if (len <= sg->length) {
-+ if (!IS_ALIGNED(len, blksize))
-+ return false;
-+
-+ return true;
-+ }
-+
-+ if (!IS_ALIGNED(sg->length, blksize))
-+ return false;
-+
-+ len -= sg->length;
-+ }
-+ return false;
-+}
-+
-+int check_valid_request(struct mtk_cipher_reqctx *rctx)
-+{
-+ struct scatterlist *src = rctx->sg_src;
-+ struct scatterlist *dst = rctx->sg_dst;
-+ uint32_t src_nents, dst_nents;
-+ u32 textsize = rctx->textsize;
-+ u32 authsize = rctx->authsize;
-+ u32 blksize = rctx->blksize;
-+ u32 totlen_src = rctx->assoclen + rctx->textsize;
-+ u32 totlen_dst = rctx->assoclen + rctx->textsize;
-+ u32 copy_len;
-+ bool src_align, dst_align;
-+ int err = -EINVAL;
-+
-+ if (!IS_CTR(rctx->flags)) {
-+ if (!IS_ALIGNED(textsize, blksize))
-+ return err;
-+ }
-+
-+ if (authsize) {
-+ if (IS_ENCRYPT(rctx->flags))
-+ totlen_dst += authsize;
-+ else
-+ totlen_src += authsize;
-+ }
-+
-+ src_nents = sg_nents_for_len(src, totlen_src);
-+ dst_nents = sg_nents_for_len(dst, totlen_dst);
-+
-+ if (src == dst) {
-+ src_nents = max(src_nents, dst_nents);
-+ dst_nents = src_nents;
-+ if (unlikely((totlen_src || totlen_dst) && (src_nents <= 0)))
-+ return err;
-+
-+ } else {
-+ if (unlikely(totlen_src && (src_nents <= 0)))
-+ return err;
-+
-+ if (unlikely(totlen_dst && (dst_nents <= 0)))
-+ return err;
-+ }
-+
-+ if (authsize) {
-+ if (dst_nents == 1 && src_nents == 1) {
-+ src_align = mtk_is_sg_aligned(src, totlen_src, blksize);
-+ if (src == dst)
-+ dst_align = src_align;
-+ else
-+ dst_align = mtk_is_sg_aligned(dst,
-+ totlen_dst, blksize);
-+ } else {
-+ src_align = false;
-+ dst_align = false;
-+ }
-+ } else {
-+ src_align = mtk_is_sg_aligned(src, totlen_src, blksize);
-+ if (src == dst)
-+ dst_align = src_align;
-+ else
-+ dst_align = mtk_is_sg_aligned(dst, totlen_dst, blksize);
-+ }
-+
-+ copy_len = max(totlen_src, totlen_dst);
-+ if (!src_align) {
-+ err = mtk_make_sg_copy(src, &rctx->sg_src, copy_len, true);
-+ if (err)
-+ return err;
-+ }
-+
-+ if (!dst_align) {
-+ err = mtk_make_sg_copy(dst, &rctx->sg_dst, copy_len, false);
-+ if (err)
-+ return err;
-+ }
-+
-+ rctx->src_nents = sg_nents_for_len(rctx->sg_src, totlen_src);
-+ rctx->dst_nents = sg_nents_for_len(rctx->sg_dst, totlen_dst);
-+
-+ return 0;
-+}
-+/*
-+ * Set saRecord function:
-+ * Even saRecord is set to "0", keep " = 0" for readability.
-+ */
-+void mtk_set_saRecord(struct saRecord_s *saRecord, const unsigned int keylen,
-+ const u32 flags)
-+{
-+ saRecord->saCmd0.bits.ivSource = 2;
-+ if (IS_ECB(flags))
-+ saRecord->saCmd0.bits.saveIv = 0;
-+ else
-+ saRecord->saCmd0.bits.saveIv = 1;
-+
-+ saRecord->saCmd0.bits.opGroup = 0;
-+ saRecord->saCmd0.bits.opCode = 0;
-+
-+ switch ((flags & MTK_ALG_MASK)) {
-+ case MTK_ALG_AES:
-+ saRecord->saCmd0.bits.cipher = 3;
-+ saRecord->saCmd1.bits.aesKeyLen = keylen >> 3;
-+ break;
-+ case MTK_ALG_3DES:
-+ saRecord->saCmd0.bits.cipher = 1;
-+ break;
-+ case MTK_ALG_DES:
-+ saRecord->saCmd0.bits.cipher = 0;
-+ break;
-+ default:
-+ saRecord->saCmd0.bits.cipher = 15;
-+ }
-+
-+ switch ((flags & MTK_HASH_MASK)) {
-+ case MTK_HASH_SHA256:
-+ saRecord->saCmd0.bits.hash = 3;
-+ break;
-+ case MTK_HASH_SHA224:
-+ saRecord->saCmd0.bits.hash = 2;
-+ break;
-+ case MTK_HASH_SHA1:
-+ saRecord->saCmd0.bits.hash = 1;
-+ break;
-+ case MTK_HASH_MD5:
-+ saRecord->saCmd0.bits.hash = 0;
-+ break;
-+ default:
-+ saRecord->saCmd0.bits.hash = 15;
-+ }
-+
-+ saRecord->saCmd0.bits.hdrProc = 0;
-+ saRecord->saCmd0.bits.padType = 3;
-+ saRecord->saCmd0.bits.extPad = 0;
-+ saRecord->saCmd0.bits.scPad = 0;
-+
-+ switch ((flags & MTK_MODE_MASK)) {
-+ case MTK_MODE_CBC:
-+ saRecord->saCmd1.bits.cipherMode = 1;
-+ break;
-+ case MTK_MODE_CTR:
-+ saRecord->saCmd1.bits.cipherMode = 2;
-+ break;
-+ case MTK_MODE_ECB:
-+ saRecord->saCmd1.bits.cipherMode = 0;
-+ break;
-+ }
-+
-+ saRecord->saCmd1.bits.byteOffset = 0;
-+ saRecord->saCmd1.bits.hashCryptOffset = 0;
-+ saRecord->saCmd0.bits.digestLength = 0;
-+ saRecord->saCmd1.bits.copyPayload = 0;
-+
-+ if (IS_HMAC(flags)) {
-+ saRecord->saCmd1.bits.hmac = 1;
-+ saRecord->saCmd1.bits.copyDigest = 1;
-+ saRecord->saCmd1.bits.copyHeader = 1;
-+ } else {
-+ saRecord->saCmd1.bits.hmac = 0;
-+ saRecord->saCmd1.bits.copyDigest = 0;
-+ saRecord->saCmd1.bits.copyHeader = 0;
-+ }
-+
-+ saRecord->saCmd1.bits.seqNumCheck = 0;
-+ saRecord->saSpi = 0x0;
-+ saRecord->saSeqNumMask[0] = 0xFFFFFFFF;
-+ saRecord->saSeqNumMask[1] = 0x0;
-+}
-+
-+/*
-+ * Poor mans Scatter/gather function:
-+ * Create a Descriptor for every segment to avoid copying buffers.
-+ * For performance better to wait for hardware to perform multiple DMA
-+ *
-+ */
-+static inline int mtk_scatter_combine(struct mtk_device *mtk,
-+ struct mtk_cipher_reqctx *rctx,
-+ u32 datalen, u32 split, int offsetin)
-+{
-+ struct eip93_descriptor_s *cdesc = rctx->cdesc;
-+ struct scatterlist *sgsrc = rctx->sg_src;
-+ struct scatterlist *sgdst = rctx->sg_dst;
-+ unsigned int remainin = sg_dma_len(sgsrc);
-+ unsigned int remainout = sg_dma_len(sgdst);
-+ dma_addr_t saddr = sg_dma_address(sgsrc);
-+ dma_addr_t daddr = sg_dma_address(sgdst);
-+ dma_addr_t stateAddr;
-+ u32 srcAddr, dstAddr, len, n;
-+ bool nextin = false;
-+ bool nextout = false;
-+ int offsetout = 0;
-+ int ndesc_cdr = 0, err;
-+
-+ if (IS_ECB(rctx->flags))
-+ rctx->saState_base = 0;
-+
-+ if (split < datalen) {
-+ stateAddr = rctx->saState_base_ctr;
-+ n = split;
-+ } else {
-+ stateAddr = rctx->saState_base;
-+ n = datalen;
-+ }
-+
-+ do {
-+ if (nextin) {
-+ sgsrc = sg_next(sgsrc);
-+ remainin = sg_dma_len(sgsrc);
-+ if (remainin == 0)
-+ continue;
-+
-+ saddr = sg_dma_address(sgsrc);
-+ offsetin = 0;
-+ nextin = false;
-+ }
-+
-+ if (nextout) {
-+ sgdst = sg_next(sgdst);
-+ remainout = sg_dma_len(sgdst);
-+ if (remainout == 0)
-+ continue;
-+
-+ daddr = sg_dma_address(sgdst);
-+ offsetout = 0;
-+ nextout = false;
-+ }
-+ srcAddr = saddr + offsetin;
-+ dstAddr = daddr + offsetout;
-+
-+ if (remainin == remainout) {
-+ len = remainin;
-+ if (len > n) {
-+ len = n;
-+ remainin -= n;
-+ remainout -= n;
-+ offsetin += n;
-+ offsetout += n;
-+ } else {
-+ nextin = true;
-+ nextout = true;
-+ }
-+ } else if (remainin < remainout) {
-+ len = remainin;
-+ if (len > n) {
-+ len = n;
-+ remainin -= n;
-+ remainout -= n;
-+ offsetin += n;
-+ offsetout += n;
-+ } else {
-+ offsetout += len;
-+ remainout -= len;
-+ nextin = true;
-+ }
-+ } else {
-+ len = remainout;
-+ if (len > n) {
-+ len = n;
-+ remainin -= n;
-+ remainout -= n;
-+ offsetin += n;
-+ offsetout += n;
-+ } else {
-+ offsetin += len;
-+ remainin -= len;
-+ nextout = true;
-+ }
-+ }
-+ n -= len;
-+
-+ cdesc->srcAddr = srcAddr;
-+ cdesc->dstAddr = dstAddr;
-+ cdesc->stateAddr = stateAddr;
-+ cdesc->peLength.bits.peReady = 0;
-+ cdesc->peLength.bits.byPass = 0;
-+ cdesc->peLength.bits.length = len;
-+ cdesc->peLength.bits.hostReady = 1;
-+
-+ if (n == 0) {
-+ n = datalen - split;
-+ split = datalen;
-+ stateAddr = rctx->saState_base;
-+ }
-+
-+ if (n == 0)
-+ cdesc->userId |= MTK_DESC_LAST;
-+
-+ /* Loop - Delay - No need to rollback
-+ * Maybe refine by slowing down at MTK_RING_BUSY
-+ */
-+again:
-+ err = mtk_put_descriptor(mtk, cdesc);
-+ if (err) {
-+ udelay(500);
-+ goto again;
-+ }
-+ /* Writing new descriptor count starts DMA action */
-+ writel(1, mtk->base + EIP93_REG_PE_CD_COUNT);
-+
-+ ndesc_cdr++;
-+ } while (n);
-+
-+ return -EINPROGRESS;
-+}
-+
-+int mtk_send_req(struct crypto_async_request *async,
-+ const u8 *reqiv, struct mtk_cipher_reqctx *rctx)
-+{
-+ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm);
-+ struct mtk_device *mtk = ctx->mtk;
-+ struct scatterlist *src = rctx->sg_src;
-+ struct scatterlist *dst = rctx->sg_dst;
-+ struct saState_s *saState;
-+ struct mtk_state_pool *saState_pool;
-+ struct eip93_descriptor_s cdesc;
-+ u32 flags = rctx->flags;
-+ int idx;
-+ int offsetin = 0, err = -ENOMEM;
-+ u32 datalen = rctx->assoclen + rctx->textsize;
-+ u32 split = datalen;
-+ u32 start, end, ctr, blocks;
-+ u32 iv[AES_BLOCK_SIZE / sizeof(u32)];
-+
-+ rctx->saState_ctr = NULL;
-+ rctx->saState = NULL;
-+
-+ if (IS_ECB(flags))
-+ goto skip_iv;
-+
-+ memcpy(iv, reqiv, rctx->ivsize);
-+
-+ if (!IS_ALIGNED((u32)reqiv, rctx->ivsize) || IS_RFC3686(flags)) {
-+ rctx->flags &= ~MTK_DESC_DMA_IV;
-+ flags = rctx->flags;
-+ }
-+
-+ if (IS_DMA_IV(flags)) {
-+ rctx->saState = (void *)reqiv;
-+ } else {
-+ idx = mtk_get_free_saState(mtk);
-+ if (idx < 0)
-+ goto send_err;
-+ saState_pool = &mtk->ring->saState_pool[idx];
-+ rctx->saState_idx = idx;
-+ rctx->saState = saState_pool->base;
-+ rctx->saState_base = saState_pool->base_dma;
-+ memcpy(rctx->saState->stateIv, iv, rctx->ivsize);
-+ }
-+
-+ saState = rctx->saState;
-+
-+ if (IS_RFC3686(flags)) {
-+ saState->stateIv[0] = ctx->saNonce;
-+ saState->stateIv[1] = iv[0];
-+ saState->stateIv[2] = iv[1];
-+ saState->stateIv[3] = cpu_to_be32(1);
-+ } else if (!IS_HMAC(flags) && IS_CTR(flags)) {
-+ /* Compute data length. */
-+ blocks = DIV_ROUND_UP(rctx->textsize, AES_BLOCK_SIZE);
-+ ctr = be32_to_cpu(iv[3]);
-+ /* Check 32bit counter overflow. */
-+ start = ctr;
-+ end = start + blocks - 1;
-+ if (end < start) {
-+ split = AES_BLOCK_SIZE * -start;
-+ /*
-+ * Increment the counter manually to cope with
-+ * the hardware counter overflow.
-+ */
-+ iv[3] = 0xffffffff;
-+ crypto_inc((u8 *)iv, AES_BLOCK_SIZE);
-+ idx = mtk_get_free_saState(mtk);
-+ if (idx < 0)
-+ goto free_state;
-+ saState_pool = &mtk->ring->saState_pool[idx];
-+ rctx->saState_ctr_idx = idx;
-+ rctx->saState_ctr = saState_pool->base;
-+ rctx->saState_base_ctr = saState_pool->base_dma;
-+
-+ memcpy(rctx->saState_ctr->stateIv, reqiv, rctx->ivsize);
-+ memcpy(saState->stateIv, iv, rctx->ivsize);
-+ }
-+ }
-+
-+ if (IS_DMA_IV(flags)) {
-+ rctx->saState_base = dma_map_single(mtk->dev, (void *)reqiv,
-+ rctx->ivsize, DMA_TO_DEVICE);
-+ if (dma_mapping_error(mtk->dev, rctx->saState_base))
-+ goto free_state;
-+ }
-+skip_iv:
-+ cdesc.peCrtlStat.bits.hostReady = 1;
-+ cdesc.peCrtlStat.bits.prngMode = 0;
-+ cdesc.peCrtlStat.bits.hashFinal = 0;
-+ cdesc.peCrtlStat.bits.padCrtlStat = 0;
-+ cdesc.peCrtlStat.bits.peReady = 0;
-+ cdesc.saAddr = rctx->saRecord_base;
-+ cdesc.arc4Addr = (uint32_t)async;
-+ cdesc.userId = flags;
-+ rctx->cdesc = &cdesc;
-+
-+ /* map DMA_BIDIRECTIONAL to invalidate cache on destination
-+ * implies __dma_cache_wback_inv
-+ */
-+ dma_map_sg(mtk->dev, dst, rctx->dst_nents, DMA_BIDIRECTIONAL);
-+ if (src != dst)
-+ dma_map_sg(mtk->dev, src, rctx->src_nents, DMA_TO_DEVICE);
-+
-+ err = mtk_scatter_combine(mtk, rctx, datalen, split, offsetin);
-+
-+ return err;
-+
-+free_state:
-+ if (rctx->saState) {
-+ saState_pool = &mtk->ring->saState_pool[rctx->saState_idx];
-+ saState_pool->in_use = false;
-+ }
-+
-+ if (rctx->saState_ctr) {
-+ saState_pool = &mtk->ring->saState_pool[rctx->saState_ctr_idx];
-+ saState_pool->in_use = false;
-+ }
-+send_err:
-+ return err;
-+}
-+
-+void mtk_unmap_dma(struct mtk_device *mtk, struct mtk_cipher_reqctx *rctx,
-+ struct scatterlist *reqsrc, struct scatterlist *reqdst)
-+{
-+ u32 len = rctx->assoclen + rctx->textsize;
-+ u32 authsize = rctx->authsize;
-+ u32 flags = rctx->flags;
-+ u32 *otag;
-+ int i;
-+
-+ if (rctx->sg_src == rctx->sg_dst) {
-+ dma_unmap_sg(mtk->dev, rctx->sg_dst, rctx->dst_nents,
-+ DMA_BIDIRECTIONAL);
-+ goto process_tag;
-+ }
-+
-+ dma_unmap_sg(mtk->dev, rctx->sg_src, rctx->src_nents,
-+ DMA_TO_DEVICE);
-+
-+ if (rctx->sg_src != reqsrc)
-+ mtk_free_sg_copy(len + rctx->authsize, &rctx->sg_src);
-+
-+ dma_unmap_sg(mtk->dev, rctx->sg_dst, rctx->dst_nents,
-+ DMA_BIDIRECTIONAL);
-+
-+ /* SHA tags need conversion from net-to-host */
-+process_tag:
-+ if (IS_DECRYPT(flags))
-+ authsize = 0;
-+
-+ if (authsize) {
-+ if (!IS_HASH_MD5(flags)) {
-+ otag = sg_virt(rctx->sg_dst) + len;
-+ for (i = 0; i < (authsize / 4); i++)
-+ otag[i] = ntohl(otag[i]);
-+ }
-+ }
-+
-+ if (rctx->sg_dst != reqdst) {
-+ sg_copy_from_buffer(reqdst, sg_nents(reqdst),
-+ sg_virt(rctx->sg_dst), len + authsize);
-+ mtk_free_sg_copy(len + rctx->authsize, &rctx->sg_dst);
-+ }
-+}
-+
-+void mtk_handle_result(struct mtk_device *mtk, struct mtk_cipher_reqctx *rctx,
-+ u8 *reqiv)
-+{
-+ struct mtk_state_pool *saState_pool;
-+
-+ if (IS_DMA_IV(rctx->flags))
-+ dma_unmap_single(mtk->dev, rctx->saState_base, rctx->ivsize,
-+ DMA_TO_DEVICE);
-+
-+ if (!IS_ECB(rctx->flags))
-+ memcpy(reqiv, rctx->saState->stateIv, rctx->ivsize);
-+
-+ if ((rctx->saState) && !(IS_DMA_IV(rctx->flags))) {
-+ saState_pool = &mtk->ring->saState_pool[rctx->saState_idx];
-+ saState_pool->in_use = false;
-+ }
-+
-+ if (rctx->saState_ctr) {
-+ saState_pool = &mtk->ring->saState_pool[rctx->saState_ctr_idx];
-+ saState_pool->in_use = false;
-+ }
-+}
-+
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_HMAC)
-+/* basically this is set hmac - key */
-+int mtk_authenc_setkey(struct crypto_shash *cshash, struct saRecord_s *sa,
-+ const u8 *authkey, unsigned int authkeylen)
-+{
-+ int bs = crypto_shash_blocksize(cshash);
-+ int ds = crypto_shash_digestsize(cshash);
-+ int ss = crypto_shash_statesize(cshash);
-+ u8 *ipad, *opad;
-+ unsigned int i, err;
-+
-+ SHASH_DESC_ON_STACK(shash, cshash);
-+
-+ shash->tfm = cshash;
-+
-+ /* auth key
-+ *
-+ * EIP93 can only authenticate with hash of the key
-+ * do software shash until EIP93 hash function complete.
-+ */
-+ ipad = kcalloc(2, SHA256_BLOCK_SIZE + ss, GFP_KERNEL);
-+ if (!ipad)
-+ return -ENOMEM;
-+
-+ opad = ipad + SHA256_BLOCK_SIZE + ss;
-+
-+ if (authkeylen > bs) {
-+ err = crypto_shash_digest(shash, authkey,
-+ authkeylen, ipad);
-+ if (err)
-+ return err;
-+
-+ authkeylen = ds;
-+ } else
-+ memcpy(ipad, authkey, authkeylen);
-+
-+ memset(ipad + authkeylen, 0, bs - authkeylen);
-+ memcpy(opad, ipad, bs);
-+
-+ for (i = 0; i < bs; i++) {
-+ ipad[i] ^= HMAC_IPAD_VALUE;
-+ opad[i] ^= HMAC_OPAD_VALUE;
-+ }
-+
-+ err = crypto_shash_init(shash) ?:
-+ crypto_shash_update(shash, ipad, bs) ?:
-+ crypto_shash_export(shash, ipad) ?:
-+ crypto_shash_init(shash) ?:
-+ crypto_shash_update(shash, opad, bs) ?:
-+ crypto_shash_export(shash, opad);
-+
-+ if (err)
-+ return err;
-+
-+ /* add auth key */
-+ memcpy(&sa->saIDigest, ipad, SHA256_DIGEST_SIZE);
-+ memcpy(&sa->saODigest, opad, SHA256_DIGEST_SIZE);
-+
-+ kfree(ipad);
-+ return 0;
-+}
-+#endif
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-common.h
-@@ -0,0 +1,28 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+
-+#ifndef _EIP93_COMMON_H_
-+#define _EIP93_COMMON_H_
-+
-+#include "eip93-main.h"
-+
-+inline int mtk_put_descriptor(struct mtk_device *mtk,
-+ struct eip93_descriptor_s *desc);
-+
-+inline void *mtk_get_descriptor(struct mtk_device *mtk);
-+
-+inline int mtk_get_free_saState(struct mtk_device *mtk);
-+
-+void mtk_set_saRecord(struct saRecord_s *saRecord, const unsigned int keylen,
-+ const u32 flags);
-+
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_HMAC)
-+int mtk_authenc_setkey(struct crypto_shash *cshash, struct saRecord_s *sa,
-+ const u8 *authkey, unsigned int authkeylen);
-+#endif
-+
-+#endif /* _EIP93_COMMON_H_ */
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-des.h
-@@ -0,0 +1,15 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+#ifndef _EIP93_DES_H_
-+#define _EIP93_DES_H_
-+
-+extern struct mtk_alg_template mtk_alg_ecb_des;
-+extern struct mtk_alg_template mtk_alg_cbc_des;
-+extern struct mtk_alg_template mtk_alg_ecb_des3_ede;
-+extern struct mtk_alg_template mtk_alg_cbc_des3_ede;
-+
-+#endif /* _EIP93_DES_H_ */
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-main.c
-@@ -0,0 +1,467 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+
-+#include <linux/atomic.h>
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/interrupt.h>
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/spinlock.h>
-+
-+#include "eip93-main.h"
-+#include "eip93-regs.h"
-+#include "eip93-common.h"
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_SKCIPHER)
-+#include "eip93-cipher.h"
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
-+#include "eip93-aes.h"
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+#include "eip93-des.h"
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AEAD)
-+#include "eip93-aead.h"
-+#endif
-+
-+static struct mtk_alg_template *mtk_algs[] = {
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+ &mtk_alg_ecb_des,
-+ &mtk_alg_cbc_des,
-+ &mtk_alg_ecb_des3_ede,
-+ &mtk_alg_cbc_des3_ede,
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
-+ &mtk_alg_ecb_aes,
-+ &mtk_alg_cbc_aes,
-+ &mtk_alg_ctr_aes,
-+ &mtk_alg_rfc3686_aes,
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AEAD)
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+ &mtk_alg_authenc_hmac_md5_cbc_des,
-+ &mtk_alg_authenc_hmac_sha1_cbc_des,
-+ &mtk_alg_authenc_hmac_sha224_cbc_des,
-+ &mtk_alg_authenc_hmac_sha256_cbc_des,
-+ &mtk_alg_authenc_hmac_md5_cbc_des3_ede,
-+ &mtk_alg_authenc_hmac_sha1_cbc_des3_ede,
-+ &mtk_alg_authenc_hmac_sha224_cbc_des3_ede,
-+ &mtk_alg_authenc_hmac_sha256_cbc_des3_ede,
-+#endif
-+ &mtk_alg_authenc_hmac_md5_cbc_aes,
-+ &mtk_alg_authenc_hmac_sha1_cbc_aes,
-+ &mtk_alg_authenc_hmac_sha224_cbc_aes,
-+ &mtk_alg_authenc_hmac_sha256_cbc_aes,
-+ &mtk_alg_authenc_hmac_md5_rfc3686_aes,
-+ &mtk_alg_authenc_hmac_sha1_rfc3686_aes,
-+ &mtk_alg_authenc_hmac_sha224_rfc3686_aes,
-+ &mtk_alg_authenc_hmac_sha256_rfc3686_aes,
-+#endif
-+};
-+
-+inline void mtk_irq_disable(struct mtk_device *mtk, u32 mask)
-+{
-+ __raw_writel(mask, mtk->base + EIP93_REG_MASK_DISABLE);
-+}
-+
-+inline void mtk_irq_enable(struct mtk_device *mtk, u32 mask)
-+{
-+ __raw_writel(mask, mtk->base + EIP93_REG_MASK_ENABLE);
-+}
-+
-+inline void mtk_irq_clear(struct mtk_device *mtk, u32 mask)
-+{
-+ __raw_writel(mask, mtk->base + EIP93_REG_INT_CLR);
-+}
-+
-+static void mtk_unregister_algs(unsigned int i)
-+{
-+ unsigned int j;
-+
-+ for (j = 0; j < i; j++) {
-+ switch (mtk_algs[j]->type) {
-+ case MTK_ALG_TYPE_SKCIPHER:
-+ crypto_unregister_skcipher(&mtk_algs[j]->alg.skcipher);
-+ break;
-+ case MTK_ALG_TYPE_AEAD:
-+ crypto_unregister_aead(&mtk_algs[j]->alg.aead);
-+ break;
-+ }
-+ }
-+}
-+
-+static int mtk_register_algs(struct mtk_device *mtk)
-+{
-+ unsigned int i;
-+ int err = 0;
-+
-+ for (i = 0; i < ARRAY_SIZE(mtk_algs); i++) {
-+ mtk_algs[i]->mtk = mtk;
-+
-+ switch (mtk_algs[i]->type) {
-+ case MTK_ALG_TYPE_SKCIPHER:
-+ err = crypto_register_skcipher(&mtk_algs[i]->alg.skcipher);
-+ break;
-+ case MTK_ALG_TYPE_AEAD:
-+ err = crypto_register_aead(&mtk_algs[i]->alg.aead);
-+ break;
-+ }
-+ if (err)
-+ goto fail;
-+ }
-+
-+ return 0;
-+
-+fail:
-+ mtk_unregister_algs(i);
-+
-+ return err;
-+}
-+
-+static void mtk_handle_result_descriptor(struct mtk_device *mtk)
-+{
-+ struct crypto_async_request *async;
-+ struct eip93_descriptor_s *rdesc;
-+ bool last_entry;
-+ u32 flags;
-+ int handled, ready, err;
-+ union peCrtlStat_w done1;
-+ union peLength_w done2;
-+
-+get_more:
-+ handled = 0;
-+
-+ ready = readl(mtk->base + EIP93_REG_PE_RD_COUNT) & GENMASK(10, 0);
-+
-+ if (!ready) {
-+ mtk_irq_clear(mtk, EIP93_INT_PE_RDRTHRESH_REQ);
-+ mtk_irq_enable(mtk, EIP93_INT_PE_RDRTHRESH_REQ);
-+ return;
-+ }
-+
-+ last_entry = false;
-+
-+ while (ready) {
-+ rdesc = mtk_get_descriptor(mtk);
-+ if (IS_ERR(rdesc)) {
-+ dev_err(mtk->dev, "Ndesc: %d nreq: %d\n",
-+ handled, ready);
-+ err = -EIO;
-+ break;
-+ }
-+ /* make sure DMA is finished writing */
-+ do {
-+ done1.word = READ_ONCE(rdesc->peCrtlStat.word);
-+ done2.word = READ_ONCE(rdesc->peLength.word);
-+ } while ((!done1.bits.peReady) || (!done2.bits.peReady));
-+
-+ err = rdesc->peCrtlStat.bits.errStatus;
-+
-+ flags = rdesc->userId;
-+ async = (struct crypto_async_request *)rdesc->arc4Addr;
-+
-+ writel(1, mtk->base + EIP93_REG_PE_RD_COUNT);
-+ mtk_irq_clear(mtk, EIP93_INT_PE_RDRTHRESH_REQ);
-+
-+ handled++;
-+ ready--;
-+
-+ if (flags & MTK_DESC_LAST) {
-+ last_entry = true;
-+ break;
-+ }
-+ }
-+
-+ if (!last_entry)
-+ goto get_more;
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_SKCIPHER)
-+ if (flags & MTK_DESC_SKCIPHER)
-+ mtk_skcipher_handle_result(async, err);
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AEAD)
-+ if (flags & MTK_DESC_AEAD)
-+ mtk_aead_handle_result(async, err);
-+#endif
-+ goto get_more;
-+}
-+
-+static void mtk_done_task(unsigned long data)
-+{
-+ struct mtk_device *mtk = (struct mtk_device *)data;
-+
-+ mtk_handle_result_descriptor(mtk);
-+}
-+
-+static irqreturn_t mtk_irq_handler(int irq, void *dev_id)
-+{
-+ struct mtk_device *mtk = (struct mtk_device *)dev_id;
-+ u32 irq_status;
-+
-+ irq_status = readl(mtk->base + EIP93_REG_INT_MASK_STAT);
-+
-+ if (irq_status & EIP93_INT_PE_RDRTHRESH_REQ) {
-+ mtk_irq_disable(mtk, EIP93_INT_PE_RDRTHRESH_REQ);
-+ tasklet_schedule(&mtk->ring->done_task);
-+ return IRQ_HANDLED;
-+ }
-+
-+ mtk_irq_clear(mtk, irq_status);
-+ if (irq_status)
-+ mtk_irq_disable(mtk, irq_status);
-+
-+ return IRQ_NONE;
-+}
-+
-+static void mtk_initialize(struct mtk_device *mtk)
-+{
-+ union peConfig_w peConfig;
-+ union peEndianCfg_w peEndianCfg;
-+ union peIntCfg_w peIntCfg;
-+ union peClockCfg_w peClockCfg;
-+ union peBufThresh_w peBufThresh;
-+ union peRingThresh_w peRingThresh;
-+
-+ /* Reset Engine and setup Mode */
-+ peConfig.word = 0;
-+ peConfig.bits.resetPE = 1;
-+ peConfig.bits.resetRing = 1;
-+ peConfig.bits.peMode = 3;
-+ peConfig.bits.enCDRupdate = 1;
-+
-+ writel(peConfig.word, mtk->base + EIP93_REG_PE_CONFIG);
-+
-+ udelay(10);
-+
-+ peConfig.bits.resetPE = 0;
-+ peConfig.bits.resetRing = 0;
-+
-+ writel(peConfig.word, mtk->base + EIP93_REG_PE_CONFIG);
-+
-+ /* Initialize the BYTE_ORDER_CFG register */
-+ peEndianCfg.word = 0;
-+ writel(peEndianCfg.word, mtk->base + EIP93_REG_PE_ENDIAN_CONFIG);
-+
-+ /* Initialize the INT_CFG register */
-+ peIntCfg.word = 0;
-+ writel(peIntCfg.word, mtk->base + EIP93_REG_INT_CFG);
-+
-+ /* Config Clocks */
-+ peClockCfg.word = 0;
-+ peClockCfg.bits.enPEclk = 1;
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES)
-+ peClockCfg.bits.enDESclk = 1;
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES)
-+ peClockCfg.bits.enAESclk = 1;
-+#endif
-+#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_HMAC)
-+ peClockCfg.bits.enHASHclk = 1;
-+#endif
-+ writel(peClockCfg.word, mtk->base + EIP93_REG_PE_CLOCK_CTRL);
-+
-+ /* Config DMA thresholds */
-+ peBufThresh.word = 0;
-+ peBufThresh.bits.inputBuffer = 128;
-+ peBufThresh.bits.outputBuffer = 128;
-+
-+ writel(peBufThresh.word, mtk->base + EIP93_REG_PE_BUF_THRESH);
-+
-+ /* Clear/ack all interrupts before disable all */
-+ mtk_irq_clear(mtk, 0xFFFFFFFF);
-+ mtk_irq_disable(mtk, 0xFFFFFFFF);
-+
-+ /* Config Ring Threshold */
-+ peRingThresh.word = 0;
-+ peRingThresh.bits.CDRThresh = MTK_RING_SIZE - MTK_RING_BUSY;
-+ peRingThresh.bits.RDRThresh = 0;
-+ peRingThresh.bits.RDTimeout = 5;
-+ peRingThresh.bits.enTimeout = 1;
-+
-+ writel(peRingThresh.word, mtk->base + EIP93_REG_PE_RING_THRESH);
-+}
-+
-+static void mtk_desc_free(struct mtk_device *mtk)
-+{
-+ writel(0, mtk->base + EIP93_REG_PE_RING_CONFIG);
-+ writel(0, mtk->base + EIP93_REG_PE_CDR_BASE);
-+ writel(0, mtk->base + EIP93_REG_PE_RDR_BASE);
-+}
-+
-+static int mtk_set_ring(struct mtk_device *mtk, struct mtk_desc_ring *ring,
-+ int Offset)
-+{
-+ ring->offset = Offset;
-+ ring->base = dmam_alloc_coherent(mtk->dev, Offset * MTK_RING_SIZE,
-+ &ring->base_dma, GFP_KERNEL);
-+ if (!ring->base)
-+ return -ENOMEM;
-+
-+ ring->write = ring->base;
-+ ring->base_end = ring->base + Offset * (MTK_RING_SIZE - 1);
-+ ring->read = ring->base;
-+
-+ return 0;
-+}
-+
-+static int mtk_desc_init(struct mtk_device *mtk)
-+{
-+ struct mtk_state_pool *saState_pool;
-+ struct mtk_desc_ring *cdr = &mtk->ring->cdr;
-+ struct mtk_desc_ring *rdr = &mtk->ring->rdr;
-+ union peRingCfg_w peRingCfg;
-+ int RingOffset, err, i;
-+
-+ RingOffset = sizeof(struct eip93_descriptor_s);
-+
-+ err = mtk_set_ring(mtk, cdr, RingOffset);
-+ if (err)
-+ return err;
-+
-+ err = mtk_set_ring(mtk, rdr, RingOffset);
-+ if (err)
-+ return err;
-+
-+ writel((u32)cdr->base_dma, mtk->base + EIP93_REG_PE_CDR_BASE);
-+ writel((u32)rdr->base_dma, mtk->base + EIP93_REG_PE_RDR_BASE);
-+
-+ peRingCfg.word = 0;
-+ peRingCfg.bits.ringSize = MTK_RING_SIZE - 1;
-+ peRingCfg.bits.ringOffset = RingOffset / 4;
-+
-+ writel(peRingCfg.word, mtk->base + EIP93_REG_PE_RING_CONFIG);
-+
-+ atomic_set(&mtk->ring->free, MTK_RING_SIZE - 1);
-+ /* Create State record DMA pool */
-+ RingOffset = sizeof(struct saState_s);
-+ mtk->ring->saState = dmam_alloc_coherent(mtk->dev,
-+ RingOffset * MTK_RING_SIZE,
-+ &mtk->ring->saState_dma, GFP_KERNEL);
-+ if (!mtk->ring->saState)
-+ return -ENOMEM;
-+
-+ mtk->ring->saState_pool = devm_kcalloc(mtk->dev, 1,
-+ sizeof(struct mtk_state_pool) * MTK_RING_SIZE,
-+ GFP_KERNEL);
-+
-+ for (i = 0; i < MTK_RING_SIZE; i++) {
-+ saState_pool = &mtk->ring->saState_pool[i];
-+ saState_pool->base = mtk->ring->saState + (i * RingOffset);
-+ saState_pool->base_dma = mtk->ring->saState_dma + (i * RingOffset);
-+ saState_pool->in_use = false;
-+ }
-+
-+ return 0;
-+}
-+
-+static void mtk_cleanup(struct mtk_device *mtk)
-+{
-+ tasklet_kill(&mtk->ring->done_task);
-+
-+ /* Clear/ack all interrupts before disable all */
-+ mtk_irq_clear(mtk, 0xFFFFFFFF);
-+ mtk_irq_disable(mtk, 0xFFFFFFFF);
-+
-+ writel(0, mtk->base + EIP93_REG_PE_CLOCK_CTRL);
-+
-+ mtk_desc_free(mtk);
-+}
-+
-+static int mtk_crypto_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct mtk_device *mtk;
-+ struct resource *res;
-+ int err;
-+
-+ mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL);
-+ if (!mtk)
-+ return -ENOMEM;
-+
-+ mtk->dev = dev;
-+ platform_set_drvdata(pdev, mtk);
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ mtk->base = devm_ioremap_resource(&pdev->dev, res);
-+
-+ if (IS_ERR(mtk->base))
-+ return PTR_ERR(mtk->base);
-+
-+ mtk->irq = platform_get_irq(pdev, 0);
-+
-+ if (mtk->irq < 0)
-+ return mtk->irq;
-+
-+ err = devm_request_threaded_irq(mtk->dev, mtk->irq, mtk_irq_handler,
-+ NULL, IRQF_ONESHOT,
-+ dev_name(mtk->dev), mtk);
-+
-+ mtk->ring = devm_kcalloc(mtk->dev, 1, sizeof(*mtk->ring), GFP_KERNEL);
-+
-+ if (!mtk->ring)
-+ return -ENOMEM;
-+
-+ err = mtk_desc_init(mtk);
-+ if (err)
-+ return err;
-+
-+ tasklet_init(&mtk->ring->done_task, mtk_done_task, (unsigned long)mtk);
-+
-+ spin_lock_init(&mtk->ring->read_lock);
-+ spin_lock_init(&mtk->ring->write_lock);
-+
-+ mtk_initialize(mtk);
-+
-+ /* Init. finished, enable RDR interupt */
-+ mtk_irq_enable(mtk, EIP93_INT_PE_RDRTHRESH_REQ);
-+
-+ err = mtk_register_algs(mtk);
-+ if (err) {
-+ mtk_cleanup(mtk);
-+ return err;
-+ }
-+
-+ dev_info(mtk->dev, "EIP93 Crypto Engine Initialized.");
-+
-+ return 0;
-+}
-+
-+static int mtk_crypto_remove(struct platform_device *pdev)
-+{
-+ struct mtk_device *mtk = platform_get_drvdata(pdev);
-+
-+ mtk_unregister_algs(ARRAY_SIZE(mtk_algs));
-+ mtk_cleanup(mtk);
-+ dev_info(mtk->dev, "EIP93 removed.\n");
-+
-+ return 0;
-+}
-+
-+#if defined(CONFIG_OF)
-+static const struct of_device_id mtk_crypto_of_match[] = {
-+ { .compatible = "mediatek,mtk-eip93", },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, mtk_crypto_of_match);
-+#endif
-+
-+static struct platform_driver mtk_crypto_driver = {
-+ .probe = mtk_crypto_probe,
-+ .remove = mtk_crypto_remove,
-+ .driver = {
-+ .name = "mtk-eip93",
-+ .of_match_table = of_match_ptr(mtk_crypto_of_match),
-+ },
-+};
-+module_platform_driver(mtk_crypto_driver);
-+
-+MODULE_AUTHOR("Richard van Schagen <vschagen@cs.com>");
-+MODULE_ALIAS("platform:" KBUILD_MODNAME);
-+MODULE_DESCRIPTION("Mediatek EIP-93 crypto engine driver");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-main.h
-@@ -0,0 +1,146 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+#ifndef _EIP93_MAIN_H_
-+#define _EIP93_MAIN_H_
-+
-+#include <crypto/internal/aead.h>
-+#include <crypto/internal/hash.h>
-+#include <crypto/internal/rng.h>
-+#include <crypto/internal/skcipher.h>
-+#include <linux/device.h>
-+#include <linux/interrupt.h>
-+
-+#define MTK_RING_SIZE 512
-+#define MTK_RING_BUSY 32
-+#define MTK_CRA_PRIORITY 1500
-+
-+/* cipher algorithms */
-+#define MTK_ALG_DES BIT(0)
-+#define MTK_ALG_3DES BIT(1)
-+#define MTK_ALG_AES BIT(2)
-+#define MTK_ALG_MASK GENMASK(2, 0)
-+/* hash and hmac algorithms */
-+#define MTK_HASH_MD5 BIT(3)
-+#define MTK_HASH_SHA1 BIT(4)
-+#define MTK_HASH_SHA224 BIT(5)
-+#define MTK_HASH_SHA256 BIT(6)
-+#define MTK_HASH_HMAC BIT(7)
-+#define MTK_HASH_MASK GENMASK(6, 3)
-+/* cipher modes */
-+#define MTK_MODE_CBC BIT(8)
-+#define MTK_MODE_ECB BIT(9)
-+#define MTK_MODE_CTR BIT(10)
-+#define MTK_MODE_RFC3686 BIT(11)
-+#define MTK_MODE_MASK GENMASK(10, 8)
-+
-+/* cipher encryption/decryption operations */
-+#define MTK_ENCRYPT BIT(12)
-+#define MTK_DECRYPT BIT(13)
-+
-+#define MTK_BUSY BIT(14)
-+
-+/* descriptor flags */
-+#define MTK_DESC_ASYNC BIT(31)
-+#define MTK_DESC_SKCIPHER BIT(30)
-+#define MTK_DESC_AEAD BIT(29)
-+#define MTK_DESC_AHASH BIT(28)
-+#define MTK_DESC_PRNG BIT(27)
-+#define MTK_DESC_FAKE_HMAC BIT(26)
-+#define MTK_DESC_LAST BIT(25)
-+#define MTK_DESC_FINISH BIT(24)
-+#define MTK_DESC_IPSEC BIT(23)
-+#define MTK_DESC_DMA_IV BIT(22)
-+
-+#define IS_DES(flags) (flags & MTK_ALG_DES)
-+#define IS_3DES(flags) (flags & MTK_ALG_3DES)
-+#define IS_AES(flags) (flags & MTK_ALG_AES)
-+
-+#define IS_HASH_MD5(flags) (flags & MTK_HASH_MD5)
-+#define IS_HASH_SHA1(flags) (flags & MTK_HASH_SHA1)
-+#define IS_HASH_SHA224(flags) (flags & MTK_HASH_SHA224)
-+#define IS_HASH_SHA256(flags) (flags & MTK_HASH_SHA256)
-+#define IS_HMAC(flags) (flags & MTK_HASH_HMAC)
-+
-+#define IS_CBC(mode) (mode & MTK_MODE_CBC)
-+#define IS_ECB(mode) (mode & MTK_MODE_ECB)
-+#define IS_CTR(mode) (mode & MTK_MODE_CTR)
-+#define IS_RFC3686(mode) (mode & MTK_MODE_RFC3686)
-+
-+#define IS_BUSY(flags) (flags & MTK_BUSY)
-+#define IS_DMA_IV(flags) (flags & MTK_DESC_DMA_IV)
-+
-+#define IS_ENCRYPT(dir) (dir & MTK_ENCRYPT)
-+#define IS_DECRYPT(dir) (dir & MTK_DECRYPT)
-+
-+#define IS_CIPHER(flags) (flags & (MTK_ALG_DES || \
-+ MTK_ALG_3DES || \
-+ MTK_ALG_AES))
-+
-+#define IS_HASH(flags) (flags & (MTK_HASH_MD5 || \
-+ MTK_HASH_SHA1 || \
-+ MTK_HASH_SHA224 || \
-+ MTK_HASH_SHA256))
-+
-+/**
-+ * struct mtk_device - crypto engine device structure
-+ */
-+struct mtk_device {
-+ void __iomem *base;
-+ struct device *dev;
-+ struct clk *clk;
-+ int irq;
-+ struct mtk_ring *ring;
-+ struct mtk_state_pool *saState_pool;
-+};
-+
-+struct mtk_desc_ring {
-+ void *base;
-+ void *base_end;
-+ dma_addr_t base_dma;
-+ /* write and read pointers */
-+ void *read;
-+ void *write;
-+ /* descriptor element offset */
-+ u32 offset;
-+};
-+
-+struct mtk_state_pool {
-+ void *base;
-+ dma_addr_t base_dma;
-+ bool in_use;
-+};
-+
-+struct mtk_ring {
-+ struct tasklet_struct done_task;
-+ /* command/result rings */
-+ struct mtk_desc_ring cdr;
-+ struct mtk_desc_ring rdr;
-+ spinlock_t write_lock;
-+ spinlock_t read_lock;
-+ atomic_t free;
-+ /* saState */
-+ struct mtk_state_pool *saState_pool;
-+ void *saState;
-+ dma_addr_t saState_dma;
-+};
-+
-+enum mtk_alg_type {
-+ MTK_ALG_TYPE_AEAD,
-+ MTK_ALG_TYPE_SKCIPHER,
-+};
-+
-+struct mtk_alg_template {
-+ struct mtk_device *mtk;
-+ enum mtk_alg_type type;
-+ u32 flags;
-+ union {
-+ struct aead_alg aead;
-+ struct skcipher_alg skcipher;
-+ } alg;
-+};
-+
-+#endif /* _EIP93_MAIN_H_ */
---- /dev/null
-+++ b/drivers/crypto/mtk-eip93/eip93-regs.h
-@@ -0,0 +1,382 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2019 - 2021
-+ *
-+ * Richard van Schagen <vschagen@icloud.com>
-+ */
-+#ifndef REG_EIP93_H
-+#define REG_EIP93_H
-+
-+#define EIP93_REG_WIDTH 4
-+/*-----------------------------------------------------------------------------
-+ * Register Map
-+ */
-+#define DESP_BASE 0x0000000
-+#define EIP93_REG_PE_CTRL_STAT ((DESP_BASE)+(0x00 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_SOURCE_ADDR ((DESP_BASE)+(0x01 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_DEST_ADDR ((DESP_BASE)+(0x02 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_SA_ADDR ((DESP_BASE)+(0x03 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_ADDR ((DESP_BASE)+(0x04 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_USER_ID ((DESP_BASE)+(0x06 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_LENGTH ((DESP_BASE)+(0x07 * EIP93_REG_WIDTH))
-+
-+//PACKET ENGINE RING configuration registers
-+#define PE_RNG_BASE 0x0000080
-+
-+#define EIP93_REG_PE_CDR_BASE ((PE_RNG_BASE)+(0x00 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_RDR_BASE ((PE_RNG_BASE)+(0x01 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_RING_CONFIG ((PE_RNG_BASE)+(0x02 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_RING_THRESH ((PE_RNG_BASE)+(0x03 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_CD_COUNT ((PE_RNG_BASE)+(0x04 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_RD_COUNT ((PE_RNG_BASE)+(0x05 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_RING_RW_PNTR ((PE_RNG_BASE)+(0x06 * EIP93_REG_WIDTH))
-+
-+//PACKET ENGINE configuration registers
-+#define PE_CFG_BASE 0x0000100
-+#define EIP93_REG_PE_CONFIG ((PE_CFG_BASE)+(0x00 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_STATUS ((PE_CFG_BASE)+(0x01 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_BUF_THRESH ((PE_CFG_BASE)+(0x03 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_INBUF_COUNT ((PE_CFG_BASE)+(0x04 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_OUTBUF_COUNT ((PE_CFG_BASE)+(0x05 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_BUF_RW_PNTR ((PE_CFG_BASE)+(0x06 * EIP93_REG_WIDTH))
-+
-+//PACKET ENGINE endian config
-+#define EN_CFG_BASE 0x00001CC
-+#define EIP93_REG_PE_ENDIAN_CONFIG ((EN_CFG_BASE)+(0x00 * EIP93_REG_WIDTH))
-+
-+//EIP93 CLOCK control registers
-+#define CLOCK_BASE 0x01E8
-+#define EIP93_REG_PE_CLOCK_CTRL ((CLOCK_BASE)+(0x00 * EIP93_REG_WIDTH))
-+
-+//EIP93 Device Option and Revision Register
-+#define REV_BASE 0x01F4
-+#define EIP93_REG_PE_OPTION_1 ((REV_BASE)+(0x00 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_OPTION_0 ((REV_BASE)+(0x01 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PE_REVISION ((REV_BASE)+(0x02 * EIP93_REG_WIDTH))
-+
-+//EIP93 Interrupt Control Register
-+#define INT_BASE 0x0200
-+#define EIP93_REG_INT_UNMASK_STAT ((INT_BASE)+(0x00 * EIP93_REG_WIDTH))
-+#define EIP93_REG_INT_MASK_STAT ((INT_BASE)+(0x01 * EIP93_REG_WIDTH))
-+#define EIP93_REG_INT_CLR ((INT_BASE)+(0x01 * EIP93_REG_WIDTH))
-+#define EIP93_REG_INT_MASK ((INT_BASE)+(0x02 * EIP93_REG_WIDTH))
-+#define EIP93_REG_INT_CFG ((INT_BASE)+(0x03 * EIP93_REG_WIDTH))
-+#define EIP93_REG_MASK_ENABLE ((INT_BASE)+(0X04 * EIP93_REG_WIDTH))
-+#define EIP93_REG_MASK_DISABLE ((INT_BASE)+(0X05 * EIP93_REG_WIDTH))
-+
-+//EIP93 SA Record register
-+#define SA_BASE 0x0400
-+#define EIP93_REG_SA_CMD_0 ((SA_BASE)+(0x00 * EIP93_REG_WIDTH))
-+#define EIP93_REG_SA_CMD_1 ((SA_BASE)+(0x01 * EIP93_REG_WIDTH))
-+
-+//#define EIP93_REG_SA_READY ((SA_BASE)+(31 * EIP93_REG_WIDTH))
-+
-+//State save register
-+#define STATE_BASE 0x0500
-+#define EIP93_REG_STATE_IV_0 ((STATE_BASE)+(0x00 * EIP93_REG_WIDTH))
-+#define EIP93_REG_STATE_IV_1 ((STATE_BASE)+(0x01 * EIP93_REG_WIDTH))
-+
-+#define EIP93_PE_ARC4STATE_BASEADDR_REG 0x0700
-+
-+//RAM buffer start address
-+#define EIP93_INPUT_BUFFER 0x0800
-+#define EIP93_OUTPUT_BUFFER 0x0800
-+
-+//EIP93 PRNG Configuration Register
-+#define PRNG_BASE 0x0300
-+#define EIP93_REG_PRNG_STAT ((PRNG_BASE)+(0x00 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_CTRL ((PRNG_BASE)+(0x01 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_SEED_0 ((PRNG_BASE)+(0x02 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_SEED_1 ((PRNG_BASE)+(0x03 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_SEED_2 ((PRNG_BASE)+(0x04 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_SEED_3 ((PRNG_BASE)+(0x05 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_KEY_0 ((PRNG_BASE)+(0x06 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_KEY_1 ((PRNG_BASE)+(0x07 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_KEY_2 ((PRNG_BASE)+(0x08 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_KEY_3 ((PRNG_BASE)+(0x09 * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_RES_0 ((PRNG_BASE)+(0x0A * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_RES_1 ((PRNG_BASE)+(0x0B * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_RES_2 ((PRNG_BASE)+(0x0C * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_RES_3 ((PRNG_BASE)+(0x0D * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_LFSR_0 ((PRNG_BASE)+(0x0E * EIP93_REG_WIDTH))
-+#define EIP93_REG_PRNG_LFSR_1 ((PRNG_BASE)+(0x0F * EIP93_REG_WIDTH))
-+
-+/*-----------------------------------------------------------------------------
-+ * Constants & masks
-+ */
-+
-+#define EIP93_SUPPORTED_INTERRUPTS_MASK 0xffff7f00
-+#define EIP93_PRNG_DT_TEXT_LOWERHALF 0xDEAD
-+#define EIP93_PRNG_DT_TEXT_UPPERHALF 0xC0DE
-+#define EIP93_10BITS_MASK 0X3FF
-+#define EIP93_12BITS_MASK 0XFFF
-+#define EIP93_4BITS_MASK 0X04
-+#define EIP93_20BITS_MASK 0xFFFFF
-+
-+#define EIP93_MIN_DESC_DONE_COUNT 0
-+#define EIP93_MAX_DESC_DONE_COUNT 15
-+
-+#define EIP93_MIN_DESC_PENDING_COUNT 0
-+#define EIP93_MAX_DESC_PENDING_COUNT 1023
-+
-+#define EIP93_MIN_TIMEOUT_COUNT 0
-+#define EIP93_MAX_TIMEOUT_COUNT 15
-+
-+#define EIP93_MIN_PE_INPUT_THRESHOLD 1
-+#define EIP93_MAX_PE_INPUT_THRESHOLD 511
-+
-+#define EIP93_MIN_PE_OUTPUT_THRESHOLD 1
-+#define EIP93_MAX_PE_OUTPUT_THRESHOLD 432
-+
-+#define EIP93_MIN_PE_RING_SIZE 1
-+#define EIP93_MAX_PE_RING_SIZE 1023
-+
-+#define EIP93_MIN_PE_DESCRIPTOR_SIZE 7
-+#define EIP93_MAX_PE_DESCRIPTOR_SIZE 15
-+
-+//3DES keys,seed,known data and its result
-+#define EIP93_KEY_0 0x133b3454
-+#define EIP93_KEY_1 0x5e5b890b
-+#define EIP93_KEY_2 0x5eb30757
-+#define EIP93_KEY_3 0x93ab15f7
-+#define EIP93_SEED_0 0x62c4bf5e
-+#define EIP93_SEED_1 0x972667c8
-+#define EIP93_SEED_2 0x6345bf67
-+#define EIP93_SEED_3 0xcb3482bf
-+#define EIP93_LFSR_0 0xDEADC0DE
-+#define EIP93_LFSR_1 0xBEEFF00D
-+
-+/*-----------------------------------------------------------------------------
-+ * EIP93 device initialization specifics
-+ */
-+
-+/*----------------------------------------------------------------------------
-+ * Byte Order Reversal Mechanisms Supported in EIP93
-+ * EIP93_BO_REVERSE_HALF_WORD : reverse the byte order within a half-word
-+ * EIP93_BO_REVERSE_WORD : reverse the byte order within a word
-+ * EIP93_BO_REVERSE_DUAL_WORD : reverse the byte order within a dual-word
-+ * EIP93_BO_REVERSE_QUAD_WORD : reverse the byte order within a quad-word
-+ */
-+enum EIP93_Byte_Order_Value_t {
-+ EIP93_BO_REVERSE_HALF_WORD = 1,
-+ EIP93_BO_REVERSE_WORD = 2,
-+ EIP93_BO_REVERSE_DUAL_WORD = 4,
-+ EIP93_BO_REVERSE_QUAD_WORD = 8,
-+};
-+
-+/*----------------------------------------------------------------------------
-+ * Byte Order Reversal Mechanisms Supported in EIP93 for Target Data
-+ * EIP93_BO_REVERSE_HALF_WORD : reverse the byte order within a half-word
-+ * EIP93_BO_REVERSE_WORD : reverse the byte order within a word
-+ */
-+enum EIP93_Byte_Order_Value_TD_t {
-+ EIP93_BO_REVERSE_HALF_WORD_TD = 1,
-+ EIP93_BO_REVERSE_WORD_TD = 2,
-+};
-+
-+// BYTE_ORDER_CFG register values
-+#define EIP93_BYTE_ORDER_PD EIP93_BO_REVERSE_WORD
-+#define EIP93_BYTE_ORDER_SA EIP93_BO_REVERSE_WORD
-+#define EIP93_BYTE_ORDER_DATA EIP93_BO_REVERSE_WORD
-+#define EIP93_BYTE_ORDER_TD EIP93_BO_REVERSE_WORD_TD
-+
-+// INT_CFG register values
-+#define EIP93_INT_HOST_OUTPUT_TYPE 0
-+#define EIP93_INT_PULSE_CLEAR 0
-+
-+/*
-+ * Interrupts of EIP93
-+ */
-+
-+enum EIP93_InterruptSource_t {
-+ EIP93_INT_PE_CDRTHRESH_REQ = BIT(0),
-+ EIP93_INT_PE_RDRTHRESH_REQ = BIT(1),
-+ EIP93_INT_PE_OPERATION_DONE = BIT(9),
-+ EIP93_INT_PE_INBUFTHRESH_REQ = BIT(10),
-+ EIP93_INT_PE_OUTBURTHRSH_REQ = BIT(11),
-+ EIP93_INT_PE_PRNG_IRQ = BIT(12),
-+ EIP93_INT_PE_ERR_REG = BIT(13),
-+ EIP93_INT_PE_RD_DONE_IRQ = BIT(16),
-+};
-+
-+union peConfig_w {
-+ u32 word;
-+ struct {
-+ u32 resetPE :1;
-+ u32 resetRing :1;
-+ u32 reserved :6;
-+ u32 peMode :2;
-+ u32 enCDRupdate :1;
-+ u32 reserved2 :5;
-+ u32 swapCDRD :1;
-+ u32 swapSA :1;
-+ u32 swapData :1;
-+ u32 reserved3 :13;
-+ } bits;
-+} __packed;
-+
-+union peEndianCfg_w {
-+ u32 word;
-+ struct {
-+ u32 masterByteSwap :8;
-+ u32 reserved :8;
-+ u32 targetByteSwap :8;
-+ u32 reserved2 :8;
-+ } bits;
-+} __packed;
-+
-+union peIntCfg_w {
-+ u32 word;
-+ struct {
-+ u32 PulseClear :1;
-+ u32 IntType :1;
-+ u32 reserved :30;
-+ } bits;
-+} __packed;
-+
-+union peClockCfg_w {
-+ u32 word;
-+ struct {
-+ u32 enPEclk :1;
-+ u32 enDESclk :1;
-+ u32 enAESclk :1;
-+ u32 reserved :1;
-+ u32 enHASHclk :1;
-+ u32 reserved2 :27;
-+ } bits;
-+} __packed;
-+
-+union peBufThresh_w {
-+ u32 word;
-+ struct {
-+ u32 inputBuffer :8;
-+ u32 reserved :8;
-+ u32 outputBuffer :8;
-+ u32 reserved2 :8;
-+ } bits;
-+} __packed;
-+
-+union peRingThresh_w {
-+ u32 word;
-+ struct {
-+ u32 CDRThresh :10;
-+ u32 reserved :6;
-+ u32 RDRThresh :10;
-+ u32 RDTimeout :4;
-+ u32 reserved2 :1;
-+ u32 enTimeout :1;
-+ } bits;
-+} __packed;
-+
-+union peRingCfg_w {
-+ u32 word;
-+ struct {
-+ u32 ringSize :10;
-+ u32 reserved :6;
-+ u32 ringOffset :8;
-+ u32 reserved2 :8;
-+ } bits;
-+} __packed;
-+
-+union saCmd0 {
-+ u32 word;
-+ struct {
-+ u32 opCode :3;
-+ u32 direction :1;
-+ u32 opGroup :2;
-+ u32 padType :2;
-+ u32 cipher :4;
-+ u32 hash :4;
-+ u32 reserved2 :1;
-+ u32 scPad :1;
-+ u32 extPad :1;
-+ u32 hdrProc :1;
-+ u32 digestLength :4;
-+ u32 ivSource :2;
-+ u32 hashSource :2;
-+ u32 saveIv :1;
-+ u32 saveHash :1;
-+ u32 reserved1 :2;
-+ } bits;
-+} __packed;
-+
-+union saCmd1 {
-+ u32 word;
-+ struct {
-+ u32 copyDigest :1;
-+ u32 copyHeader :1;
-+ u32 copyPayload :1;
-+ u32 copyPad :1;
-+ u32 reserved4 :4;
-+ u32 cipherMode :2;
-+ u32 reserved3 :1;
-+ u32 sslMac :1;
-+ u32 hmac :1;
-+ u32 byteOffset :1;
-+ u32 reserved2 :2;
-+ u32 hashCryptOffset :8;
-+ u32 aesKeyLen :3;
-+ u32 reserved1 :1;
-+ u32 aesDecKey :1;
-+ u32 seqNumCheck :1;
-+ u32 reserved0 :2;
-+ } bits;
-+} __packed;
-+
-+struct saRecord_s {
-+ union saCmd0 saCmd0;
-+ union saCmd1 saCmd1;
-+ u32 saKey[8];
-+ u32 saIDigest[8];
-+ u32 saODigest[8];
-+ u32 saSpi;
-+ u32 saSeqNum[2];
-+ u32 saSeqNumMask[2];
-+ u32 saNonce;
-+} __packed;
-+
-+struct saState_s {
-+ u32 stateIv[4];
-+ u32 stateByteCnt[2];
-+ u32 stateIDigest[8];
-+} __packed;
-+
-+union peCrtlStat_w {
-+ u32 word;
-+ struct {
-+ u32 hostReady :1;
-+ u32 peReady :1;
-+ u32 reserved :1;
-+ u32 initArc4 :1;
-+ u32 hashFinal :1;
-+ u32 haltMode :1;
-+ u32 prngMode :2;
-+ u32 padValue :8;
-+ u32 errStatus :8;
-+ u32 padCrtlStat :8;
-+ } bits;
-+} __packed;
-+
-+union peLength_w {
-+ u32 word;
-+ struct {
-+ u32 length :20;
-+ u32 reserved :2;
-+ u32 hostReady :1;
-+ u32 peReady :1;
-+ u32 byPass :8;
-+ } bits;
-+} __packed;
-+
-+struct eip93_descriptor_s {
-+ union peCrtlStat_w peCrtlStat;
-+ u32 srcAddr;
-+ u32 dstAddr;
-+ u32 saAddr;
-+ u32 stateAddr;
-+ u32 arc4Addr;
-+ u32 userId;
-+ union peLength_w peLength;
-+} __packed;
-+
-+#endif
---- a/drivers/crypto/Kconfig
-+++ b/drivers/crypto/Kconfig
-@@ -824,4 +824,6 @@ config CRYPTO_DEV_SA2UL
- source "drivers/crypto/keembay/Kconfig"
- source "drivers/crypto/aspeed/Kconfig"
-
-+source "drivers/crypto/mtk-eip93/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-$(CONFIG_CRYPTO_DEV_EIP93) += mtk-eip93/
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
-@@ -563,8 +563,28 @@ static int __init bootcmdline_scan_chose
+@@ -564,8 +564,28 @@ static int __init bootcmdline_scan_chose
#endif /* CONFIG_OF_EARLY_FLATTREE */
bool dt_bootargs = false;
/*
-@@ -578,6 +598,14 @@ static void __init bootcmdline_init(void
+@@ -579,6 +599,14 @@ static void __init bootcmdline_init(void
}
/*
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
-@@ -705,7 +705,6 @@ static void __init arch_mem_init(char **
+@@ -706,7 +706,6 @@ static void __init arch_mem_init(char **
mips_reserve_vmcore();
mips_parse_crashkernel();
/*
* In order to reduce the possibility of kernel panic when failed to
-@@ -841,6 +840,7 @@ void __init setup_arch(char **cmdline_p)
+@@ -842,6 +841,7 @@ void __init setup_arch(char **cmdline_p)
cpu_cache_init();
paging_init();
+++ /dev/null
-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_MQ_PCI=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLK_MTMIPS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=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_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_DTB_RT2880_EVAL is not set
-CONFIG_DTB_RT_NONE=y
-CONFIG_DTC=y
-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_GCC11_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_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_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_RALINK=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_IP17XX_PHY=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=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_SYSCON=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_CMDLINE_BUILTIN_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-CONFIG_MIPS_L1_CACHE_SHIFT=4
-CONFIG_MIPS_L1_CACHE_SHIFT_4=y
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-# 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_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
-CONFIG_MTD_SPLIT_LZMA_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_MTD_SPLIT_WRGG_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_MDIO=y
-CONFIG_NET_RALINK_MDIO_RT2880=y
-CONFIG_NET_RALINK_RT2880=y
-CONFIG_NET_RALINK_SOC=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_VENDOR_RALINK=y
-CONFIG_NLS=m
-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_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-# CONFIG_PHY_MT7621_PCI is not set
-# CONFIG_PHY_RALINK_USB is not set
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_RALINK=y
-CONFIG_PINCTRL_RT2880=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RALINK=y
-CONFIG_RALINK_WDT=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_SERIAL_8250_RT288X=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_SOC_MT7620 is not set
-# CONFIG_SOC_MT7621 is not set
-CONFIG_SOC_RT288X=y
-# CONFIG_SOC_RT305X is not set
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_MT7621 is not set
-CONFIG_SPI_RT2880=y
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=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_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-CONFIG_USB=m
-CONFIG_USB_COMMON=m
-CONFIG_USB_EHCI_HCD=m
-CONFIG_USB_EHCI_HCD_PLATFORM=m
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_OHCI_HCD_PLATFORM=m
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_ZBOOT_LOAD_ADDRESS=0x0
+++ /dev/null
-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_CEVT_SYSTICK_QUIRK=y
-CONFIG_CLKEVT_RT3352=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLK_MTMIPS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=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_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_DEBUG_PINCTRL=y
-CONFIG_DMA_NONCOHERENT=y
-# CONFIG_DTB_RT305X_EVAL is not set
-CONFIG_DTB_RT_NONE=y
-CONFIG_DTC=y
-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_GCC11_NO_ARRAY_BOUNDS=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_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_RALINK=y
-CONFIG_GPIO_WATCHDOG=y
-# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
-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_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=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_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_BUILTIN_EXTEND is not set
-# 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_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_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
-CONFIG_MTD_SPLIT_JIMAGE_FW=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_ESW_RT3050=y
-CONFIG_NET_RALINK_RT3050=y
-CONFIG_NET_RALINK_SOC=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_VENDOR_RALINK=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_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-# CONFIG_PHY_MT7621_PCI is not set
-CONFIG_PHY_RALINK_USB=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_RALINK=y
-CONFIG_PINCTRL_RT305X=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RALINK=y
-# CONFIG_RALINK_ILL_ACC is not set
-CONFIG_RALINK_WDT=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_SERIAL_8250_RT288X=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_SOC_MT7620 is not set
-# CONFIG_SOC_MT7621 is not set
-# CONFIG_SOC_RT288X is not set
-CONFIG_SOC_RT305X=y
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_MT7621 is not set
-CONFIG_SPI_RT2880=y
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=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_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=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_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_ZBOOT_LOAD_ADDRESS=0x0
+++ /dev/null
-CONFIG_AR8216_PHY=y
-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_MQ_PCI=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLK_MTMIPS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=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_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_DEBUG_PINCTRL=y
-CONFIG_DMA_NONCOHERENT=y
-# CONFIG_DTB_RT3883_EVAL is not set
-CONFIG_DTB_RT_NONE=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_ETHERNET_PACKET_MANGLE=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_GCC11_NO_ARRAY_BOUNDS=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_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_RALINK=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_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=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_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_BUILTIN_EXTEND is not set
-# 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_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_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_MDIO=y
-CONFIG_NET_RALINK_MDIO_RT2880=y
-CONFIG_NET_RALINK_RT3883=y
-CONFIG_NET_RALINK_SOC=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_VENDOR_RALINK=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_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-# CONFIG_PHY_MT7621_PCI is not set
-CONFIG_PHY_RALINK_USB=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_RALINK=y
-CONFIG_PINCTRL_RT3883=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RALINK=y
-CONFIG_RALINK_WDT=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RTL8366_SMI=y
-CONFIG_RTL8367B_PHY=y
-CONFIG_RTL8367_PHY=y
-CONFIG_SERIAL_8250_RT288X=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_SOC_MT7620 is not set
-# CONFIG_SOC_MT7621 is not set
-# CONFIG_SOC_RT288X is not set
-# CONFIG_SOC_RT305X is not set
-CONFIG_SOC_RT3883=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_MT7621 is not set
-CONFIG_SPI_RT2880=y
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=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_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_ZBOOT_LOAD_ADDRESS=0x0
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)
{
rtl83xx_vlan_setup(priv);
rtl83xx_setup_bpdu_traps(priv);
+ rtl83xx_setup_lldp_traps(priv);
ds->configure_vlan_while_not_filtering = true;
sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1),
RTL838X_RMA_PTP_CTRL + ((port >> 4) << 2));
break;
- case LLTP:
+ case LLDP:
sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1),
- RTL838X_RMA_LLTP_CTRL + ((port >> 4) << 2));
+ RTL838X_RMA_LLDP_CTRL + ((port >> 4) << 2));
break;
default:
break;
PTP,
PTP_UDP,
PTP_ETH2,
- LLTP,
+ LLDP,
EAPOL,
GRATARP,
} rma_ctrl_t;
#define RTL930X_RMA_PTP_CTRL (0x9E88)
#define RTL931X_RMA_PTP_CTRL (0x8834)
-#define RTL838X_RMA_LLTP_CTRL (0x4340)
-#define RTL839X_RMA_LLTP_CTRL (0x124C)
-#define RTL930X_RMA_LLTP_CTRL (0x9EFC)
-#define RTL931X_RMA_LLTP_CTRL (0x8918)
+#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)
sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1),
RTL839X_RMA_PTP_CTRL + ((port >> 4) << 2));
break;
- case LLTP:
+ case LLDP:
sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1),
- RTL839X_RMA_LLTP_CTRL + ((port >> 4) << 2));
+ RTL839X_RMA_LLDP_CTRL + ((port >> 4) << 2));
break;
default:
break;
case PTP_ETH2:
sw_w32_mask(3, value, RTL931X_RMA_PTP_CTRL + (port << 2));
break;
- case LLTP:
- sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_LLTP_CTRL + ((port / 10) << 2));
+ 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));
int err;
struct rtl838x_eth_priv *priv = bus->priv;
- if (mii_id >= 48 && mii_id <= 49 && priv->id == 0x8393)
+ if (priv->phy_is_internal[mii_id])
return rtl839x_read_sds_phy(mii_id, regnum);
if (regnum & (MII_ADDR_C45 | MII_ADDR_C22_MMD)) {
struct rtl838x_eth_priv *priv = bus->priv;
int err;
- if (mii_id >= 48 && mii_id <= 49 && priv->id == 0x8393)
+ 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)) {
/* 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
/* Read internal PHY ID */
phy_write_paged(phydev, 31, 27, 0x0002);
val = phy_read_paged(phydev, 31, 28);
- if (val != 0x6276) {
+ if (val != RTL821X_CHIP_ID) {
phydev_err(phydev, "Expected external RTL8218B, found PHY-ID %x\n", val);
return -1;
}
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 != 0x6276) {
+ if (val != RTL821X_CHIP_ID) {
phydev_err(phydev, "Expected external RTL8214FC, found PHY-ID %x\n", val);
return -1;
}
FEATURES:=ext4 audio usb usbgadget display gpio fpu pci pcie rootfs-part boot-part squashfs
SUBTARGETS:=armv8
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware image for Rockchip SoC devices.
friendlyarm,nanopi-r5s)
ucidef_set_interfaces_lan_wan 'eth1 eth2' 'eth0'
;;
+ sinovoip,rk3568-bpi-r2pro)
+ ucidef_set_interfaces_lan_wan 'lan0 lan1 lan2 lan3' 'eth0'
+ ;;
*)
ucidef_set_interface_lan 'eth0'
;;
;;
friendlyarm,nanopi-r2c-plus|\
friendlyarm,nanopi-r4s|\
- friendlyarm,nanopi-r5s)
+ friendlyarm,nanopi-r5s|\
+ sinovoip,rk3568-bpi-r2pro)
wan_mac=$(macaddr_generate_from_mmc_cid mmcblk1)
lan_mac=$(macaddr_add "$wan_mac" 1)
;;
set_interface_core 20 "eth1"
;;
friendlyarm,nanopi-r5c|\
-radxa,e25)
+radxa,e25|\
+sinovoip,rk3568-bpi-r2pro)
set_interface_core 2 "eth0"
set_interface_core 4 "eth1"
;;
+++ /dev/null
-CONFIG_64BIT=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_POSSIBLE=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=33
-CONFIG_ARCH_MMAP_RND_BITS_MIN=18
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_PROC_KCORE_TEXT=y
-CONFIG_ARCH_ROCKCHIP=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_ARC_EMAC_CORE=y
-CONFIG_ARM64=y
-CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=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_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
-CONFIG_ARM64_PTR_AUTH_KERNEL=y
-CONFIG_ARM64_RAS_EXTN=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_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_PCI=y
-CONFIG_ARM_MHU=y
-CONFIG_ARM_MHU_V2=y
-CONFIG_ARM_PSCI_CPUIDLE=y
-CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
-CONFIG_ARM_PSCI_FW=y
-# CONFIG_ARM_RK3399_DMC_DEVFREQ is not set
-CONFIG_ARM_SCMI_CPUFREQ=y
-CONFIG_ARM_SCMI_HAVE_SHMEM=y
-CONFIG_ARM_SCMI_HAVE_TRANSPORT=y
-CONFIG_ARM_SCMI_POWER_CONTROL=y
-CONFIG_ARM_SCMI_POWER_DOMAIN=y
-CONFIG_ARM_SCMI_PROTOCOL=y
-CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y
-CONFIG_ARM_SCMI_TRANSPORT_SMC=y
-CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE=y
-CONFIG_ARM_SCPI_CPUFREQ=y
-CONFIG_ARM_SCPI_POWER_DOMAIN=y
-CONFIG_ARM_SCPI_PROTOCOL=y
-CONFIG_ARM_SMMU=y
-CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y
-# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set
-CONFIG_ARM_SMMU_V3=y
-# CONFIG_ARM_SMMU_V3_SVA is not set
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_GPIO=y
-CONFIG_BACKLIGHT_PWM=y
-CONFIG_BLK_DEV_BSG=y
-CONFIG_BLK_DEV_BSGLIB=y
-CONFIG_BLK_DEV_BSG_COMMON=y
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_BLK_DEV_INTEGRITY=y
-CONFIG_BLK_DEV_INTEGRITY_T10=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NVME=y
-CONFIG_BLK_DEV_PCIESSD_MTIP32XX=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_PM=y
-CONFIG_BRCMSTB_GISB_ARB=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=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_CHARGER_GPIO=y
-# CONFIG_CHARGER_RK817 is not set
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLK_PX30=y
-CONFIG_CLK_RK3308=y
-CONFIG_CLK_RK3328=y
-CONFIG_CLK_RK3368=y
-CONFIG_CLK_RK3399=y
-CONFIG_CLK_RK3568=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_RK808=y
-CONFIG_COMMON_CLK_ROCKCHIP=y
-CONFIG_COMMON_CLK_SCMI=y
-CONFIG_COMMON_CLK_SCPI=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_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_CONSERVATIVE is not set
-# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
-CONFIG_CPU_ISOLATION=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CRASH_CORE=y
-CONFIG_CRASH_DUMP=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CRC64=y
-CONFIG_CRC64_ROCKSOFT=y
-CONFIG_CRC_T10DIF=y
-CONFIG_CROSS_MEMORY_ATTACH=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_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_DEV_ROCKCHIP is not set
-CONFIG_CRYPTO_GHASH_ARM64_CE=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_POLYVAL=y
-CONFIG_CRYPTO_POLYVAL_ARM64_CE=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_SM3=y
-CONFIG_CRYPTO_SM3_NEON=y
-CONFIG_CRYPTO_SM4=y
-CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y
-CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_DEVFREQ_GOV_PASSIVE is not set
-CONFIG_DEVFREQ_GOV_PERFORMANCE=y
-CONFIG_DEVFREQ_GOV_POWERSAVE=y
-CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
-CONFIG_DEVFREQ_GOV_USERSPACE=y
-# CONFIG_DEVFREQ_THERMAL is not set
-CONFIG_DEVMEM=y
-# CONFIG_DEVPORT is not set
-CONFIG_DMADEVICES=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_DT_IDLE_GENPD=y
-CONFIG_DT_IDLE_STATES=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_DWMAC_DWC_QOS_ETH=y
-CONFIG_DWMAC_GENERIC=y
-CONFIG_DWMAC_ROCKCHIP=y
-CONFIG_DW_WATCHDOG=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_AT24=y
-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
-CONFIG_FHANDLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-# CONFIG_FORTIFY_SOURCE is not set
-CONFIG_FRAME_POINTER=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_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=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_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IOREMAP=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_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_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_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_DWAPB=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_GPIO_ROCKCHIP=y
-CONFIG_GPIO_SYSCON=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HID=y
-CONFIG_HID_GENERIC=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HOTPLUG_PCI=y
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_PCIE is not set
-# CONFIG_HOTPLUG_PCI_SHPC is not set
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_HWMON=y
-CONFIG_HWSPINLOCK=y
-CONFIG_HW_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_RK3X=y
-CONFIG_IIO=y
-# CONFIG_IIO_SCMI is not set
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_INDIRECT_PIO=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_FF_MEMLESS=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INPUT_LEDS=y
-CONFIG_INPUT_MATRIXKMAP=y
-CONFIG_INPUT_RK805_PWRKEY=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_IO_STRICT_DEVMEM is not set
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MSI_IOMMU=y
-CONFIG_IRQ_TIME_ACCOUNTING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JUMP_LABEL=y
-CONFIG_KALLSYMS=y
-CONFIG_KCMP=y
-CONFIG_KEXEC_CORE=y
-CONFIG_KEXEC_FILE=y
-CONFIG_KSM=y
-# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_PWM=y
-CONFIG_LEDS_SYSCON=y
-CONFIG_LEDS_TRIGGER_CPU=y
-CONFIG_LEDS_TRIGGER_PANIC=y
-CONFIG_LIBCRC32C=y
-CONFIG_LIBFDT=y
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LOG_BUF_SHIFT=19
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MAGIC_SYSRQ_SERIAL=y
-CONFIG_MAILBOX=y
-# CONFIG_MAILBOX_TEST is not set
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_BUS_MUX=y
-CONFIG_MDIO_BUS_MUX_GPIO=y
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MFD_CORE=y
-# CONFIG_MFD_KHADAS_MCU is not set
-CONFIG_MFD_RK808=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=32
-CONFIG_MMC_CQHCI=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_ROCKCHIP=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_OF_ARASAN=y
-CONFIG_MMC_SDHCI_OF_DWCMSHC=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MOTORCOMM_PHY=y
-CONFIG_MQ_IOSCHED_DEADLINE=y
-# CONFIG_MTD_CFI is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NLS=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NOP_USB_XCEIV=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=256
-CONFIG_NVMEM=y
-CONFIG_NVMEM_ROCKCHIP_EFUSE=y
-# CONFIG_NVMEM_ROCKCHIP_OTP is not set
-CONFIG_NVMEM_SYSFS=y
-CONFIG_NVME_CORE=y
-# CONFIG_NVME_HWMON is not set
-# CONFIG_NVME_MULTIPATH is not set
-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_IOMMU=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_OVERLAY=y
-CONFIG_OF_RESOLVE=y
-# CONFIG_OVERLAY_FS_XINO_AUTO is not set
-CONFIG_PADATA=y
-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_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_PME=y
-CONFIG_PCIE_ROCKCHIP=y
-CONFIG_PCIE_ROCKCHIP_DW_HOST=y
-CONFIG_PCIE_ROCKCHIP_HOST=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCI_STUB=y
-CONFIG_PCS_XPCS=y
-CONFIG_PGTABLE_LEVELS=4
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PHY_ROCKCHIP_DP=y
-# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set
-CONFIG_PHY_ROCKCHIP_EMMC=y
-# CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY is not set
-# CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set
-# CONFIG_PHY_ROCKCHIP_INNO_HDMI is not set
-CONFIG_PHY_ROCKCHIP_INNO_USB2=y
-CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y
-CONFIG_PHY_ROCKCHIP_PCIE=y
-CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
-CONFIG_PHY_ROCKCHIP_TYPEC=y
-CONFIG_PHY_ROCKCHIP_USB=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_RK805=y
-CONFIG_PINCTRL_ROCKCHIP=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PL330_DMA=y
-CONFIG_PLATFORM_MHU=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_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_POWER_SUPPLY_HWMON=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 is not set
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_PROC_VMCORE=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_ROCKCHIP=y
-CONFIG_PWM_SYSFS=y
-# CONFIG_QFMT_V2 is not set
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_QUOTA=y
-CONFIG_QUOTACTL=y
-CONFIG_RAID_ATTRS=y
-CONFIG_RANDOMIZE_BASE=y
-CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-# CONFIG_RAVE_SP_CORE is not set
-CONFIG_RCU_TRACE=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_ARM_SCMI=y
-CONFIG_REGULATOR_FAN53555=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_GPIO=y
-CONFIG_REGULATOR_PWM=y
-CONFIG_REGULATOR_RK808=y
-CONFIG_RELOCATABLE=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_SCMI=y
-CONFIG_RFS_ACCEL=y
-CONFIG_ROCKCHIP_GRF=y
-CONFIG_ROCKCHIP_IODOMAIN=y
-CONFIG_ROCKCHIP_IOMMU=y
-CONFIG_ROCKCHIP_MBOX=y
-CONFIG_ROCKCHIP_PHY=y
-CONFIG_ROCKCHIP_PM_DOMAINS=y
-# CONFIG_ROCKCHIP_SARADC is not set
-CONFIG_ROCKCHIP_THERMAL=y
-CONFIG_ROCKCHIP_TIMER=y
-CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
-CONFIG_RPS=y
-CONFIG_RSEQ=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_RK808=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_NVMEM=y
-# CONFIG_RUNTIME_TESTING_MENU is not set
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCHED_MC=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_SCSI_SAS_ATTRS=y
-CONFIG_SCSI_SAS_HOST_SMP=y
-CONFIG_SCSI_SAS_LIBSAS=y
-# CONFIG_SECURITY_DMESG_RESTRICT is not set
-CONFIG_SENSORS_ARM_SCMI=y
-CONFIG_SENSORS_ARM_SCPI=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_8250_EXAR=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_DEV_BUS=y
-CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIO=y
-CONFIG_SERIO_AMBAKMI=y
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=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_BITBANG=y
-CONFIG_SPI_DYNAMIC=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_ROCKCHIP=y
-CONFIG_SPI_ROCKCHIP_SFC=y
-CONFIG_SPI_SPIDEV=y
-# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set
-CONFIG_SQUASHFS_DECOMP_SINGLE=y
-# CONFIG_SQUASHFS_EMBEDDED is not set
-CONFIG_SQUASHFS_FILE_CACHE=y
-# CONFIG_SQUASHFS_FILE_DIRECT is not set
-CONFIG_SRAM=y
-CONFIG_SRCU=y
-CONFIG_STACKPROTECTOR=y
-CONFIG_STACKPROTECTOR_PER_TASK=y
-CONFIG_STACKPROTECTOR_STRONG=y
-CONFIG_STACKTRACE=y
-CONFIG_STMMAC_ETH=y
-CONFIG_STMMAC_PLATFORM=y
-CONFIG_STRICT_DEVMEM=y
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_SWAP is not set
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYNC_FILE=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYSFS_SYSCALL=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_EMULATION=y
-CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
-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_TRACE_CLOCK=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_TYPEC=y
-# CONFIG_TYPEC_ANX7411 is not set
-CONFIG_TYPEC_FUSB302=y
-# CONFIG_TYPEC_HD3SS3220 is not set
-# CONFIG_TYPEC_MUX_FSA4480 is not set
-# CONFIG_TYPEC_MUX_PI3USB30532 is not set
-# CONFIG_TYPEC_RT1719 is not set
-# CONFIG_TYPEC_STUSB160X is not set
-# CONFIG_TYPEC_TCPCI is not set
-CONFIG_TYPEC_TCPM=y
-# CONFIG_TYPEC_TPS6598X is not set
-# CONFIG_TYPEC_WUSB3801 is not set
-# CONFIG_UACCE is not set
-# CONFIG_UCLAMP_TASK is not set
-# CONFIG_UEVENT_HELPER is not set
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_UNMAP_KERNEL_AT_EL0=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_DWC3=y
-CONFIG_USB_DWC3_HOST=y
-CONFIG_USB_DWC3_OF_SIMPLE=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-CONFIG_USB_HID=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ULPI=y
-CONFIG_USB_ULPI_BUS=y
-CONFIG_USB_ULPI_VIEWPORT=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PLATFORM=y
-# CONFIG_VIRTIO_MENU is not set
-CONFIG_VMAP_STACK=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XARRAY_MULTI=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
--- /dev/null
+CONFIG_64BIT=y
+CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
+CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
+CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_FORCE_MAX_ORDER=10
+CONFIG_ARCH_HIBERNATION_POSSIBLE=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=33
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ARCH_SELECTS_KEXEC_FILE=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_ARC_EMAC_CORE=y
+CONFIG_ARM64=y
+CONFIG_ARM64_4K_PAGES=y
+CONFIG_ARM64_CNP=y
+CONFIG_ARM64_EPAN=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_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
+CONFIG_ARM64_PTR_AUTH_KERNEL=y
+CONFIG_ARM64_RAS_EXTN=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_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_PCI=y
+CONFIG_ARM_MHU=y
+CONFIG_ARM_MHU_V2=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
+CONFIG_ARM_PSCI_FW=y
+# CONFIG_ARM_RK3399_DMC_DEVFREQ is not set
+CONFIG_ARM_SCMI_CPUFREQ=y
+CONFIG_ARM_SCMI_HAVE_SHMEM=y
+CONFIG_ARM_SCMI_HAVE_TRANSPORT=y
+CONFIG_ARM_SCMI_POWER_CONTROL=y
+CONFIG_ARM_SCMI_POWER_DOMAIN=y
+CONFIG_ARM_SCMI_PROTOCOL=y
+# CONFIG_ARM_SCMI_RAW_MODE_SUPPORT is not set
+CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y
+CONFIG_ARM_SCMI_TRANSPORT_SMC=y
+CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE=y
+CONFIG_ARM_SCPI_CPUFREQ=y
+CONFIG_ARM_SCPI_POWER_DOMAIN=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_ARM_SMMU=y
+CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y
+# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set
+CONFIG_ARM_SMMU_V3=y
+# CONFIG_ARM_SMMU_V3_SVA is not set
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_BLK_DEV_BSG_COMMON=y
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLK_DEV_INTEGRITY_T10=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NVME=y
+CONFIG_BLK_DEV_PCIESSD_MTIP32XX=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BRCMSTB_GISB_ARB=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=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_CHARGER_GPIO=y
+# CONFIG_CHARGER_RK817 is not set
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLK_PX30=y
+CONFIG_CLK_RK3308=y
+CONFIG_CLK_RK3328=y
+CONFIG_CLK_RK3368=y
+CONFIG_CLK_RK3399=y
+CONFIG_CLK_RK3568=y
+CONFIG_CLK_RK3588=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_RK808=y
+CONFIG_COMMON_CLK_ROCKCHIP=y
+CONFIG_COMMON_CLK_SCMI=y
+CONFIG_COMMON_CLK_SCPI=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_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_CONSERVATIVE is not set
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
+CONFIG_CPU_ISOLATION=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CRASH_CORE=y
+CONFIG_CRASH_DUMP=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CRC64=y
+CONFIG_CRC64_ROCKSOFT=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CROSS_MEMORY_ATTACH=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_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_DEV_ROCKCHIP is not set
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_HW=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_POLYVAL=y
+CONFIG_CRYPTO_POLYVAL_ARM64_CE=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SM3=y
+CONFIG_CRYPTO_SM3_NEON=y
+CONFIG_CRYPTO_SM4=y
+CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y
+CONFIG_CRYPTO_SM4_ARM64_NEON_BLK=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEVFREQ_GOV_PASSIVE is not set
+CONFIG_DEVFREQ_GOV_PERFORMANCE=y
+CONFIG_DEVFREQ_GOV_POWERSAVE=y
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
+CONFIG_DEVFREQ_GOV_USERSPACE=y
+# CONFIG_DEVFREQ_THERMAL is not set
+CONFIG_DEVMEM=y
+# CONFIG_DEVPORT is not set
+CONFIG_DMADEVICES=y
+CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OPS=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DNOTIFY=y
+CONFIG_DTC=y
+CONFIG_DT_IDLE_GENPD=y
+CONFIG_DT_IDLE_STATES=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_DWMAC_DWC_QOS_ETH=y
+CONFIG_DWMAC_GENERIC=y
+CONFIG_DWMAC_ROCKCHIP=y
+CONFIG_DW_WATCHDOG=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_AT24=y
+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
+CONFIG_FHANDLE=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+# CONFIG_FORTIFY_SOURCE is not set
+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
+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_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=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_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOREMAP=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_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_MSI_IRQ=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_GENERIC_TIME_VSYSCALL=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_DWAPB=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_ROCKCHIP=y
+CONFIG_GPIO_SYSCON=y
+CONFIG_GRO_CELLS=y
+CONFIG_HARDIRQS_SW_RESEND=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_HOTPLUG_PCI=y
+# CONFIG_HOTPLUG_PCI_CPCI is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_HWMON=y
+CONFIG_HWSPINLOCK=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_ROCKCHIP=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_RK3X=y
+CONFIG_IIO=y
+# CONFIG_IIO_SCMI is not set
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_INDIRECT_PIO=y
+CONFIG_INPUT=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_INPUT_LEDS=y
+CONFIG_INPUT_MATRIXKMAP=y
+CONFIG_INPUT_RK805_PWRKEY=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 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_IO_STRICT_DEVMEM is not set
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MSI_IOMMU=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_KALLSYMS=y
+CONFIG_KCMP=y
+CONFIG_KEXEC_CORE=y
+CONFIG_KEXEC_FILE=y
+CONFIG_KSM=y
+# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_SYSCON=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_PANIC=y
+CONFIG_LIBCRC32C=y
+CONFIG_LIBFDT=y
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAGIC_SYSRQ_SERIAL=y
+CONFIG_MAILBOX=y
+# CONFIG_MAILBOX_TEST is not set
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_BUS_MUX=y
+CONFIG_MDIO_BUS_MUX_GPIO=y
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEDIATEK_GE_PHY=y
+# CONFIG_MEDIATEK_GE_SOC_PHY is not set
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_KHADAS_MCU is not set
+CONFIG_MFD_RK8XX=y
+CONFIG_MFD_RK8XX_I2C=y
+CONFIG_MFD_RK8XX_SPI=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_CQHCI=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_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+CONFIG_MMC_SDHCI_OF_DWCMSHC=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MOTORCOMM_PHY=y
+CONFIG_MQ_IOSCHED_DEADLINE=y
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_FLAGS=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MT7530=y
+CONFIG_NET_DSA_MT7530_MDIO=y
+CONFIG_NET_DSA_MT7530_MMIO=y
+CONFIG_NET_DSA_TAG_MTK=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_NLS_ISO8859_1=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+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_SYSFS=y
+CONFIG_NVME_CORE=y
+# CONFIG_NVME_HWMON is not set
+# CONFIG_NVME_MULTIPATH is not set
+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_IOMMU=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_OVERLAY=y
+CONFIG_OF_RESOLVE=y
+# CONFIG_OVERLAY_FS_XINO_AUTO is not set
+CONFIG_PADATA=y
+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_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_PME=y
+CONFIG_PCIE_ROCKCHIP=y
+CONFIG_PCIE_ROCKCHIP_DW_HOST=y
+CONFIG_PCIE_ROCKCHIP_HOST=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_STUB=y
+CONFIG_PCS_MTK_LYNXI=y
+CONFIG_PCS_XPCS=y
+CONFIG_PER_VMA_LOCK=y
+CONFIG_PGTABLE_LEVELS=4
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_PHY_ROCKCHIP_DP=y
+# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set
+CONFIG_PHY_ROCKCHIP_EMMC=y
+# CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY is not set
+# CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY is not set
+# CONFIG_PHY_ROCKCHIP_INNO_HDMI is not set
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y
+CONFIG_PHY_ROCKCHIP_PCIE=y
+CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
+CONFIG_PHY_ROCKCHIP_TYPEC=y
+CONFIG_PHY_ROCKCHIP_USB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RK805=y
+CONFIG_PINCTRL_ROCKCHIP=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PL330_DMA=y
+CONFIG_PLATFORM_MHU=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_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_SUPPLY_HWMON=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_PROC_PAGE_MONITOR=y
+CONFIG_PROC_VMCORE=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_PWM_SYSFS=y
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_QUOTA=y
+CONFIG_QUOTACTL=y
+CONFIG_RAID_ATTRS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+# CONFIG_RAVE_SP_CORE is not set
+CONFIG_RCU_TRACE=y
+CONFIG_REALTEK_PHY=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_ARM_SCMI=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_RK808=y
+CONFIG_RELOCATABLE=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_SCMI=y
+CONFIG_RFS_ACCEL=y
+CONFIG_ROCKCHIP_GRF=y
+CONFIG_ROCKCHIP_IODOMAIN=y
+CONFIG_ROCKCHIP_IOMMU=y
+CONFIG_ROCKCHIP_MBOX=y
+CONFIG_ROCKCHIP_PHY=y
+CONFIG_ROCKCHIP_PM_DOMAINS=y
+# CONFIG_ROCKCHIP_SARADC is not set
+CONFIG_ROCKCHIP_THERMAL=y
+CONFIG_ROCKCHIP_TIMER=y
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
+CONFIG_RPS=y
+CONFIG_RSEQ=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_HYM8563=y
+CONFIG_RTC_DRV_RK808=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_NVMEM=y
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCHED_MC=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_SCSI_SAS_ATTRS=y
+CONFIG_SCSI_SAS_HOST_SMP=y
+CONFIG_SCSI_SAS_LIBSAS=y
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+CONFIG_SENSORS_ARM_SCMI=y
+CONFIG_SENSORS_ARM_SCPI=y
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_8250_EXAR=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_PCILIB=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_DEV_BUS=y
+CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIO=y
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=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_BITBANG=y
+CONFIG_SPI_DYNAMIC=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_ROCKCHIP=y
+CONFIG_SPI_ROCKCHIP_SFC=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FILE_CACHE=y
+# CONFIG_SQUASHFS_FILE_DIRECT is not set
+CONFIG_SRAM=y
+CONFIG_STACKPROTECTOR=y
+CONFIG_STACKPROTECTOR_PER_TASK=y
+CONFIG_STACKPROTECTOR_STRONG=y
+CONFIG_STACKTRACE=y
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_STRICT_DEVMEM=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_SWAP is not set
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_FILE=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYSFS_SYSCALL=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_EMULATION=y
+CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
+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_TRACE_CLOCK=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_TYPEC=y
+# CONFIG_TYPEC_ANX7411 is not set
+CONFIG_TYPEC_FUSB302=y
+# CONFIG_TYPEC_HD3SS3220 is not set
+# CONFIG_TYPEC_MUX_FSA4480 is not set
+# CONFIG_TYPEC_MUX_GPIO_SBU is not set
+# CONFIG_TYPEC_MUX_NB7VPQ904M is not set
+# CONFIG_TYPEC_MUX_PI3USB30532 is not set
+# CONFIG_TYPEC_RT1719 is not set
+# CONFIG_TYPEC_STUSB160X is not set
+# CONFIG_TYPEC_TCPCI is not set
+CONFIG_TYPEC_TCPM=y
+# CONFIG_TYPEC_TPS6598X is not set
+# CONFIG_TYPEC_WUSB3801 is not set
+# CONFIG_UCLAMP_TASK is not set
+# CONFIG_UEVENT_HELPER is not set
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_UNMAP_KERNEL_AT_EL0=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_HOST=y
+CONFIG_USB_DWC3_OF_SIMPLE=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_PHY=y
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_BUS=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
+# CONFIG_VIRTIO_MENU is not set
+CONFIG_VMAP_STACK=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XARRAY_MULTI=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
endef
TARGET_DEVICES += radxa_rock-pi-e
+define Device/sinovoip_bpi-r2-pro
+ DEVICE_VENDOR := Sinovoip
+ DEVICE_MODEL := Bananapi-R2 Pro
+ SOC := rk3568
+ SUPPORTED_DEVICES := sinovoip,rk3568-bpi-r2pro
+ DEVICE_PACKAGES := kmod-ata-ahci-dwc
+endef
+TARGET_DEVICES += sinovoip_bpi-r2-pro
+
define Device/xunlong_orangepi-r1-plus
DEVICE_VENDOR := Xunlong
DEVICE_MODEL := Orange Pi R1 Plus
+++ /dev/null
-From b75a52b0dda353aeefb4830a320589a363f49579 Mon Sep 17 00:00:00 2001
-From: Shawn Lin <shawn.lin@rock-chips.com>
-Date: Thu, 2 Feb 2023 08:35:16 +0800
-Subject: [PATCH] mmc: sdhci-of-dwcmshc: Update DLL and pre-change delay for
- rockchip platform
-
-For Rockchip platform, DLL bypass bit and start bit need to be set if
-DLL is not locked. And adjust pre-change delay to 0x3 for better signal
-test result.
-
-Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
-Link: https://lore.kernel.org/r/1675298118-64243-2-git-send-email-shawn.lin@rock-chips.com
-Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
----
- drivers/mmc/host/sdhci-of-dwcmshc.c | 13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
---- a/drivers/mmc/host/sdhci-of-dwcmshc.c
-+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
-@@ -48,6 +48,7 @@
- #define DWCMSHC_EMMC_DLL_RXCLK_SRCSEL 29
- #define DWCMSHC_EMMC_DLL_START_POINT 16
- #define DWCMSHC_EMMC_DLL_INC 8
-+#define DWCMSHC_EMMC_DLL_BYPASS BIT(24)
- #define DWCMSHC_EMMC_DLL_DLYENA BIT(27)
- #define DLL_TXCLK_TAPNUM_DEFAULT 0x10
- #define DLL_TXCLK_TAPNUM_90_DEGREES 0xA
-@@ -60,6 +61,7 @@
- #define DLL_RXCLK_NO_INVERTER 1
- #define DLL_RXCLK_INVERTER 0
- #define DLL_CMDOUT_TAPNUM_90_DEGREES 0x8
-+#define DLL_RXCLK_ORI_GATE BIT(31)
- #define DLL_CMDOUT_TAPNUM_FROM_SW BIT(24)
- #define DLL_CMDOUT_SRC_CLK_NEG BIT(28)
- #define DLL_CMDOUT_EN_SRC_CLK_NEG BIT(29)
-@@ -234,9 +236,12 @@ static void dwcmshc_rk3568_set_clock(str
- sdhci_writel(host, extra, reg);
-
- if (clock <= 52000000) {
-- /* Disable DLL and reset both of sample and drive clock */
-- sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL);
-- sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_RXCLK);
-+ /*
-+ * Disable DLL and reset both of sample and drive clock.
-+ * The bypass bit and start bit need to be set if DLL is not locked.
-+ */
-+ sdhci_writel(host, DWCMSHC_EMMC_DLL_BYPASS | DWCMSHC_EMMC_DLL_START, DWCMSHC_EMMC_DLL_CTRL);
-+ sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK);
- sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
- sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT);
- /*
-@@ -279,7 +284,7 @@ static void dwcmshc_rk3568_set_clock(str
- }
-
- extra = 0x1 << 16 | /* tune clock stop en */
-- 0x2 << 17 | /* pre-change delay */
-+ 0x3 << 17 | /* pre-change delay */
- 0x3 << 19; /* post-change delay */
- sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL);
-
+++ /dev/null
-From 49502408007b77ff290ce62e6218cefaeedcb31a Mon Sep 17 00:00:00 2001
-From: Vasily Khoruzhick <anarsoul@gmail.com>
-Date: Thu, 9 Mar 2023 17:03:49 -0800
-Subject: [PATCH] mmc: sdhci-of-dwcmshc: properly determine max clock on
- Rockchip
-
-Currently .get_max_clock returns the current clock rate for cclk_emmc
-on rk35xx, thus max clock gets set to whatever bootloader set it to.
-
-In case of u-boot, it is intentionally reset to 50 MHz if it boots
-from eMMC, see mmc_deinit() in u-boot sources. As a result, HS200 and
-HS400 modes are never selected by Linux, because dwcmshc_rk35xx_postinit
-clears appropriate caps if host->mmc->f_max is < 52MHz
-
-cclk_emmc is not a fixed clock on rk35xx, so using
-sdhci_pltfm_clk_get_max_clock is not appropriate here.
-
-Implement rk35xx_get_max_clock that returns actual max clock for cclk_emmc.
-
-Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
-Acked-by: Adrian Hunter <adrian.hunter@intel.com>
-Link: https://lore.kernel.org/r/20230310010349.509132-1-anarsoul@gmail.com
-Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
----
- drivers/mmc/host/sdhci-of-dwcmshc.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
---- a/drivers/mmc/host/sdhci-of-dwcmshc.c
-+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
-@@ -126,6 +126,13 @@ static unsigned int dwcmshc_get_max_cloc
- return pltfm_host->clock;
- }
-
-+static unsigned int rk35xx_get_max_clock(struct sdhci_host *host)
-+{
-+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-+
-+ return clk_round_rate(pltfm_host->clk, ULONG_MAX);
-+}
-+
- static void dwcmshc_check_auto_cmd23(struct mmc_host *mmc,
- struct mmc_request *mrq)
- {
-@@ -343,7 +350,7 @@ static const struct sdhci_ops sdhci_dwcm
- .set_clock = dwcmshc_rk3568_set_clock,
- .set_bus_width = sdhci_set_bus_width,
- .set_uhs_signaling = dwcmshc_set_uhs_signaling,
-- .get_max_clock = sdhci_pltfm_clk_get_max_clock,
-+ .get_max_clock = rk35xx_get_max_clock,
- .reset = rk35xx_sdhci_reset,
- .adma_write_desc = dwcmshc_adma_write_desc,
- };
+++ /dev/null
-From 004589ff9df5b75672a78b6c3c4cba93202b14c9 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Sat, 25 Mar 2023 15:40:20 +0800
-Subject: [PATCH] arm64: dts: rockchip: Add FriendlyARM NanoPi R2C
-
-The NanoPi R2C is a minor variant of NanoPi R2S with the on-board NIC
-chip changed from rtl8211e to yt8521s, and otherwise identical to R2S.
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Link: https://lore.kernel.org/r/20230325074022.9818-3-cnsztl@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/Makefile | 1 +
- .../boot/dts/rockchip/rk3328-nanopi-r2c.dts | 40 +++++++++++++++++++
- 2 files changed, 41 insertions(+)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c.dts
-
---- a/arch/arm64/boot/dts/rockchip/Makefile
-+++ b/arch/arm64/boot/dts/rockchip/Makefile
-@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a9
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb
-+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c.dts
-@@ -0,0 +1,40 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright (c) 2021 FriendlyElec Computer Tech. Co., Ltd.
-+ * (http://www.friendlyarm.com)
-+ *
-+ * Copyright (c) 2021-2023 Tianling Shen <cnsztl@gmail.com>
-+ */
-+
-+/dts-v1/;
-+#include "rk3328-nanopi-r2s.dts"
-+
-+/ {
-+ model = "FriendlyElec NanoPi R2C";
-+ compatible = "friendlyarm,nanopi-r2c", "rockchip,rk3328";
-+};
-+
-+&gmac2io {
-+ phy-handle = <&yt8521s>;
-+ tx_delay = <0x22>;
-+ rx_delay = <0x12>;
-+
-+ mdio {
-+ /delete-node/ ethernet-phy@1;
-+
-+ yt8521s: ethernet-phy@3 {
-+ compatible = "ethernet-phy-ieee802.3-c22";
-+ reg = <3>;
-+
-+ motorcomm,clk-out-frequency-hz = <125000000>;
-+ motorcomm,keep-pll-enabled;
-+ motorcomm,auto-sleep-disabled;
-+
-+ pinctrl-0 = <ð_phy_reset_pin>;
-+ pinctrl-names = "default";
-+ reset-assert-us = <10000>;
-+ reset-deassert-us = <50000>;
-+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
+++ /dev/null
-From 51712e1d014aaaa4c6e1e7e84932d58b5c0f59ed Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Sat, 3 Dec 2022 15:41:49 +0800
-Subject: [PATCH] arm64: dts: rockchip: rk3328: Add Orange Pi R1 Plus
-
-Orange Pi R1 Plus is a Rockchip RK3328 based SBC by Xunlong.
-
-This device is similar to the NanoPi R2S, and has a 16MB
-SPI NOR (mx25l12805d). The reset button is changed to
-directly reset the power supply, another detail is that
-both network ports have independent MAC addresses.
-
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
-Link: https://lore.kernel.org/r/20221203074149.11543-3-amadeus@jmu.edu.cn
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/Makefile | 1 +
- .../dts/rockchip/rk3328-orangepi-r1-plus.dts | 373 ++++++++++++++++++
- 2 files changed, 374 insertions(+)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
-
---- a/arch/arm64/boot/dts/rockchip/Makefile
-+++ b/arch/arm64/boot/dts/rockchip/Makefile
-@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb
-+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
-@@ -0,0 +1,373 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+/*
-+ * Based on rk3328-nanopi-r2s.dts, which is:
-+ * Copyright (c) 2020 David Bauer <mail@david-bauer.net>
-+ */
-+
-+/dts-v1/;
-+
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/leds/common.h>
-+#include "rk3328.dtsi"
-+
-+/ {
-+ model = "Xunlong Orange Pi R1 Plus";
-+ compatible = "xunlong,orangepi-r1-plus", "rockchip,rk3328";
-+
-+ aliases {
-+ ethernet1 = &rtl8153;
-+ mmc0 = &sdmmc;
-+ };
-+
-+ chosen {
-+ stdout-path = "serial2:1500000n8";
-+ };
-+
-+ gmac_clk: gmac-clock {
-+ compatible = "fixed-clock";
-+ clock-frequency = <125000000>;
-+ clock-output-names = "gmac_clkin";
-+ #clock-cells = <0>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+ pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>;
-+ pinctrl-names = "default";
-+
-+ led-0 {
-+ function = LED_FUNCTION_LAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-1 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "heartbeat";
-+ };
-+
-+ led-2 {
-+ function = LED_FUNCTION_WAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+
-+ vcc_sd: sdmmc-regulator {
-+ compatible = "regulator-fixed";
-+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
-+ pinctrl-0 = <&sdmmc0m1_pin>;
-+ pinctrl-names = "default";
-+ regulator-name = "vcc_sd";
-+ regulator-boot-on;
-+ vin-supply = <&vcc_io>;
-+ };
-+
-+ vcc_sys: vcc-sys-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc_sys";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ };
-+
-+ vdd_5v_lan: vdd-5v-lan-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>;
-+ pinctrl-0 = <&lan_vdd_pin>;
-+ pinctrl-names = "default";
-+ regulator-name = "vdd_5v_lan";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ vin-supply = <&vcc_sys>;
-+ };
-+};
-+
-+&cpu0 {
-+ cpu-supply = <&vdd_arm>;
-+};
-+
-+&cpu1 {
-+ cpu-supply = <&vdd_arm>;
-+};
-+
-+&cpu2 {
-+ cpu-supply = <&vdd_arm>;
-+};
-+
-+&cpu3 {
-+ cpu-supply = <&vdd_arm>;
-+};
-+
-+&display_subsystem {
-+ status = "disabled";
-+};
-+
-+&gmac2io {
-+ assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>;
-+ assigned-clock-parents = <&gmac_clk>, <&gmac_clk>;
-+ clock_in_out = "input";
-+ phy-handle = <&rtl8211e>;
-+ phy-mode = "rgmii";
-+ phy-supply = <&vcc_io>;
-+ pinctrl-0 = <&rgmiim1_pins>;
-+ pinctrl-names = "default";
-+ snps,aal;
-+ rx_delay = <0x18>;
-+ tx_delay = <0x24>;
-+ status = "okay";
-+
-+ mdio {
-+ compatible = "snps,dwmac-mdio";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ rtl8211e: ethernet-phy@1 {
-+ reg = <1>;
-+ pinctrl-0 = <ð_phy_reset_pin>;
-+ pinctrl-names = "default";
-+ reset-assert-us = <10000>;
-+ reset-deassert-us = <50000>;
-+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
-+
-+&i2c1 {
-+ status = "okay";
-+
-+ rk805: pmic@18 {
-+ compatible = "rockchip,rk805";
-+ reg = <0x18>;
-+ interrupt-parent = <&gpio1>;
-+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
-+ #clock-cells = <1>;
-+ clock-output-names = "xin32k", "rk805-clkout2";
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ pinctrl-0 = <&pmic_int_l>;
-+ pinctrl-names = "default";
-+ rockchip,system-power-controller;
-+ wakeup-source;
-+
-+ vcc1-supply = <&vcc_sys>;
-+ vcc2-supply = <&vcc_sys>;
-+ vcc3-supply = <&vcc_sys>;
-+ vcc4-supply = <&vcc_sys>;
-+ vcc5-supply = <&vcc_io>;
-+ vcc6-supply = <&vcc_sys>;
-+
-+ regulators {
-+ vdd_log: DCDC_REG1 {
-+ regulator-name = "vdd_log";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <712500>;
-+ regulator-max-microvolt = <1450000>;
-+ regulator-ramp-delay = <12500>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <1000000>;
-+ };
-+ };
-+
-+ vdd_arm: DCDC_REG2 {
-+ regulator-name = "vdd_arm";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <712500>;
-+ regulator-max-microvolt = <1450000>;
-+ regulator-ramp-delay = <12500>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <950000>;
-+ };
-+ };
-+
-+ vcc_ddr: DCDC_REG3 {
-+ regulator-name = "vcc_ddr";
-+ regulator-always-on;
-+ regulator-boot-on;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ };
-+ };
-+
-+ vcc_io: DCDC_REG4 {
-+ regulator-name = "vcc_io";
-+ regulator-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_18: LDO_REG1 {
-+ regulator-name = "vcc_18";
-+ 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>;
-+ };
-+ };
-+
-+ vcc18_emmc: LDO_REG2 {
-+ regulator-name = "vcc18_emmc";
-+ 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>;
-+ };
-+ };
-+
-+ vdd_10: LDO_REG3 {
-+ regulator-name = "vdd_10";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1000000>;
-+ regulator-max-microvolt = <1000000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <1000000>;
-+ };
-+ };
-+ };
-+ };
-+};
-+
-+&io_domains {
-+ pmuio-supply = <&vcc_io>;
-+ vccio1-supply = <&vcc_io>;
-+ vccio2-supply = <&vcc18_emmc>;
-+ vccio3-supply = <&vcc_io>;
-+ vccio4-supply = <&vcc_io>;
-+ vccio5-supply = <&vcc_io>;
-+ vccio6-supply = <&vcc_io>;
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ gmac2io {
-+ eth_phy_reset_pin: eth-phy-reset-pin {
-+ rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>;
-+ };
-+ };
-+
-+ leds {
-+ lan_led_pin: lan-led-pin {
-+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ sys_led_pin: sys-led-pin {
-+ rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ wan_led_pin: wan-led-pin {
-+ rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+
-+ lan {
-+ lan_vdd_pin: lan-vdd-pin {
-+ rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+
-+ pmic {
-+ pmic_int_l: pmic-int-l {
-+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>;
-+ };
-+ };
-+};
-+
-+&pwm2 {
-+ status = "okay";
-+};
-+
-+&sdmmc {
-+ bus-width = <4>;
-+ cap-sd-highspeed;
-+ disable-wp;
-+ pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>;
-+ pinctrl-names = "default";
-+ vmmc-supply = <&vcc_sd>;
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ status = "okay";
-+
-+ flash@0 {
-+ compatible = "jedec,spi-nor";
-+ reg = <0>;
-+ spi-max-frequency = <50000000>;
-+ };
-+};
-+
-+&tsadc {
-+ rockchip,hw-tshut-mode = <0>;
-+ rockchip,hw-tshut-polarity = <0>;
-+ status = "okay";
-+};
-+
-+&u2phy {
-+ status = "okay";
-+};
-+
-+&u2phy_host {
-+ status = "okay";
-+};
-+
-+&u2phy_otg {
-+ status = "okay";
-+};
-+
-+&uart2 {
-+ status = "okay";
-+};
-+
-+&usb20_otg {
-+ dr_mode = "host";
-+ status = "okay";
-+};
-+
-+&usbdrd3 {
-+ dr_mode = "host";
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ /* Second port is for USB 3.0 */
-+ rtl8153: device@2 {
-+ compatible = "usbbda,8153";
-+ reg = <2>;
-+ };
-+};
-+
-+&usb_host0_ehci {
-+ status = "okay";
-+};
-+
-+&usb_host0_ohci {
-+ status = "okay";
-+};
+++ /dev/null
-From 387b3bbac5ea6a0a105d685237f033ffe0f184f1 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Sat, 25 Mar 2023 15:40:22 +0800
-Subject: [PATCH] arm64: dts: rockchip: Add Xunlong OrangePi R1 Plus LTS
-
-The OrangePi R1 Plus LTS is a minor variant of OrangePi R1 Plus with
-the on-board NIC chip changed from rtl8211e to yt8531c, and otherwise
-identical to OrangePi R1 Plus.
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Link: https://lore.kernel.org/r/20230325074022.9818-5-cnsztl@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/Makefile | 1 +
- .../rockchip/rk3328-orangepi-r1-plus-lts.dts | 40 +++++++++++++++++++
- 2 files changed, 41 insertions(+)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts
-
---- a/arch/arm64/boot/dts/rockchip/Makefile
-+++ b/arch/arm64/boot/dts/rockchip/Makefile
-@@ -13,6 +13,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-ev
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb
-+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts
-@@ -0,0 +1,40 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright (c) 2016 Xunlong Software. Co., Ltd.
-+ * (http://www.orangepi.org)
-+ *
-+ * Copyright (c) 2021-2023 Tianling Shen <cnsztl@gmail.com>
-+ */
-+
-+/dts-v1/;
-+#include "rk3328-orangepi-r1-plus.dts"
-+
-+/ {
-+ model = "Xunlong Orange Pi R1 Plus LTS";
-+ compatible = "xunlong,orangepi-r1-plus-lts", "rockchip,rk3328";
-+};
-+
-+&gmac2io {
-+ phy-handle = <&yt8531c>;
-+ tx_delay = <0x19>;
-+ rx_delay = <0x05>;
-+
-+ mdio {
-+ /delete-node/ ethernet-phy@1;
-+
-+ yt8531c: ethernet-phy@0 {
-+ compatible = "ethernet-phy-ieee802.3-c22";
-+ reg = <0>;
-+
-+ motorcomm,clk-out-frequency-hz = <125000000>;
-+ motorcomm,keep-pll-enabled;
-+ motorcomm,auto-sleep-disabled;
-+
-+ pinctrl-0 = <ð_phy_reset_pin>;
-+ pinctrl-names = "default";
-+ reset-assert-us = <15000>;
-+ reset-deassert-us = <50000>;
-+ reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
+++ /dev/null
-From c6629b9a6738a64507478527da6c7b83c10a6d2c Mon Sep 17 00:00:00 2001
-From: Vasily Khoruzhick <anarsoul@gmail.com>
-Date: Tue, 7 Mar 2023 22:32:40 -0800
-Subject: [PATCH] arm64: dts: rockchip: Add FriendlyElec Nanopi R5S
-
-FriendlyElec Nanopi R5S is an open-sourced mini IoT gateway device.
-
-Board Specifications
-- Rockchip RK3568
-- 2 or 4GB LPDDR4X
-- 8GB or 16GB eMMC, SD card slot
-- GbE LAN (Native)
-- 2x 2.5G LAN (PCIe)
-- M.2 Connector
-- HDMI 2.0, MIPI DSI/CSI
-- 2xUSB 3.0 Host
-- USB Type C PD, 5V/9V/12V
-- GPIO: 12-pin 0.5mm FPC connector
-
-Based on Tianling Shen's <cnsztl@gmail.com> work.
-
-Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
-Link: https://lore.kernel.org/r/20230308063240.107178-2-anarsoul@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/Makefile | 1 +
- .../boot/dts/rockchip/rk3568-nanopi-r5s.dts | 713 ++++++++++++++++++
- 2 files changed, 714 insertions(+)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-
---- a/arch/arm64/boot/dts/rockchip/Makefile
-+++ b/arch/arm64/boot/dts/rockchip/Makefile
-@@ -74,4 +74,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-ro
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
-+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-@@ -0,0 +1,713 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright (c) 2022 FriendlyElec Computer Tech. Co., Ltd.
-+ * (http://www.friendlyelec.com)
-+ *
-+ * Copyright (c) 2023 Tianling Shen <cnsztl@gmail.com>
-+ */
-+
-+/dts-v1/;
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/pinctrl/rockchip.h>
-+#include <dt-bindings/soc/rockchip,vop2.h>
-+#include "rk3568.dtsi"
-+
-+/ {
-+ model = "FriendlyElec NanoPi R5S";
-+ compatible = "friendlyarm,nanopi-r5s", "rockchip,rk3568";
-+
-+ aliases {
-+ ethernet0 = &gmac0;
-+ mmc0 = &sdmmc0;
-+ mmc1 = &sdhci;
-+ };
-+
-+ chosen: chosen {
-+ stdout-path = "serial2:1500000n8";
-+ };
-+
-+ hdmi-con {
-+ compatible = "hdmi-connector";
-+ type = "a";
-+
-+ port {
-+ hdmi_con_in: endpoint {
-+ remote-endpoint = <&hdmi_out_con>;
-+ };
-+ };
-+ };
-+
-+ gpio-leds {
-+ compatible = "gpio-leds";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&lan1_led_pin>, <&lan2_led_pin>, <&power_led_pin>, <&wan_led_pin>;
-+
-+ led-lan1 {
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_LAN;
-+ function-enumerator = <1>;
-+ gpios = <&gpio3 RK_PD6 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-lan2 {
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_LAN;
-+ function-enumerator = <2>;
-+ gpios = <&gpio3 RK_PD7 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ power_led: led-power {
-+ color = <LED_COLOR_ID_RED>;
-+ function = LED_FUNCTION_POWER;
-+ linux,default-trigger = "heartbeat";
-+ gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-wan {
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_WAN;
-+ gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+
-+ vdd_usbc: vdd-usbc-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vdd_usbc";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ };
-+
-+ 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 = <&vdd_usbc>;
-+ };
-+
-+ 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 = <&vdd_usbc>;
-+ };
-+
-+ vcc3v3_pcie: vcc3v3-pcie-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc3v3_pcie";
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ enable-active-high;
-+ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
-+ startup-delay-us = <200000>;
-+ vin-supply = <&vcc5v0_sys>;
-+ };
-+
-+ 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 = <&vdd_usbc>;
-+ };
-+
-+ vcc5v0_usb_host: vcc5v0-usb-host-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&vcc5v0_usb_host_en>;
-+ regulator-name = "vcc5v0_usb_host";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ vin-supply = <&vcc5v0_usb>;
-+ };
-+
-+ vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&vcc5v0_usb_otg_en>;
-+ regulator-name = "vcc5v0_usb_otg";
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ vin-supply = <&vcc5v0_usb>;
-+ };
-+
-+ pcie30_avdd0v9: pcie30-avdd0v9-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "pcie30_avdd0v9";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+ vin-supply = <&vcc3v3_sys>;
-+ };
-+
-+ pcie30_avdd1v8: pcie30-avdd1v8-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "pcie30_avdd1v8";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ vin-supply = <&vcc3v3_sys>;
-+ };
-+};
-+
-+&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>;
-+ assigned-clock-rates = <0>, <125000000>;
-+ clock_in_out = "output";
-+ phy-handle = <&rgmii_phy0>;
-+ phy-mode = "rgmii-id";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&gmac0_miim
-+ &gmac0_tx_bus2
-+ &gmac0_rx_bus2
-+ &gmac0_rgmii_clk
-+ &gmac0_rgmii_bus>;
-+ snps,reset-gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_LOW>;
-+ snps,reset-active-low;
-+ /* Reset time is 15ms, 50ms for rtl8211f */
-+ snps,reset-delays-us = <0 15000 50000>;
-+ tx_delay = <0x3c>;
-+ rx_delay = <0x2f>;
-+ 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-cells = <1>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pmic_int>;
-+ rockchip,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;
-+
-+ regulators {
-+ vdd_logic: DCDC_REG1 {
-+ regulator-name = "vdd_logic";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-init-microvolt = <900000>;
-+ 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-init-microvolt = <900000>;
-+ 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-init-microvolt = <900000>;
-+ 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 = <950000>;
-+ regulator-max-microvolt = <950000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vdda_0v9: LDO_REG2 {
-+ regulator-name = "vdda_0v9";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vdda0v9_pmu: LDO_REG3 {
-+ regulator-name = "vdda0v9_pmu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <900000>;
-+ };
-+ };
-+
-+ vccio_acodec: LDO_REG4 {
-+ regulator-name = "vccio_acodec";
-+ regulator-always-on;
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vccio_sd: LDO_REG5 {
-+ regulator-name = "vccio_sd";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <3300000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc3v3_pmu: LDO_REG6 {
-+ regulator-name = "vcc3v3_pmu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <3300000>;
-+ };
-+ };
-+
-+ vcca_1v8: LDO_REG7 {
-+ regulator-name = "vcca_1v8";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcca1v8_pmu: LDO_REG8 {
-+ regulator-name = "vcca1v8_pmu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <1800000>;
-+ };
-+ };
-+
-+ vcca1v8_image: LDO_REG9 {
-+ regulator-name = "vcca1v8_image";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc_3v3: SWITCH_REG1 {
-+ regulator-name = "vcc_3v3";
-+ regulator-always-on;
-+ regulator-boot-on;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc3v3_sd: SWITCH_REG2 {
-+ regulator-name = "vcc3v3_sd";
-+ regulator-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 = <&hym8563_int>;
-+ wakeup-source;
-+ };
-+};
-+
-+&i2s0_8ch {
-+ status = "okay";
-+};
-+
-+&i2s1_8ch {
-+ rockchip,trcm-sync-tx-only;
-+ status = "okay";
-+};
-+
-+&mdio0 {
-+ rgmii_phy0: ethernet-phy@1 {
-+ compatible = "ethernet-phy-ieee802.3-c22";
-+ reg = <1>;
-+ pinctrl-0 = <ð_phy0_reset_pin>;
-+ pinctrl-names = "default";
-+ reset-assert-us = <10000>;
-+ reset-deassert-us = <50000>;
-+ reset-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
-+ };
-+};
-+
-+&pcie2x1 {
-+ num-lanes = <1>;
-+ reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
-+ status = "okay";
-+};
-+
-+&pcie30phy {
-+ data-lanes = <1 2>;
-+ status = "okay";
-+};
-+
-+&pcie3x1 {
-+ num-lanes = <1>;
-+ reset-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
-+ vpcie3v3-supply = <&vcc3v3_pcie>;
-+ status = "okay";
-+};
-+
-+&pcie3x2 {
-+ num-lanes = <1>;
-+ num-ib-windows = <8>;
-+ num-ob-windows = <8>;
-+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
-+ vpcie3v3-supply = <&vcc3v3_pcie>;
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ gmac0 {
-+ eth_phy0_reset_pin: eth-phy0-reset-pin {
-+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>;
-+ };
-+ };
-+
-+ gpio-leds {
-+ lan1_led_pin: lan1-led-pin {
-+ rockchip,pins = <3 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ lan2_led_pin: lan2-led-pin {
-+ rockchip,pins = <3 RK_PD7 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ power_led_pin: power-led-pin {
-+ rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ wan_led_pin: wan-led-pin {
-+ rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+
-+ hym8563 {
-+ hym8563_int: hym8563-int {
-+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
-+ };
-+ };
-+
-+ pmic {
-+ pmic_int: pmic-int {
-+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
-+ };
-+ };
-+
-+ usb {
-+ vcc5v0_usb_host_en: vcc5v0-usb-host-en {
-+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ vcc5v0_usb_otg_en: vcc5v0-usb-otg-en {
-+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+};
-+
-+&pmu_io_domains {
-+ pmuio1-supply = <&vcc3v3_pmu>;
-+ pmuio2-supply = <&vcc3v3_pmu>;
-+ vccio1-supply = <&vccio_acodec>;
-+ 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>;
-+ max-frequency = <200000000>;
-+ non-removable;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
-+ status = "okay";
-+};
-+
-+&sdmmc0 {
-+ max-frequency = <150000000>;
-+ no-sdio;
-+ no-mmc;
-+ bus-width = <4>;
-+ cap-mmc-highspeed;
-+ cap-sd-highspeed;
-+ disable-wp;
-+ vmmc-supply = <&vcc3v3_sd>;
-+ vqmmc-supply = <&vccio_sd>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
-+ status = "okay";
-+};
-+
-+&tsadc {
-+ rockchip,hw-tshut-mode = <1>;
-+ rockchip,hw-tshut-polarity = <0>;
-+ status = "okay";
-+};
-+
-+&uart2 {
-+ status = "okay";
-+};
-+
-+&usb_host0_ehci {
-+ status = "okay";
-+};
-+
-+&usb_host0_ohci {
-+ status = "okay";
-+};
-+
-+&usb_host0_xhci {
-+ extcon = <&usb2phy0>;
-+ 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_usb_host>;
-+ status = "okay";
-+};
-+
-+&usb2phy0_otg {
-+ status = "okay";
-+};
-+
-+&usb2phy1 {
-+ status = "okay";
-+};
-+
-+&usb2phy1_host {
-+ phy-supply = <&vcc5v0_usb_otg>;
-+ status = "okay";
-+};
-+
-+&usb2phy1_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
-From c8ec73b05a95d9f0969ae0f28dd8799a54fcdfc7 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Sat, 18 Mar 2023 16:37:41 +0800
-Subject: [PATCH] arm64: dts: rockchip: create common dtsi for NanoPi R5 series
-
-Create common dtsi for the FriendlyElec NanoPi R5 series.
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Link: https://lore.kernel.org/r/20230318083745.6181-2-cnsztl@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- .../boot/dts/rockchip/rk3568-nanopi-r5s.dts | 575 +----------------
- .../boot/dts/rockchip/rk3568-nanopi-r5s.dtsi | 596 ++++++++++++++++++
- 2 files changed, 597 insertions(+), 574 deletions(-)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-@@ -7,12 +7,7 @@
- */
-
- /dts-v1/;
--#include <dt-bindings/gpio/gpio.h>
--#include <dt-bindings/input/input.h>
--#include <dt-bindings/leds/common.h>
--#include <dt-bindings/pinctrl/rockchip.h>
--#include <dt-bindings/soc/rockchip,vop2.h>
--#include "rk3568.dtsi"
-+#include "rk3568-nanopi-r5s.dtsi"
-
- / {
- model = "FriendlyElec NanoPi R5S";
-@@ -20,23 +15,6 @@
-
- aliases {
- ethernet0 = &gmac0;
-- mmc0 = &sdmmc0;
-- mmc1 = &sdhci;
-- };
--
-- chosen: chosen {
-- stdout-path = "serial2:1500000n8";
-- };
--
-- hdmi-con {
-- compatible = "hdmi-connector";
-- type = "a";
--
-- port {
-- hdmi_con_in: endpoint {
-- remote-endpoint = <&hdmi_out_con>;
-- };
-- };
- };
-
- gpio-leds {
-@@ -71,130 +49,6 @@
- gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
- };
- };
--
-- vdd_usbc: vdd-usbc-regulator {
-- compatible = "regulator-fixed";
-- regulator-name = "vdd_usbc";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-min-microvolt = <5000000>;
-- regulator-max-microvolt = <5000000>;
-- };
--
-- 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 = <&vdd_usbc>;
-- };
--
-- 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 = <&vdd_usbc>;
-- };
--
-- vcc3v3_pcie: vcc3v3-pcie-regulator {
-- compatible = "regulator-fixed";
-- regulator-name = "vcc3v3_pcie";
-- regulator-min-microvolt = <3300000>;
-- regulator-max-microvolt = <3300000>;
-- enable-active-high;
-- gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
-- startup-delay-us = <200000>;
-- vin-supply = <&vcc5v0_sys>;
-- };
--
-- 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 = <&vdd_usbc>;
-- };
--
-- vcc5v0_usb_host: vcc5v0-usb-host-regulator {
-- compatible = "regulator-fixed";
-- enable-active-high;
-- gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&vcc5v0_usb_host_en>;
-- regulator-name = "vcc5v0_usb_host";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-min-microvolt = <5000000>;
-- regulator-max-microvolt = <5000000>;
-- vin-supply = <&vcc5v0_usb>;
-- };
--
-- vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
-- compatible = "regulator-fixed";
-- enable-active-high;
-- gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&vcc5v0_usb_otg_en>;
-- regulator-name = "vcc5v0_usb_otg";
-- regulator-min-microvolt = <5000000>;
-- regulator-max-microvolt = <5000000>;
-- vin-supply = <&vcc5v0_usb>;
-- };
--
-- pcie30_avdd0v9: pcie30-avdd0v9-regulator {
-- compatible = "regulator-fixed";
-- regulator-name = "pcie30_avdd0v9";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-min-microvolt = <900000>;
-- regulator-max-microvolt = <900000>;
-- vin-supply = <&vcc3v3_sys>;
-- };
--
-- pcie30_avdd1v8: pcie30-avdd1v8-regulator {
-- compatible = "regulator-fixed";
-- regulator-name = "pcie30_avdd1v8";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-min-microvolt = <1800000>;
-- regulator-max-microvolt = <1800000>;
-- vin-supply = <&vcc3v3_sys>;
-- };
--};
--
--&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 {
-@@ -219,292 +73,6 @@
- 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-cells = <1>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&pmic_int>;
-- rockchip,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;
--
-- regulators {
-- vdd_logic: DCDC_REG1 {
-- regulator-name = "vdd_logic";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-init-microvolt = <900000>;
-- 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-init-microvolt = <900000>;
-- 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-init-microvolt = <900000>;
-- 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 = <950000>;
-- regulator-max-microvolt = <950000>;
--
-- regulator-state-mem {
-- regulator-off-in-suspend;
-- };
-- };
--
-- vdda_0v9: LDO_REG2 {
-- regulator-name = "vdda_0v9";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-min-microvolt = <900000>;
-- regulator-max-microvolt = <900000>;
--
-- regulator-state-mem {
-- regulator-off-in-suspend;
-- };
-- };
--
-- vdda0v9_pmu: LDO_REG3 {
-- regulator-name = "vdda0v9_pmu";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-min-microvolt = <900000>;
-- regulator-max-microvolt = <900000>;
--
-- regulator-state-mem {
-- regulator-on-in-suspend;
-- regulator-suspend-microvolt = <900000>;
-- };
-- };
--
-- vccio_acodec: LDO_REG4 {
-- regulator-name = "vccio_acodec";
-- regulator-always-on;
-- regulator-min-microvolt = <3300000>;
-- regulator-max-microvolt = <3300000>;
--
-- regulator-state-mem {
-- regulator-off-in-suspend;
-- };
-- };
--
-- vccio_sd: LDO_REG5 {
-- regulator-name = "vccio_sd";
-- regulator-min-microvolt = <1800000>;
-- regulator-max-microvolt = <3300000>;
--
-- regulator-state-mem {
-- regulator-off-in-suspend;
-- };
-- };
--
-- vcc3v3_pmu: LDO_REG6 {
-- regulator-name = "vcc3v3_pmu";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-min-microvolt = <3300000>;
-- regulator-max-microvolt = <3300000>;
--
-- regulator-state-mem {
-- regulator-on-in-suspend;
-- regulator-suspend-microvolt = <3300000>;
-- };
-- };
--
-- vcca_1v8: LDO_REG7 {
-- regulator-name = "vcca_1v8";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-min-microvolt = <1800000>;
-- regulator-max-microvolt = <1800000>;
--
-- regulator-state-mem {
-- regulator-off-in-suspend;
-- };
-- };
--
-- vcca1v8_pmu: LDO_REG8 {
-- regulator-name = "vcca1v8_pmu";
-- regulator-always-on;
-- regulator-boot-on;
-- regulator-min-microvolt = <1800000>;
-- regulator-max-microvolt = <1800000>;
--
-- regulator-state-mem {
-- regulator-on-in-suspend;
-- regulator-suspend-microvolt = <1800000>;
-- };
-- };
--
-- vcca1v8_image: LDO_REG9 {
-- regulator-name = "vcca1v8_image";
-- regulator-min-microvolt = <1800000>;
-- regulator-max-microvolt = <1800000>;
--
-- regulator-state-mem {
-- regulator-off-in-suspend;
-- };
-- };
--
-- vcc_3v3: SWITCH_REG1 {
-- regulator-name = "vcc_3v3";
-- regulator-always-on;
-- regulator-boot-on;
--
-- regulator-state-mem {
-- regulator-off-in-suspend;
-- };
-- };
--
-- vcc3v3_sd: SWITCH_REG2 {
-- regulator-name = "vcc3v3_sd";
-- regulator-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 = <&hym8563_int>;
-- wakeup-source;
-- };
--};
--
--&i2s0_8ch {
-- status = "okay";
--};
--
--&i2s1_8ch {
-- rockchip,trcm-sync-tx-only;
-- status = "okay";
--};
--
- &mdio0 {
- rgmii_phy0: ethernet-phy@1 {
- compatible = "ethernet-phy-ieee802.3-c22";
-@@ -568,146 +136,5 @@
- rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
- };
- };
--
-- hym8563 {
-- hym8563_int: hym8563-int {
-- rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
-- };
-- };
--
-- pmic {
-- pmic_int: pmic-int {
-- rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
-- };
-- };
--
-- usb {
-- vcc5v0_usb_host_en: vcc5v0-usb-host-en {
-- rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
-- };
--
-- vcc5v0_usb_otg_en: vcc5v0-usb-otg-en {
-- rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
-- };
-- };
--};
--
--&pmu_io_domains {
-- pmuio1-supply = <&vcc3v3_pmu>;
-- pmuio2-supply = <&vcc3v3_pmu>;
-- vccio1-supply = <&vccio_acodec>;
-- 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>;
-- max-frequency = <200000000>;
-- non-removable;
-- pinctrl-names = "default";
-- pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
-- status = "okay";
--};
--
--&sdmmc0 {
-- max-frequency = <150000000>;
-- no-sdio;
-- no-mmc;
-- bus-width = <4>;
-- cap-mmc-highspeed;
-- cap-sd-highspeed;
-- disable-wp;
-- vmmc-supply = <&vcc3v3_sd>;
-- vqmmc-supply = <&vccio_sd>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
-- status = "okay";
--};
--
--&tsadc {
-- rockchip,hw-tshut-mode = <1>;
-- rockchip,hw-tshut-polarity = <0>;
-- status = "okay";
--};
--
--&uart2 {
-- status = "okay";
--};
--
--&usb_host0_ehci {
-- status = "okay";
--};
--
--&usb_host0_ohci {
-- status = "okay";
--};
--
--&usb_host0_xhci {
-- extcon = <&usb2phy0>;
-- 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_usb_host>;
-- status = "okay";
--};
--
--&usb2phy0_otg {
-- status = "okay";
--};
--
--&usb2phy1 {
-- status = "okay";
--};
--
--&usb2phy1_host {
-- phy-supply = <&vcc5v0_usb_otg>;
-- status = "okay";
--};
--
--&usb2phy1_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/rk3568-nanopi-r5s.dtsi
-@@ -0,0 +1,596 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright (c) 2022 FriendlyElec Computer Tech. Co., Ltd.
-+ * (http://www.friendlyelec.com)
-+ *
-+ * Copyright (c) 2023 Tianling Shen <cnsztl@gmail.com>
-+ */
-+
-+/dts-v1/;
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/pinctrl/rockchip.h>
-+#include <dt-bindings/soc/rockchip,vop2.h>
-+#include "rk3568.dtsi"
-+
-+/ {
-+ aliases {
-+ mmc0 = &sdmmc0;
-+ mmc1 = &sdhci;
-+ };
-+
-+ chosen: chosen {
-+ stdout-path = "serial2:1500000n8";
-+ };
-+
-+ hdmi-con {
-+ compatible = "hdmi-connector";
-+ type = "a";
-+
-+ port {
-+ hdmi_con_in: endpoint {
-+ remote-endpoint = <&hdmi_out_con>;
-+ };
-+ };
-+ };
-+
-+ vdd_usbc: vdd-usbc-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vdd_usbc";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ };
-+
-+ 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 = <&vdd_usbc>;
-+ };
-+
-+ 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 = <&vdd_usbc>;
-+ };
-+
-+ vcc3v3_pcie: vcc3v3-pcie-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc3v3_pcie";
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ enable-active-high;
-+ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
-+ startup-delay-us = <200000>;
-+ vin-supply = <&vcc5v0_sys>;
-+ };
-+
-+ 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 = <&vdd_usbc>;
-+ };
-+
-+ vcc5v0_usb_host: vcc5v0-usb-host-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&vcc5v0_usb_host_en>;
-+ regulator-name = "vcc5v0_usb_host";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ vin-supply = <&vcc5v0_usb>;
-+ };
-+
-+ vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&vcc5v0_usb_otg_en>;
-+ regulator-name = "vcc5v0_usb_otg";
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ vin-supply = <&vcc5v0_usb>;
-+ };
-+
-+ pcie30_avdd0v9: pcie30-avdd0v9-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "pcie30_avdd0v9";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+ vin-supply = <&vcc3v3_sys>;
-+ };
-+
-+ pcie30_avdd1v8: pcie30-avdd1v8-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "pcie30_avdd1v8";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ vin-supply = <&vcc3v3_sys>;
-+ };
-+};
-+
-+&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>;
-+};
-+
-+&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-cells = <1>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pmic_int>;
-+ rockchip,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;
-+
-+ regulators {
-+ vdd_logic: DCDC_REG1 {
-+ regulator-name = "vdd_logic";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-init-microvolt = <900000>;
-+ 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-init-microvolt = <900000>;
-+ 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-init-microvolt = <900000>;
-+ 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 = <950000>;
-+ regulator-max-microvolt = <950000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vdda_0v9: LDO_REG2 {
-+ regulator-name = "vdda_0v9";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vdda0v9_pmu: LDO_REG3 {
-+ regulator-name = "vdda0v9_pmu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <900000>;
-+ };
-+ };
-+
-+ vccio_acodec: LDO_REG4 {
-+ regulator-name = "vccio_acodec";
-+ regulator-always-on;
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vccio_sd: LDO_REG5 {
-+ regulator-name = "vccio_sd";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <3300000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc3v3_pmu: LDO_REG6 {
-+ regulator-name = "vcc3v3_pmu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <3300000>;
-+ };
-+ };
-+
-+ vcca_1v8: LDO_REG7 {
-+ regulator-name = "vcca_1v8";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcca1v8_pmu: LDO_REG8 {
-+ regulator-name = "vcca1v8_pmu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <1800000>;
-+ };
-+ };
-+
-+ vcca1v8_image: LDO_REG9 {
-+ regulator-name = "vcca1v8_image";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc_3v3: SWITCH_REG1 {
-+ regulator-name = "vcc_3v3";
-+ regulator-always-on;
-+ regulator-boot-on;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc3v3_sd: SWITCH_REG2 {
-+ regulator-name = "vcc3v3_sd";
-+ regulator-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 = <&hym8563_int>;
-+ wakeup-source;
-+ };
-+};
-+
-+&i2s0_8ch {
-+ status = "okay";
-+};
-+
-+&i2s1_8ch {
-+ rockchip,trcm-sync-tx-only;
-+ status = "okay";
-+};
-+
-+&pcie30phy {
-+ data-lanes = <1 2>;
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ hym8563 {
-+ hym8563_int: hym8563-int {
-+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
-+ };
-+ };
-+
-+ pmic {
-+ pmic_int: pmic-int {
-+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
-+ };
-+ };
-+
-+ usb {
-+ vcc5v0_usb_host_en: vcc5v0-usb-host-en {
-+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ vcc5v0_usb_otg_en: vcc5v0-usb-otg-en {
-+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+};
-+
-+&pmu_io_domains {
-+ pmuio1-supply = <&vcc3v3_pmu>;
-+ pmuio2-supply = <&vcc3v3_pmu>;
-+ vccio1-supply = <&vccio_acodec>;
-+ 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>;
-+ max-frequency = <200000000>;
-+ non-removable;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
-+ status = "okay";
-+};
-+
-+&sdmmc0 {
-+ max-frequency = <150000000>;
-+ no-sdio;
-+ no-mmc;
-+ bus-width = <4>;
-+ cap-mmc-highspeed;
-+ cap-sd-highspeed;
-+ disable-wp;
-+ vmmc-supply = <&vcc3v3_sd>;
-+ vqmmc-supply = <&vccio_sd>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
-+ status = "okay";
-+};
-+
-+&tsadc {
-+ rockchip,hw-tshut-mode = <1>;
-+ rockchip,hw-tshut-polarity = <0>;
-+ status = "okay";
-+};
-+
-+&uart2 {
-+ status = "okay";
-+};
-+
-+&usb_host0_ehci {
-+ status = "okay";
-+};
-+
-+&usb_host0_ohci {
-+ status = "okay";
-+};
-+
-+&usb_host0_xhci {
-+ extcon = <&usb2phy0>;
-+ 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_usb_host>;
-+ status = "okay";
-+};
-+
-+&usb2phy0_otg {
-+ status = "okay";
-+};
-+
-+&usb2phy1 {
-+ status = "okay";
-+};
-+
-+&usb2phy1_host {
-+ phy-supply = <&vcc5v0_usb_otg>;
-+ status = "okay";
-+};
-+
-+&usb2phy1_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
-From 31425b1fadb2040b359e52ffc24c049a78d56c96 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Sat, 18 Mar 2023 16:37:44 +0800
-Subject: [PATCH] arm64: dts: rockchip: fix gmac support for NanoPi R5S
-
-- Changed phy-mode to rgmii.
-
-- Fixed pull type in pinctrl for gmac0.
-
-- Removed duplicate properties in mdio node.
- These properties are defined in the gmac0 node already.
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Link: https://lore.kernel.org/r/20230318083745.6181-5-cnsztl@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts | 7 ++-----
- 1 file changed, 2 insertions(+), 5 deletions(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-@@ -57,7 +57,7 @@
- assigned-clock-rates = <0>, <125000000>;
- clock_in_out = "output";
- phy-handle = <&rgmii_phy0>;
-- phy-mode = "rgmii-id";
-+ phy-mode = "rgmii";
- pinctrl-names = "default";
- pinctrl-0 = <&gmac0_miim
- &gmac0_tx_bus2
-@@ -79,9 +79,6 @@
- reg = <1>;
- pinctrl-0 = <ð_phy0_reset_pin>;
- pinctrl-names = "default";
-- reset-assert-us = <10000>;
-- reset-deassert-us = <50000>;
-- reset-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
- };
- };
-
-@@ -115,7 +112,7 @@
- &pinctrl {
- gmac0 {
- eth_phy0_reset_pin: eth-phy0-reset-pin {
-- rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>;
-+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>;
- };
- };
-
+++ /dev/null
-From 975e9bbad11950fc8276f1fa260d8bf2c341aa41 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Sat, 18 Mar 2023 16:37:45 +0800
-Subject: [PATCH] arm64: dts: rockchip: remove I2S1 TDM node for the NanoPi R5
- series
-
-This is for the audio output which does not exist on the boards.
-Also disable regulator-always-on for vccio_acodec since it's only
-used by the audio output.
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Link: https://lore.kernel.org/r/20230318083745.6181-6-cnsztl@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi | 6 ------
- 1 file changed, 6 deletions(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
-@@ -330,7 +330,6 @@
-
- vccio_acodec: LDO_REG4 {
- regulator-name = "vccio_acodec";
-- regulator-always-on;
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
-
-@@ -441,11 +440,6 @@
- status = "okay";
- };
-
--&i2s1_8ch {
-- rockchip,trcm-sync-tx-only;
-- status = "okay";
--};
--
- &pcie30phy {
- data-lanes = <1 2>;
- status = "okay";
+++ /dev/null
-From 05620031408ac6cfc6d5c048431827e49aa0ade1 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Sat, 18 Mar 2023 16:37:43 +0800
-Subject: [PATCH] arm64: dts: rockchip: Add FriendlyARM NanoPi R5C
-
-FriendlyARM NanoPi R5C is an open-sourced mini IoT gateway device.
-
-Specification:
-- Rockchip RK3568
-- 1/4GB LPDDR4X RAM
-- 8/32GB eMMC
-- SD card slot
-- M.2 Connector
-- 2x USB 3.0 Port
-- 2x 2500 Base-T (PCIe, r8125)
-- HDMI 2.0
-- MIPI DSI/CSI
-- USB Type C 5V
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Link: https://lore.kernel.org/r/20230318083745.6181-4-cnsztl@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/Makefile | 1 +
- .../boot/dts/rockchip/rk3568-nanopi-r5c.dts | 112 ++++++++++++++++++
- 2 files changed, 113 insertions(+)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5c.dts
-
---- a/arch/arm64/boot/dts/rockchip/Makefile
-+++ b/arch/arm64/boot/dts/rockchip/Makefile
-@@ -74,5 +74,6 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-ro
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
-+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5c.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5c.dts
-@@ -0,0 +1,112 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright (c) 2022 FriendlyElec Computer Tech. Co., Ltd.
-+ * (http://www.friendlyelec.com)
-+ *
-+ * Copyright (c) 2023 Tianling Shen <cnsztl@gmail.com>
-+ */
-+
-+/dts-v1/;
-+#include "rk3568-nanopi-r5s.dtsi"
-+
-+/ {
-+ model = "FriendlyElec NanoPi R5C";
-+ compatible = "friendlyarm,nanopi-r5c", "rockchip,rk3568";
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&reset_button_pin>;
-+
-+ button-reset {
-+ debounce-interval = <50>;
-+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>;
-+ label = "reset";
-+ linux,code = <KEY_RESTART>;
-+ };
-+ };
-+
-+ gpio-leds {
-+ compatible = "gpio-leds";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&lan_led_pin>, <&power_led_pin>, <&wan_led_pin>, <&wlan_led_pin>;
-+
-+ led-lan {
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_LAN;
-+ gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ power_led: led-power {
-+ color = <LED_COLOR_ID_RED>;
-+ function = LED_FUNCTION_POWER;
-+ linux,default-trigger = "heartbeat";
-+ gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-wan {
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_WAN;
-+ gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-wlan {
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_WLAN;
-+ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
-+
-+&pcie2x1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie20_reset_pin>;
-+ reset-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
-+ status = "okay";
-+};
-+
-+&pcie3x1 {
-+ num-lanes = <1>;
-+ reset-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
-+ vpcie3v3-supply = <&vcc3v3_pcie>;
-+ status = "okay";
-+};
-+
-+&pcie3x2 {
-+ num-lanes = <1>;
-+ reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
-+ vpcie3v3-supply = <&vcc3v3_pcie>;
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ gpio-leds {
-+ lan_led_pin: lan-led-pin {
-+ rockchip,pins = <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ power_led_pin: power-led-pin {
-+ rockchip,pins = <3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ wan_led_pin: wan-led-pin {
-+ rockchip,pins = <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ wlan_led_pin: wlan-led-pin {
-+ rockchip,pins = <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+
-+ pcie {
-+ pcie20_reset_pin: pcie20-reset-pin {
-+ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
-+ };
-+ };
-+
-+ rockchip-key {
-+ reset_button_pin: reset-button-pin {
-+ rockchip,pins = <4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
-+ };
-+ };
-+};
+++ /dev/null
-From 5325593377f07de31f7e473a9677a28a04c891f3 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Thu, 11 May 2023 00:18:50 +0800
-Subject: [PATCH] arm64: dts: rockchip: fix button reset pin for nanopi r5c
-
-The reset pin was wrongly assigned due to a copy/paste error,
-fix it to match actual gpio pin.
-
-While at it, remove a blank line from nanopi r5s dts.
-
-Fixes: 05620031408a ("arm64: dts: rockchip: Add FriendlyARM NanoPi R5C")
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Link: https://lore.kernel.org/r/20230510161850.4866-1-cnsztl@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5c.dts | 2 +-
- arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts | 1 -
- 2 files changed, 1 insertion(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5c.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5c.dts
-@@ -106,7 +106,7 @@
-
- rockchip-key {
- reset_button_pin: reset-button-pin {
-- rockchip,pins = <4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
-+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>;
- };
- };
- };
---- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-@@ -134,4 +134,3 @@
- };
- };
- };
--
+++ /dev/null
-From fc5a80a432607d05e85bba37971712405f75c546 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Sat, 16 Dec 2023 12:07:23 +0800
-Subject: [PATCH] arm64: dts: rockchip: configure eth pad driver strength
- for orangepi r1 plus lts
-
-The default strength is not enough to provide stable connection
-under 3.3v LDO voltage.
-
-Fixes: 387b3bbac5ea ("arm64: dts: rockchip: Add Xunlong OrangePi R1 Plus LTS")
-Cc: stable@vger.kernel.org # 6.6+
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Link: https://lore.kernel.org/r/20231216040723.17864-1-cnsztl@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts
-@@ -26,9 +26,11 @@
- compatible = "ethernet-phy-ieee802.3-c22";
- reg = <0>;
-
-+ motorcomm,auto-sleep-disabled;
- motorcomm,clk-out-frequency-hz = <125000000>;
- motorcomm,keep-pll-enabled;
-- motorcomm,auto-sleep-disabled;
-+ motorcomm,rx-clk-drv-microamp = <5020>;
-+ motorcomm,rx-data-drv-microamp = <5020>;
-
- pinctrl-0 = <ð_phy_reset_pin>;
- pinctrl-names = "default";
+++ /dev/null
-From 096ebfb74b19f2d4bdcbc33ae02e857ff4b3e0a0 Mon Sep 17 00:00:00 2001
-From: Jagan Teki <jagan@amarulasolutions.com>
-Date: Thu, 12 Jan 2023 16:29:02 +0530
-Subject: [PATCH] arm64: dts: rockchip: Add Radxa Compute Module 3 IO board
-
-Radxa Compute Module 3(CM3) IO board is an application board from Radxa
-and is compatible with Raspberry Pi CM4 IO form factor.
-
-Specification:
-- 1x HDMI,
-- 2x MIPI DSI
-- 2x MIPI CSI2
-- 1x eDP
-- 1x PCIe card
-- 2x SATA
-- 2x USB 2.0 Host
-- 1x USB 3.0
-- 1x USB 2.0 OTG
-- Phone jack
-- microSD slot
-- 40-pin GPIO expansion header
-- 12V DC
-
-Radxa CM3 needs to mount on top of this IO board in order to create
-complete Radxa CM3 IO board platform.
-
-Add support for Radxa CM3 IO Board.
-
-Co-developed-by: FUKAUMI Naoki <naoki@radxa.com>
-Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
-Co-developed-by: Manoj Sai <abbaraju.manojsai@amarulasolutions.com>
-Signed-off-by: Manoj Sai <abbaraju.manojsai@amarulasolutions.com>
-Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
-Link: https://lore.kernel.org/r/20230112105902.192852-3-jagan@amarulasolutions.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/Makefile | 1 +
- .../boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 179 ++++++++++++++++++
- 2 files changed, 180 insertions(+)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-
---- a/arch/arm64/boot/dts/rockchip/Makefile
-+++ b/arch/arm64/boot/dts/rockchip/Makefile
-@@ -70,6 +70,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pi
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.2.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb
-+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-cm3-io.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-@@ -0,0 +1,179 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+/*
-+ * Copyright (c) 2022 Radxa Limited
-+ * Copyright (c) 2022 Amarula Solutions(India)
-+ */
-+
-+/dts-v1/;
-+#include <dt-bindings/soc/rockchip,vop2.h>
-+#include "rk3566.dtsi"
-+#include "rk3566-radxa-cm3.dtsi"
-+
-+/ {
-+ model = "Radxa Compute Module 3(CM3) IO Board";
-+ compatible = "radxa,radxa-cm3-io", "radxa,radxa-cm3", "rockchip,rk3566";
-+
-+ aliases {
-+ mmc1 = &sdmmc0;
-+ };
-+
-+ chosen: chosen {
-+ stdout-path = "serial2:1500000n8";
-+ };
-+
-+ hdmi-con {
-+ compatible = "hdmi-connector";
-+ type = "a";
-+
-+ port {
-+ hdmi_con_in: endpoint {
-+ remote-endpoint = <&hdmi_out_con>;
-+ };
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-1 {
-+ gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_LOW>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_ACTIVITY;
-+ linux,default-trigger = "heartbeat";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pi_nled_activity>;
-+ };
-+ };
-+
-+ vcc5v0_usb30: vcc5v0-usb30-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc5v0_usb30";
-+ enable-active-high;
-+ gpio = <&gpio3 RK_PC2 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&vcc5v0_usb30_en_h>;
-+ regulator-always-on;
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ vin-supply = <&vcc_sys>;
-+ };
-+
-+ vcca1v8_image: vcca1v8-image-regulator {
-+ 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>;
-+ };
-+
-+ vdda0v9_image: vdda0v9-image-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcca0v9_image";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+ vin-supply = <&vdda_0v9>;
-+ };
-+};
-+
-+&combphy1 {
-+ 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";
-+};
-+
-+&pinctrl {
-+ leds {
-+ pi_nled_activity: pi-nled-activity {
-+ rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+
-+ sdcard {
-+ sdmmc_pwren: sdmmc-pwren {
-+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+
-+ usb {
-+ vcc5v0_usb30_en_h: vcc5v0-host-en-h {
-+ rockchip,pins = <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+};
-+
-+&sdmmc0 {
-+ bus-width = <4>;
-+ cap-mmc-highspeed;
-+ cap-sd-highspeed;
-+ disable-wp;
-+ vqmmc-supply = <&vccio_sd>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det &sdmmc0_pwren>;
-+ status = "okay";
-+};
-+
-+&uart2 {
-+ status = "okay";
-+};
-+
-+&usb2phy0_host {
-+ phy-supply = <&vcc5v0_usb30>;
-+ status = "okay";
-+};
-+
-+&usb2phy1_host {
-+ status = "okay";
-+};
-+
-+&usb2phy1_otg {
-+ status = "okay";
-+};
-+
-+&usb_host0_ehci {
-+ status = "okay";
-+};
-+
-+&usb_host1_xhci {
-+ 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
-From d211665c5a833873ee37e501af58adbf028e6b5f Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Sat, 13 May 2023 21:53:07 +0800
-Subject: [PATCH] arm64: dts: rockchip: Add FriendlyARM NanoPi R2C Plus
-
-The NanoPi R2C Plus is a small variant of NanoPi R2C with a on-board
-eMMC flash (8G) included.
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
-Link: https://lore.kernel.org/r/20230513135307.26554-2-cnsztl@gmail.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/Makefile | 1 +
- .../boot/dts/rockchip/rk3328-nanopi-r2c-plus.dts | 33 ++++++++++++++++++++++
- 2 files changed, 34 insertions(+)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c-plus.dts
-
---- a/arch/arm64/boot/dts/rockchip/Makefile
-+++ b/arch/arm64/boot/dts/rockchip/Makefile
-@@ -11,6 +11,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-od
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb
-+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c-plus.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2c-plus.dts
-@@ -0,0 +1,33 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright (c) 2021 FriendlyElec Computer Tech. Co., Ltd.
-+ * (http://www.friendlyarm.com)
-+ *
-+ * Copyright (c) 2023 Tianling Shen <cnsztl@gmail.com>
-+ */
-+
-+/dts-v1/;
-+#include "rk3328-nanopi-r2c.dts"
-+
-+/ {
-+ model = "FriendlyElec NanoPi R2C Plus";
-+ compatible = "friendlyarm,nanopi-r2c-plus", "rockchip,rk3328";
-+
-+ aliases {
-+ mmc1 = &emmc;
-+ };
-+};
-+
-+&emmc {
-+ bus-width = <8>;
-+ cap-mmc-highspeed;
-+ max-frequency = <150000000>;
-+ mmc-ddr-1_8v;
-+ mmc-hs200-1_8v;
-+ non-removable;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
-+ vmmc-supply = <&vcc_io_33>;
-+ vqmmc-supply = <&vcc18_emmc>;
-+ status = "okay";
-+};
+++ /dev/null
-From cc52bfc04726a574fc4440bbbe0c710890e7040a Mon Sep 17 00:00:00 2001
-From: Manoj Sai <abbaraju.manojsai@amarulasolutions.com>
-Date: Wed, 25 Jan 2023 21:40:22 +0530
-Subject: [PATCH] arm64: dts: rockchip: Enable Ethernet for Radxa CM3 IO
-
-Add ethernet nodes for enabling gmac1 on the Radxa CM3 IO board.
-
-Signed-off-by: Manoj Sai <abbaraju.manojsai@amarulasolutions.com>
-Link: https://lore.kernel.org/r/20230125161023.12115-1-jagan@amarulasolutions.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- .../boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 93 +++++++++++++++++++
- 1 file changed, 93 insertions(+)
-
---- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-@@ -21,6 +21,13 @@
- 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";
-@@ -83,6 +90,29 @@
- status = "okay";
- };
-
-+&gmac1 {
-+ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
-+ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>;
-+ assigned-clock-rates = <0>, <125000000>;
-+ clock_in_out = "input";
-+ phy-handle = <&rgmii_phy1>;
-+ phy-mode = "rgmii";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&gmac1m0_miim
-+ &gmac1m0_tx_bus2
-+ &gmac1m0_rx_bus2
-+ &gmac1m0_rgmii_clk
-+ &gmac1m0_rgmii_bus
-+ &gmac1m0_clkinout>;
-+ snps,reset-gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_LOW>;
-+ snps,reset-active-low;
-+ /* Reset time is 20ms, 100ms for rtl8211f */
-+ snps,reset-delays-us = <0 20000 100000>;
-+ tx_delay = <0x46>;
-+ rx_delay = <0x2e>;
-+ status = "okay";
-+};
-+
- &hdmi {
- avdd-0v9-supply = <&vdda0v9_image>;
- avdd-1v8-supply = <&vcca1v8_image>;
-@@ -105,7 +135,70 @@
- status = "okay";
- };
-
-+&mdio1 {
-+ rgmii_phy1: ethernet-phy@0 {
-+ compatible="ethernet-phy-ieee802.3-c22";
-+ reg= <0x0>;
-+ };
-+};
-+
- &pinctrl {
-+ gmac1 {
-+ gmac1m0_miim: gmac1m0-miim {
-+ rockchip,pins =
-+ /* gmac1_mdcm0 */
-+ <3 RK_PC4 3 &pcfg_pull_none_drv_level_15>,
-+ /* gmac1_mdiom0 */
-+ <3 RK_PC5 3 &pcfg_pull_none_drv_level_15>;
-+ };
-+
-+ gmac1m0_rx_bus2: gmac1m0-rx-bus2 {
-+ rockchip,pins =
-+ /* gmac1_rxd0m0 */
-+ <3 RK_PB1 3 &pcfg_pull_none_drv_level_15>,
-+ /* gmac1_rxd1m0 */
-+ <3 RK_PB2 3 &pcfg_pull_none_drv_level_15>,
-+ /* gmac1_rxdvcrsm0 */
-+ <3 RK_PB3 3 &pcfg_pull_none_drv_level_15>;
-+ };
-+
-+ gmac1m0_tx_bus2: gmac1m0-tx-bus2 {
-+ rockchip,pins =
-+ /* gmac1_txd0m0 */
-+ <3 RK_PB5 3 &pcfg_pull_none_drv_level_15>,
-+ /* gmac1_txd1m0 */
-+ <3 RK_PB6 3 &pcfg_pull_none_drv_level_15>,
-+ /* gmac1_txenm0 */
-+ <3 RK_PB7 3 &pcfg_pull_none_drv_level_15>;
-+ };
-+
-+ gmac1m0_rgmii_clk: gmac1m0-rgmii-clk {
-+ rockchip,pins =
-+ /* gmac1_rxclkm0 */
-+ <3 RK_PA7 3 &pcfg_pull_none_drv_level_15>,
-+ /* gmac1_txclkm0 */
-+ <3 RK_PA6 3 &pcfg_pull_none_drv_level_15>;
-+ };
-+
-+ gmac1m0_rgmii_bus: gmac1m0-rgmii-bus {
-+ rockchip,pins =
-+ /* gmac1_rxd2m0 */
-+ <3 RK_PA4 3 &pcfg_pull_none_drv_level_15>,
-+ /* gmac1_rxd3m0 */
-+ <3 RK_PA5 3 &pcfg_pull_none_drv_level_15>,
-+ /* gmac1_txd2m0 */
-+ <3 RK_PA2 3 &pcfg_pull_none_drv_level_15>,
-+ /* gmac1_txd3m0 */
-+ <3 RK_PA3 3 &pcfg_pull_none_drv_level_15>;
-+ };
-+
-+ gmac1m0_clkinout: gmac1m0-clkinout {
-+ rockchip,pins =
-+ /* gmac1_mclkinoutm0 */
-+ <3 RK_PC0 3 &pcfg_pull_none_drv_level_15>;
-+ };
-+ };
-+
- leds {
- pi_nled_activity: pi-nled-activity {
- rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+++ /dev/null
-From 7469ab529bcad50490f6ff651c3e4f03bfa88fe0 Mon Sep 17 00:00:00 2001
-From: Jagan Teki <jagan@amarulasolutions.com>
-Date: Thu, 12 Jan 2023 16:29:01 +0530
-Subject: [PATCH] arm64: dts: rockchip: Add rk3566 based Radxa Compute Module 3
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Radxa Compute Module 3(CM3) is one of the modules from a series
-System On Module based on the Radxa ROCK 3 series and is compatible
-with Raspberry Pi CM4 pinout and form factor.
-
-Specification:
-- Rockchip RK3566
-- up to 8GB LPDDR4
-- up to 128GB high performance eMMC
-- Optional wireless LAN, 2.4GHz and 5.0GHz IEEE 802.11b/g/n/ac wireless,
- BT 5.0, BLE with onboard and external antenna.
-- Gigabit Ethernet PHY
-
-Radxa CM3 needs to mount on top of this IO board in order to create
-complete Radxa CM3 IO board platform.
-
-Since Radxa CM3 is compatible with Raspberry Pi CM4 pinout so it is
-possible to mount Radxa CM3 on top of the Rasberry Pi CM4 IO board.
-
-Add support for Radxa CM3.
-
-Co-developed-by: FUKAUMI Naoki <naoki@radxa.com>
-Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
-Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
-Link: https://lore.kernel.org/r/20230112105902.192852-2-jagan@amarulasolutions.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- .../boot/dts/rockchip/rk3566-radxa-cm3.dtsi | 345 ++++++++++++++++++
- 1 file changed, 345 insertions(+)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
-
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
-@@ -0,0 +1,345 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+/*
-+ * Copyright (c) 2022 Radxa Limited
-+ * Copyright (c) 2022 Amarula Solutions(India)
-+ */
-+
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ compatible = "radxa,radxa-cm3", "rockchip,rk3566";
-+
-+ aliases {
-+ mmc0 = &sdhci;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-0 {
-+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_STATUS;
-+ linux,default-trigger = "timer";
-+ default-state = "on";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&user_led2>;
-+ };
-+ };
-+
-+ vcc_sys: vcc-sys-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc_sys";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ };
-+
-+ vcc_1v8: vcc-1v8-regulator {
-+ 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>;
-+ };
-+
-+ vcc_3v3: vcc-3v3-regulator {
-+ 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>;
-+ };
-+
-+ vcca_1v8: vcca-1v8-regulator {
-+ 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>;
-+ };
-+};
-+
-+&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";
-+};
-+
-+&i2c0 {
-+ status = "okay";
-+
-+ vdd_cpu: regulator@1c {
-+ compatible = "tcs,tcs4525";
-+ reg = <0x1c>;
-+ fcs,suspend-voltage-selector = <1>;
-+ regulator-name = "vdd_cpu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <712500>;
-+ regulator-max-microvolt = <1390000>;
-+ regulator-ramp-delay = <2300>;
-+ vin-supply = <&vcc_sys>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ 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>;
-+ rockchip,system-power-controller;
-+ wakeup-source;
-+
-+ vcc1-supply = <&vcc_sys>;
-+ vcc2-supply = <&vcc_sys>;
-+ vcc3-supply = <&vcc_sys>;
-+ vcc4-supply = <&vcc_sys>;
-+ vcc5-supply = <&vcc_sys>;
-+ vcc6-supply = <&vcc_sys>;
-+ vcc7-supply = <&vcc_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-on-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;
-+ };
-+ };
-+
-+ };
-+ };
-+};
-+
-+&pinctrl {
-+ pmic {
-+ pmic_int_l: pmic-int-l {
-+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
-+ };
-+ };
-+
-+ leds {
-+ user_led2: user-led2 {
-+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+};
-+
-+&pmu_io_domains {
-+ pmuio1-supply = <&vcc3v3_pmu>;
-+ pmuio2-supply = <&vcc_3v3>;
-+ 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";
-+};
-+
-+&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";
-+};
-+
-+&usb2phy0 {
-+ status = "okay";
-+};
-+
-+&usb2phy1 {
-+ status = "okay";
-+};
-+
-+&tsadc {
-+ rockchip,hw-tshut-mode = <1>;
-+ rockchip,hw-tshut-polarity = <0>;
-+ status = "okay";
-+};
+++ /dev/null
-From af5a803bf212e077e5fb7a1d4cf6be02f74a74ca Mon Sep 17 00:00:00 2001
-From: Jagan Teki <jagan@amarulasolutions.com>
-Date: Wed, 25 Jan 2023 21:40:23 +0530
-Subject: [PATCH] arm64: dts: rockchip: rk3566: Enable WiFi, BT support for
- Radxa CM3
-
-Radxa Compute Module 3 has an onboard AW_CM256SM WiFi/BT module.
-
-Add nodes for enabling it.
-
-Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
-Link: https://lore.kernel.org/r/20230125161023.12115-2-jagan@amarulasolutions.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- .../boot/dts/rockchip/rk3566-radxa-cm3.dtsi | 80 +++++++++++++++++++
- 1 file changed, 80 insertions(+)
-
---- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
-@@ -66,6 +66,15 @@
- regulator-max-microvolt = <1800000>;
- vin-supply = <&vcc_1v8_p>;
- };
-+
-+ sdio_pwrseq: pwrseq-sdio {
-+ compatible = "mmc-pwrseq-simple";
-+ clocks = <&rk817 1>;
-+ clock-names = "ext_clock";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&wifi_reg_on_h>;
-+ reset-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_LOW>;
-+ };
- };
-
- &cpu0 {
-@@ -287,6 +296,20 @@
- };
-
- &pinctrl {
-+ bluetooth {
-+ bt_host_wake_h: bt-host-wake-h {
-+ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ bt_reg_on_h: bt-reg-on-h {
-+ rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ bt_wake_host_h: bt-wake-host-h {
-+ rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+
- pmic {
- pmic_int_l: pmic-int-l {
- rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
-@@ -298,6 +321,16 @@
- rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
- };
- };
-+
-+ wifi {
-+ wifi_reg_on_h: wifi-reg-on-h {
-+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ wifi_host_wake_h: wifi-host-wake-h {
-+ rockchip,pins = <2 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
- };
-
- &pmu_io_domains {
-@@ -318,6 +351,34 @@
- status = "okay";
- };
-
-+&sdmmc1 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ bus-width = <4>;
-+ disable-wp;
-+ 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 = <&vcc_3v3>;
-+ vqmmc-supply = <&vcc_1v8>;
-+ status = "okay";
-+
-+ wifi@1 {
-+ compatible = "brcm,bcm43455-fmac";
-+ reg = <1>;
-+ interrupt-parent = <&gpio2>;
-+ interrupts = <RK_PC1 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupt-names = "host-wake";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&wifi_host_wake_h>;
-+ };
-+};
-+
- &sdhci {
- bus-width = <8>;
- max-frequency = <200000000>;
-@@ -330,6 +391,25 @@
- status = "okay";
- };
-
-+&uart1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart1m0_ctsn &uart1m0_rtsn &uart1m0_xfer>;
-+ status = "okay";
-+
-+ bluetooth {
-+ compatible = "brcm,bcm4345c5";
-+ clocks = <&rk817 1>;
-+ clock-names = "lpo";
-+ device-wakeup-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>;
-+ host-wakeup-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_HIGH>;
-+ reset-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_LOW>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&bt_host_wake_h &bt_reg_on_h &bt_wake_host_h>;
-+ vbat-supply = <&vcc_3v3>;
-+ vddio-supply = <&vcc_1v8>;
-+ };
-+};
-+
- &usb2phy0 {
- status = "okay";
- };
+++ /dev/null
-From 477ed3ade6a46e445b4e2348b710c51df4f6f4b1 Mon Sep 17 00:00:00 2001
-From: Manoj Sai <abbaraju.manojsai@amarulasolutions.com>
-Date: Thu, 23 Feb 2023 19:29:29 +0530
-Subject: [PATCH] arm64: dts: rockchip: Enable USB OTG for rk3566 Radxa CM3
-
-Enable USB OTG support for Radxa Compute Module 3 IO Board
-
-Signed-off-by: Manoj Sai <abbaraju.manojsai@amarulasolutions.com>
-Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
-Link: https://lore.kernel.org/r/20230223135929.630787-1-abbaraju.manojsai@amarulasolutions.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-@@ -254,6 +254,14 @@
- status = "okay";
- };
-
-+&usb2phy0_otg {
-+ status = "okay";
-+};
-+
-+&usb_host0_xhci {
-+ status = "okay";
-+};
-+
- &vop {
- assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
- assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+++ /dev/null
-From 8f19828844f20b22182719cf53be64f8c955aee8 Mon Sep 17 00:00:00 2001
-From: Jagan Teki <jagan@amarulasolutions.com>
-Date: Mon, 23 Jan 2023 12:46:50 +0530
-Subject: [PATCH] arm64: dts: rockchip: Fix compatible for Radxa CM3
-
-The compatible string "radxa,radxa-cm3" referring the product name
-as "Radxa Radxa CM3" but the actual product name is "Radxa CM3".
-
-Fix the compatible strings.
-
-Fixes: 24a28d3eb07d ("dt-bindings: arm: rockchip: Add Radxa Compute Module 3")
-Fixes: 7469ab529bca ("arm64: dts: rockchip: Add rk3566 based Radxa Compute Module 3")
-Fixes: 096ebfb74b19 ("arm64: dts: rockchip: Add Radxa Compute Module 3 IO board")
-Suggested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20230123071654.73139-1-jagan@amarulasolutions.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 2 +-
- arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-@@ -11,7 +11,7 @@
-
- / {
- model = "Radxa Compute Module 3(CM3) IO Board";
-- compatible = "radxa,radxa-cm3-io", "radxa,radxa-cm3", "rockchip,rk3566";
-+ compatible = "radxa,cm3-io", "radxa,cm3", "rockchip,rk3566";
-
- aliases {
- mmc1 = &sdmmc0;
---- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
-@@ -8,7 +8,7 @@
- #include <dt-bindings/leds/common.h>
-
- / {
-- compatible = "radxa,radxa-cm3", "rockchip,rk3566";
-+ compatible = "radxa,cm3", "rockchip,rk3566";
-
- aliases {
- mmc0 = &sdhci;
+++ /dev/null
-From f99a75f11f46a24dabb33e90893eebf61dca0566 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Sun, 2 Jul 2023 20:52:42 +0200
-Subject: [PATCH] arm64: dts: rockchip: minor whitespace cleanup around '='
-
-The DTS code coding style expects exactly one space before and after '='
-sign.
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20230702185242.44421-1-krzysztof.kozlowski@linaro.org
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- .../boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-@@ -137,8 +137,8 @@
-
- &mdio1 {
- rgmii_phy1: ethernet-phy@0 {
-- compatible="ethernet-phy-ieee802.3-c22";
-- reg= <0x0>;
-+ compatible = "ethernet-phy-ieee802.3-c22";
-+ reg = <0x0>;
- };
- };
-
+++ /dev/null
-From 36d9b3ae708e865cdab95692db5a24c5d975383d Mon Sep 17 00:00:00 2001
-From: Dragan Simic <dsimic@manjaro.org>
-Date: Tue, 12 Dec 2023 09:01:39 +0100
-Subject: [PATCH] arm64: dts: rockchip: Add ethernet0 alias to the dts for
- RK3566 boards
-
-Add ethernet0 alias to the board dts files for a few supported RK3566 boards
-that had it missing. Also, remove the ethernet0 alias from one RK3566 SoM
-dtsi file, which doesn't enable the GMAC, and add the ethernet0 alias back to
-the dependent board dts files, which actually enable the GMAC.
-
-Signed-off-by: Dragan Simic <dsimic@manjaro.org>
-Link: https://lore.kernel.org/r/d2a272e0ae0fff0adfab8bb0238243b11d348799.1702368023.git.dsimic@manjaro.org
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
- 1 files changed, 1 insertions(+), 0 deletion(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-@@ -14,6 +14,7 @@
- compatible = "radxa,cm3-io", "radxa,cm3", "rockchip,rk3566";
-
- aliases {
-+ ethernet0 = &gmac1;
- mmc1 = &sdmmc0;
- };
-
+++ /dev/null
-From 2bf2f4d9f673013a58109626b87329310537a611 Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Fri, 9 Dec 2022 18:25:24 +0800
-Subject: [PATCH] arm64: dts: rockchip: Add Radxa CM3I E25
-
-Radxa E25 is a network application carrier board for the Radxa CM3
-Industrial (CM3I) SoM, which is based on the Rockchip RK3568 SoC.
-
-It has the following features:
-
-- MicroSD card socket, on board eMMC flash
-- 2x 2.5GbE Realtek RTL8125B Ethernet transceiver
-- 1x USB Type-C port (Power and Serial console)
-- 1x USB 3.0 OTG port
-- mini PCIe socket (USB or PCIe)
-- ngff PCIe socket (USB or SATA)
-- 1x User LED and 16x RGB LEDs
-- 26-pin expansion header
-
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
-Link: https://lore.kernel.org/r/20221209102524.129367-3-amadeus@jmu.edu.cn
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/Makefile | 1 +
- .../boot/dts/rockchip/rk3568-radxa-cm3i.dtsi | 416 ++++++++++++++++++
- .../boot/dts/rockchip/rk3568-radxa-e25.dts | 229 ++++++++++
- 3 files changed, 646 insertions(+)
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
- create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-
---- a/arch/arm64/boot/dts/rockchip/Makefile
-+++ b/arch/arm64/boot/dts/rockchip/Makefile
-@@ -78,4 +78,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bp
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5c.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb
-+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-radxa-e25.dtb
- dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
-@@ -0,0 +1,416 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/pinctrl/rockchip.h>
-+#include "rk3568.dtsi"
-+
-+/ {
-+ model = "Radxa CM3 Industrial Board";
-+ compatible = "radxa,cm3i", "rockchip,rk3568";
-+
-+ aliases {
-+ mmc0 = &sdhci;
-+ };
-+
-+ chosen {
-+ stdout-path = "serial2:115200n8";
-+ };
-+
-+ gpio-leds {
-+ compatible = "gpio-leds";
-+
-+ led_user: led-0 {
-+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
-+ function = LED_FUNCTION_HEARTBEAT;
-+ color = <LED_COLOR_ID_GREEN>;
-+ linux,default-trigger = "heartbeat";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&led_user_en>;
-+ };
-+ };
-+
-+ pcie30_avdd0v9: pcie30-avdd0v9-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "pcie30_avdd0v9";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+ vin-supply = <&vcc3v3_sys>;
-+ };
-+
-+ pcie30_avdd1v8: pcie30-avdd1v8-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "pcie30_avdd1v8";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ vin-supply = <&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 = <&vcc5v_input>;
-+ };
-+
-+ 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_input>;
-+ };
-+
-+ /* labeled +5v_input in schematic */
-+ vcc5v_input: vcc5v-input-regulator {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc5v_input";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ };
-+};
-+
-+&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>;
-+};
-+
-+&display_subsystem {
-+ status = "disabled";
-+};
-+
-+&gpu {
-+ mali-supply = <&vdd_gpu>;
-+ 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 = <&vcc5v_input>;
-+
-+ 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-cells = <1>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pmic_int>;
-+ rockchip,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-init-microvolt = <900000>;
-+ 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-init-microvolt = <900000>;
-+ 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-init-microvolt = <900000>;
-+ regulator-initial-mode = <0x2>;
-+ regulator-min-microvolt = <500000>;
-+ regulator-max-microvolt = <1350000>;
-+ regulator-ramp-delay = <6001>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc_1v8: DCDC_REG5 {
-+ regulator-name = "vcc_1v8";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vdda0v9_image: LDO_REG1 {
-+ regulator-name = "vdda0v9_image";
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vdda_0v9: LDO_REG2 {
-+ regulator-name = "vdda_0v9";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vdda0v9_pmu: LDO_REG3 {
-+ regulator-name = "vdda0v9_pmu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <900000>;
-+ regulator-max-microvolt = <900000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <900000>;
-+ };
-+ };
-+
-+ vccio_acodec: LDO_REG4 {
-+ regulator-name = "vccio_acodec";
-+ regulator-always-on;
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vccio_sd: LDO_REG5 {
-+ regulator-name = "vccio_sd";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <3300000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc3v3_pmu: LDO_REG6 {
-+ regulator-name = "vcc3v3_pmu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <3300000>;
-+ };
-+ };
-+
-+ vcca_1v8: LDO_REG7 {
-+ regulator-name = "vcca_1v8";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcca1v8_pmu: LDO_REG8 {
-+ regulator-name = "vcca1v8_pmu";
-+ regulator-always-on;
-+ regulator-boot-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-on-in-suspend;
-+ regulator-suspend-microvolt = <1800000>;
-+ };
-+ };
-+
-+ vcca1v8_image: LDO_REG9 {
-+ regulator-name = "vcca1v8_image";
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc_3v3: SWITCH_REG1 {
-+ regulator-name = "vcc_3v3";
-+ regulator-always-on;
-+ regulator-boot-on;
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+
-+ vcc3v3_sd: SWITCH_REG2 {
-+ regulator-name = "vcc3v3_sd";
-+
-+ regulator-state-mem {
-+ regulator-off-in-suspend;
-+ };
-+ };
-+ };
-+ };
-+};
-+
-+&pinctrl {
-+ leds {
-+ led_user_en: led_user_en {
-+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+
-+ pmic {
-+ pmic_int: pmic_int {
-+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
-+ };
-+ };
-+};
-+
-+&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>;
-+ max-frequency = <200000000>;
-+ 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";
-+};
-+
-+&tsadc {
-+ rockchip,hw-tshut-mode = <1>;
-+ rockchip,hw-tshut-polarity = <0>;
-+ status = "okay";
-+};
-+
-+&uart2 {
-+ status = "okay";
-+};
-+
-+&usb2phy0 {
-+ status = "okay";
-+};
-+
-+&usb2phy1 {
-+ status = "okay";
-+};
-+
-+&usb_host0_xhci {
-+ extcon = <&usb2phy0>;
-+};
---- /dev/null
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-@@ -0,0 +1,229 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+
-+/dts-v1/;
-+#include "rk3568-radxa-cm3i.dtsi"
-+
-+/ {
-+ model = "Radxa E25";
-+ compatible = "radxa,e25", "rockchip,rk3568";
-+
-+ aliases {
-+ mmc0 = &sdmmc0;
-+ mmc1 = &sdhci;
-+ };
-+
-+ pwm-leds {
-+ compatible = "pwm-leds-multicolor";
-+
-+ multi-led {
-+ color = <LED_COLOR_ID_RGB>;
-+ max-brightness = <255>;
-+
-+ led-red {
-+ color = <LED_COLOR_ID_RED>;
-+ pwms = <&pwm1 0 1000000 0>;
-+ };
-+
-+ led-green {
-+ color = <LED_COLOR_ID_GREEN>;
-+ pwms = <&pwm2 0 1000000 0>;
-+ };
-+
-+ led-blue {
-+ color = <LED_COLOR_ID_BLUE>;
-+ pwms = <&pwm12 0 1000000 0>;
-+ };
-+ };
-+ };
-+
-+ vbus_typec: vbus-typec-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpio = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&vbus_typec_en>;
-+ regulator-name = "vbus_typec";
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ vin-supply = <&vcc5v0_sys>;
-+ };
-+
-+ vcc3v3_minipcie: vcc3v3-minipcie-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&minipcie_enable_h>;
-+ regulator-name = "vcc3v3_minipcie";
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ vin-supply = <&vcc5v0_sys>;
-+ };
-+
-+ vcc3v3_ngff: vcc3v3-ngff-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&ngffpcie_enable_h>;
-+ regulator-name = "vcc3v3_ngff";
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ vin-supply = <&vcc5v0_sys>;
-+ };
-+
-+ /* actually fed by vcc5v0_sys, dependent
-+ * on pi6c clock generator
-+ */
-+ vcc3v3_pcie30x1: vcc3v3-pcie30x1-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie30x1_enable_h>;
-+ regulator-name = "vcc3v3_pcie30x1";
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ vin-supply = <&vcc3v3_pi6c_05>;
-+ };
-+
-+ vcc3v3_pi6c_05: vcc3v3-pi6c-05-regulator {
-+ compatible = "regulator-fixed";
-+ enable-active-high;
-+ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie_enable_h>;
-+ regulator-name = "vcc3v3_pcie";
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ vin-supply = <&vcc5v0_sys>;
-+ };
-+};
-+
-+&pcie2x1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie20_reset_h>;
-+ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
-+ vpcie3v3-supply = <&vcc3v3_pi6c_05>;
-+ status = "okay";
-+};
-+
-+&pcie30phy {
-+ data-lanes = <1 2>;
-+ status = "okay";
-+};
-+
-+&pcie3x1 {
-+ num-lanes = <1>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie30x1m0_pins>;
-+ reset-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>;
-+ vpcie3v3-supply = <&vcc3v3_pcie30x1>;
-+ status = "okay";
-+};
-+
-+&pcie3x2 {
-+ num-lanes = <1>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pcie30x2_reset_h>;
-+ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
-+ vpcie3v3-supply = <&vcc3v3_pi6c_05>;
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ pcie {
-+ pcie20_reset_h: pcie20-reset-h {
-+ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ pcie30x1_enable_h: pcie30x1-enable-h {
-+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ pcie30x2_reset_h: pcie30x2-reset-h {
-+ rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ pcie_enable_h: pcie-enable-h {
-+ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+
-+ usb {
-+ minipcie_enable_h: minipcie-enable-h {
-+ rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ ngffpcie_enable_h: ngffpcie-enable-h {
-+ rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+
-+ vbus_typec_en: vbus_typec_en {
-+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
-+ };
-+ };
-+};
-+
-+&pwm1 {
-+ status = "okay";
-+};
-+
-+&pwm2 {
-+ status = "okay";
-+};
-+
-+&pwm12 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm12m1_pins>;
-+ status = "okay";
-+};
-+
-+&sdmmc0 {
-+ bus-width = <4>;
-+ cap-sd-highspeed;
-+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
-+ /* Also used in pcie30x1_clkreqnm0 */
-+ disable-wp;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd>;
-+ sd-uhs-sdr104;
-+ vmmc-supply = <&vcc3v3_sd>;
-+ vqmmc-supply = <&vccio_sd>;
-+ status = "okay";
-+};
-+
-+&usb_host0_ehci {
-+ status = "okay";
-+};
-+
-+&usb_host0_ohci {
-+ status = "okay";
-+};
-+
-+&usb_host0_xhci {
-+ status = "okay";
-+};
-+
-+&usb_host1_ehci {
-+ status = "okay";
-+};
-+
-+&usb_host1_ohci {
-+ status = "okay";
-+};
-+
-+&usb2phy0_otg {
-+ phy-supply = <&vbus_typec>;
-+ status = "okay";
-+};
-+
-+&usb2phy1_host {
-+ phy-supply = <&vcc3v3_minipcie>;
-+ status = "okay";
-+};
-+
-+&usb2phy1_otg {
-+ phy-supply = <&vcc3v3_ngff>;
-+ status = "okay";
-+};
+++ /dev/null
-From c80992abd2877590059e9cb254213c16824e2106 Mon Sep 17 00:00:00 2001
-From: Jagan Teki <jagan@amarulasolutions.com>
-Date: Wed, 18 Jan 2023 13:34:53 +0530
-Subject: [PATCH] arm64: dts: rockchip: Update eMMC, SD aliases for Radxa SoM
- boards
-
-Radxa has produced Compute Modules like RK3399pro VMARC and CM3i with
-onboarding eMMC flash, so the eMMC is the primary MMC device.
-
-On the other hand, Rockchip boot orders start from eMMC from an MMC
-device perspective.
-
-Mark, the eMMC has mmc0 to satisfy the above two conditions.
-
-Reported-by: FUKAUMI Naoki <naoki@radxa.com>
-Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
-Link: https://lore.kernel.org/r/20230118080454.11643-1-jagan@amarulasolutions.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi | 4 ++--
- arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts | 3 +--
- 2 files changed, 3 insertions(+), 4 deletions(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
-+++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
-@@ -13,8 +13,8 @@
- compatible = "vamrs,rk3399pro-vmarc-som", "rockchip,rk3399pro";
-
- aliases {
-- mmc0 = &sdmmc;
-- mmc1 = &sdhci;
-+ mmc0 = &sdhci;
-+ mmc1 = &sdmmc;
- };
-
- vcc3v3_pcie: vcc-pcie-regulator {
---- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-@@ -8,8 +8,7 @@
- compatible = "radxa,e25", "rockchip,rk3568";
-
- aliases {
-- mmc0 = &sdmmc0;
-- mmc1 = &sdhci;
-+ mmc1 = &sdmmc0;
- };
-
- pwm-leds {
+++ /dev/null
-From c4d2b02d63ee38b381fbc886c02eecfec4f981cc Mon Sep 17 00:00:00 2001
-From: Jagan Teki <jagan@amarulasolutions.com>
-Date: Mon, 23 Jan 2023 12:46:51 +0530
-Subject: [PATCH] arm64: dts: rockchip: Add missing CM3i fallback compatible
- for Radxa E25
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-In order to function the Radxa E25 Carrier board, it is mandatory to
-mount the Radxa CM3i module.
-
-Add Radxa CM3i compatible as fallback compatible to string to satisfy
-the Module and Carrier board topology.
-
-Fixes: 2bf2f4d9f673 ("arm64: dts: rockchip: Add Radxa CM3I E25")
-Cc: Chukun Pan <amadeus@jmu.edu.cn>
-Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
-Link: https://lore.kernel.org/r/20230123071654.73139-2-jagan@amarulasolutions.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-@@ -5,7 +5,7 @@
-
- / {
- model = "Radxa E25";
-- compatible = "radxa,e25", "rockchip,rk3568";
-+ compatible = "radxa,e25", "radxa,cm3i", "rockchip,rk3568";
-
- aliases {
- mmc1 = &sdmmc0;
+++ /dev/null
-From ef9134d9bbce071c9e4ebdcbb6f8fb1a5dd0a67e Mon Sep 17 00:00:00 2001
-From: Jagan Teki <jagan@amarulasolutions.com>
-Date: Mon, 23 Jan 2023 12:46:53 +0530
-Subject: [PATCH] arm64: dts: rockchip: Correct the model name for Radxa E25
-
-Radxa E25 is a Carrier board, so update the model name for Radxa E25
-as suggested by the Radxa website.
-
-Fixes: 2bf2f4d9f673 ("arm64: dts: rockchip: Add Radxa CM3I E25")
-Cc: Chukun Pan <amadeus@jmu.edu.cn>
-Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
-Link: https://lore.kernel.org/r/20230123071654.73139-4-jagan@amarulasolutions.com
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-@@ -4,7 +4,7 @@
- #include "rk3568-radxa-cm3i.dtsi"
-
- / {
-- model = "Radxa E25";
-+ model = "Radxa E25 Carrier Board";
- compatible = "radxa,e25", "radxa,cm3i", "rockchip,rk3568";
-
- aliases {
+++ /dev/null
-From a87852e37f782257ebc57cc44a0d3fbf806471f6 Mon Sep 17 00:00:00 2001
-From: Jonas Karlman <jonas@kwiboo.se>
-Date: Mon, 24 Jul 2023 14:52:16 +0000
-Subject: [PATCH] arm64: dts: rockchip: Fix PCIe regulators on Radxa E25
-
-Despite its name, the regulator vcc3v3_pcie30x1 has nothing to do with
-pcie30x1. Instead, it supply power to VBAT1-5 on the M.2 KEY B port as
-seen on page 8 of the schematic [1].
-
-pcie30x1 is used for the mini PCIe slot, and as seen on page 9 the
-vcc3v3_minipcie regulator is instead related to pcie30x1.
-
-The M.2 KEY B port can be used for WWAN USB2 modules or SATA drives.
-
-Use correct regulator vcc3v3_minipcie for pcie30x1.
-
-[1] https://dl.radxa.com/cm3p/e25/radxa-e25-v1.4-sch.pdf
-
-Fixes: 2bf2f4d9f673 ("arm64: dts: rockchip: Add Radxa CM3I E25")
-Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
-Link: https://lore.kernel.org/r/20230724145213.3833099-1-jonas@kwiboo.se
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- .../arm64/boot/dts/rockchip/rk3568-radxa-e25.dts | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-@@ -47,6 +47,9 @@
- vin-supply = <&vcc5v0_sys>;
- };
-
-+ /* actually fed by vcc5v0_sys, dependent
-+ * on pi6c clock generator
-+ */
- vcc3v3_minipcie: vcc3v3-minipcie-regulator {
- compatible = "regulator-fixed";
- enable-active-high;
-@@ -54,9 +57,9 @@
- pinctrl-names = "default";
- pinctrl-0 = <&minipcie_enable_h>;
- regulator-name = "vcc3v3_minipcie";
-- regulator-min-microvolt = <5000000>;
-- regulator-max-microvolt = <5000000>;
-- vin-supply = <&vcc5v0_sys>;
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ vin-supply = <&vcc3v3_pi6c_05>;
- };
-
- vcc3v3_ngff: vcc3v3-ngff-regulator {
-@@ -71,9 +74,6 @@
- vin-supply = <&vcc5v0_sys>;
- };
-
-- /* actually fed by vcc5v0_sys, dependent
-- * on pi6c clock generator
-- */
- vcc3v3_pcie30x1: vcc3v3-pcie30x1-regulator {
- compatible = "regulator-fixed";
- enable-active-high;
-@@ -83,7 +83,7 @@
- regulator-name = "vcc3v3_pcie30x1";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
-- vin-supply = <&vcc3v3_pi6c_05>;
-+ vin-supply = <&vcc5v0_sys>;
- };
-
- vcc3v3_pi6c_05: vcc3v3-pi6c-05-regulator {
-@@ -117,7 +117,7 @@
- pinctrl-names = "default";
- pinctrl-0 = <&pcie30x1m0_pins>;
- reset-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>;
-- vpcie3v3-supply = <&vcc3v3_pcie30x1>;
-+ vpcie3v3-supply = <&vcc3v3_minipcie>;
- status = "okay";
- };
-
+++ /dev/null
-From 2bdfe84fbd57a4ed9fd65a67210442559ce078f0 Mon Sep 17 00:00:00 2001
-From: Jonas Karlman <jonas@kwiboo.se>
-Date: Mon, 24 Jul 2023 14:52:16 +0000
-Subject: [PATCH] arm64: dts: rockchip: Enable SATA on Radxa E25
-
-The M.2 KEY B port can be used for WWAN USB2 modules or SATA drives.
-
-Enable sata1 node to fix use of SATA drives on the M.2 slot.
-
-Fixes: 2bf2f4d9f673 ("arm64: dts: rockchip: Add Radxa CM3I E25")
-Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
-Link: https://lore.kernel.org/r/20230724145213.3833099-1-jonas@kwiboo.se
-Signed-off-by: Heiko Stuebner <heiko@sntech.de>
----
- arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-e25.dts
-@@ -99,6 +99,10 @@
- };
- };
-
-+&combphy1 {
-+ phy-supply = <&vcc3v3_pcie30x1>;
-+};
-+
- &pcie2x1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie20_reset_h>;
-@@ -178,6 +182,10 @@
- status = "okay";
- };
-
-+&sata1 {
-+ status = "okay";
-+};
-+
- &sdmmc0 {
- bus-width = <4>;
- cap-sd-highspeed;
+++ /dev/null
-From 6731d2c9039fbe1ecf21915eab3acee0a999508a Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Fri, 10 Jul 2020 21:38:20 +0200
-Subject: [PATCH] rockchip: use system LED for OpenWrt
-
-Use the SYS LED on the casing for showing system status.
-
-This patch is kept separate from the NanoPi R2S support patch, as i plan
-on submitting the device support upstream.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
-@@ -6,6 +6,7 @@
- /dts-v1/;
-
- #include <dt-bindings/input/input.h>
-+#include <dt-bindings/leds/common.h>
- #include <dt-bindings/gpio/gpio.h>
- #include "rk3328.dtsi"
-
-@@ -16,6 +17,11 @@
- aliases {
- ethernet1 = &rtl8153;
- mmc0 = &sdmmc;
-+
-+ led-boot = &sys_led;
-+ led-failsafe = &sys_led;
-+ led-running = &sys_led;
-+ led-upgrade = &sys_led;
- };
-
- chosen {
-@@ -48,19 +54,22 @@
- pinctrl-names = "default";
-
- lan_led: led-0 {
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_LAN;
- gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
-- label = "nanopi-r2s:green:lan";
- };
-
- sys_led: led-1 {
-+ color = <LED_COLOR_ID_RED>;
-+ function = LED_FUNCTION_STATUS;
- gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
-- label = "nanopi-r2s:red:sys";
- default-state = "on";
- };
-
- wan_led: led-2 {
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_WAN;
- gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>;
-- label = "nanopi-r2s:green:wan";
- };
- };
-
---- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
-@@ -13,6 +13,11 @@
- aliases {
- mmc0 = &sdmmc;
- mmc1 = &emmc;
-+
-+ led-boot = &power_led;
-+ led-failsafe = &power_led;
-+ led-running = &power_led;
-+ led-upgrade = &power_led;
- };
-
- chosen {
+++ /dev/null
-From 2795c8b31a686bdb8338f9404d18ef7a154f0d75 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 26 Jul 2020 13:32:59 +0200
-Subject: [PATCH] arm64: rockchip: add OF node for USB eth on NanoPi R2S
-
-This adds the OF node for the USB3 ethernet adapter on the FriendlyARM
-NanoPi R2S. Add the correct value for the RTL8153 LED configuration
-register to match the blink behavior of the other port on the device.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 7 +++++++
- 1 file changed, 1 insertions(+)
-
---- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
-@@ -406,6 +406,7 @@
- rtl8153: device@2 {
- compatible = "usbbda,8153";
- reg = <2>;
-+ realtek,led-data = <0x87>;
- };
- };
-
+++ /dev/null
-From: David Bauer <mail@david-bauer.net>
-Subject: arm64: dts: rockchip: disable UHS modes for NanoPi R4S
-
-The NanoPi R4S leaves the SD card in 1.8V signalling when rebooting
-while U-Boot requires the card to be in 3.3V mode.
-
-Remove UHS support from the SD controller so the card remains in 3.3V
-mode. This reduces transfer speeds but ensures a reboot whether from
-userspace or following a kernel panic is always working.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
---- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
-@@ -335,7 +335,6 @@
- sd-uhs-sdr12;
- sd-uhs-sdr25;
- sd-uhs-sdr50;
-- sd-uhs-sdr104;
- vmmc-supply = <&vcc_sd>;
- vqmmc-supply = <&vcc_sdio>;
- status = "okay";
---- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
-@@ -112,6 +112,11 @@
- status = "disabled";
- };
-
-+&sdmmc {
-+ /delete-property/ sd-uhs-sdr104;
-+ cap-sd-highspeed;
-+};
-+
- &u2phy0_host {
- phy-supply = <&vdd_5v>;
- };
+++ /dev/null
---- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
-@@ -19,6 +19,13 @@
- model = "FriendlyElec NanoPi R4S";
- compatible = "friendlyarm,nanopi-r4s", "rockchip,rk3399";
-
-+ aliases {
-+ led-boot = &sys_led;
-+ led-failsafe = &sys_led;
-+ led-running = &sys_led;
-+ led-upgrade = &sys_led;
-+ };
-+
- /delete-node/ display-subsystem;
-
- gpio-leds {
+++ /dev/null
-From d2166e3b3680bd2b206aebf1e1ce4c0d346f3c50 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Fri, 19 May 2023 12:10:52 +0800
-Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Orange Pi R1
- Plus
-
-Add OpenWrt's LED aliases for showing system status.
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
----
- .../dts/rockchip/rk3328-orangepi-r1-plus.dts | 17 +++++++++--------
- 1 file changed, 9 insertions(+), 8 deletions(-)
-
---- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
-@@ -17,6 +17,11 @@
- aliases {
- ethernet1 = &rtl8153;
- mmc0 = &sdmmc;
-+
-+ led-boot = &status_led;
-+ led-failsafe = &status_led;
-+ led-running = &status_led;
-+ led-upgrade = &status_led;
- };
-
- chosen {
-@@ -41,11 +46,10 @@
- gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
- };
-
-- led-1 {
-+ status_led: led-1 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
-- linux,default-trigger = "heartbeat";
- };
-
- led-2 {
+++ /dev/null
-From b46a530d12ada422b9d5b2b97059e0d3ed950b40 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Fri, 19 May 2023 12:38:04 +0800
-Subject: [PATCH] arm64: dts: rockchip: add LED configuration to Orange Pi R1
- Plus
-
-Add the correct value for the RTL8153 LED configuration register to
-match the blink behavior of the other port on the device.
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
----
- arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
-@@ -365,6 +365,7 @@
- rtl8153: device@2 {
- compatible = "usbbda,8153";
- reg = <2>;
-+ realtek,led-data = <0x87>;
- };
- };
-
+++ /dev/null
---- a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
-@@ -15,6 +15,13 @@
- model = "FriendlyElec NanoPC-T4";
- compatible = "friendlyarm,nanopc-t4", "rockchip,rk3399";
-
-+ aliases {
-+ led-boot = &status_led;
-+ led-failsafe = &status_led;
-+ led-running = &status_led;
-+ led-upgrade = &status_led;
-+ };
-+
- vcc12v0_sys: vcc12v0-sys {
- compatible = "regulator-fixed";
- regulator-always-on;
+++ /dev/null
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tianling Shen <cnsztl@gmail.com>
-Date: Tue Jun 20 16:45:27 2023 +0800
-Subject: [PATCH] arm64: dts: rockchip: Update LED properties for NanoPi R5
- series
-
-Add OpenWrt's LED aliases for showing system status.
-
-Signed-off-by: Tianling Shen <cnsztl@gmail.com>
----
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5c.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5c.dts
-@@ -40,7 +40,6 @@
- power_led: led-power {
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_POWER;
-- linux,default-trigger = "heartbeat";
- gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_HIGH>;
- };
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
-@@ -39,7 +39,6 @@
- power_led: led-power {
- color = <LED_COLOR_ID_RED>;
- function = LED_FUNCTION_POWER;
-- linux,default-trigger = "heartbeat";
- gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
- };
-
---- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
-+++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
-@@ -18,6 +18,11 @@
- aliases {
- mmc0 = &sdmmc0;
- mmc1 = &sdhci;
-+
-+ led-boot = &power_led;
-+ led-failsafe = &power_led;
-+ led-running = &power_led;
-+ led-upgrade = &power_led;
- };
-
- chosen: chosen {
+++ /dev/null
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Marius Durbaca <mariusd84@gmail.com>
-Date: Tue Feb 20 15:05:27 2024 +0200
-Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Radxa
-CM3 IO board
-
-Add OpenWrt's LED aliases for showing system status.
-
-Suggested-by: Tianling Shen <cnsztl@immortalwrt.org>
-Signed-off-by: Marius Durbaca <mariusd84@gmail.com>
----
-
---- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
-@@ -16,6 +16,10 @@
- aliases {
- ethernet0 = &gmac1;
- mmc1 = &sdmmc0;
-+ led-boot = &status_led;
-+ led-failsafe = &status_led;
-+ led-running = &status_led;
-+ led-upgrade = &status_led;
- };
-
- chosen: chosen {
---- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
-+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
-@@ -17,7 +17,7 @@
- leds {
- compatible = "gpio-leds";
-
-- led-0 {
-+ status_led: led-0 {
- gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_STATUS;
+++ /dev/null
-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 {
--- /dev/null
+From 36d9b3ae708e865cdab95692db5a24c5d975383d Mon Sep 17 00:00:00 2001
+From: Dragan Simic <dsimic@manjaro.org>
+Date: Tue, 12 Dec 2023 09:01:39 +0100
+Subject: [PATCH] arm64: dts: rockchip: Add ethernet0 alias to the dts for
+ RK3566 boards
+
+Add ethernet0 alias to the board dts files for a few supported RK3566 boards
+that had it missing. Also, remove the ethernet0 alias from one RK3566 SoM
+dtsi file, which doesn't enable the GMAC, and add the ethernet0 alias back to
+the dependent board dts files, which actually enable the GMAC.
+
+Signed-off-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/d2a272e0ae0fff0adfab8bb0238243b11d348799.1702368023.git.dsimic@manjaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
+ 1 files changed, 1 insertions(+), 0 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
+@@ -14,6 +14,7 @@
+ compatible = "radxa,cm3-io", "radxa,cm3", "rockchip,rk3566";
+
+ aliases {
++ ethernet0 = &gmac1;
+ mmc1 = &sdmmc0;
+ };
+
--- /dev/null
+From 437644753208092f642b7669c69da606aa07dfb4 Mon Sep 17 00:00:00 2001
+From: Tim Lunn <tim@feathertop.org>
+Date: Wed, 14 Feb 2024 15:07:30 +1100
+Subject: [PATCH] arm64: dts: rockchip: adjust vendor on Banana Pi R2 Pro board
+
+Adjust compatible string to match the board vendor of Sinovoip
+
+Signed-off-by: Tim Lunn <tim@feathertop.org>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20240214040731.3069111-4-tim@feathertop.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
+@@ -13,7 +13,7 @@
+
+ / {
+ model = "Bananapi-R2 Pro (RK3568) DDR4 Board";
+- compatible = "rockchip,rk3568-bpi-r2pro", "rockchip,rk3568";
++ compatible = "sinovoip,rk3568-bpi-r2pro", "rockchip,rk3568";
+
+ aliases {
+ ethernet0 = &gmac0;
--- /dev/null
+From 6731d2c9039fbe1ecf21915eab3acee0a999508a Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+Date: Fri, 10 Jul 2020 21:38:20 +0200
+Subject: [PATCH] rockchip: use system LED for OpenWrt
+
+Use the SYS LED on the casing for showing system status.
+
+This patch is kept separate from the NanoPi R2S support patch, as i plan
+on submitting the device support upstream.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+---
+ arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
+@@ -6,6 +6,7 @@
+ /dts-v1/;
+
+ #include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
+ #include <dt-bindings/gpio/gpio.h>
+ #include "rk3328.dtsi"
+
+@@ -16,6 +17,11 @@
+ aliases {
+ ethernet1 = &rtl8153;
+ mmc0 = &sdmmc;
++
++ led-boot = &sys_led;
++ led-failsafe = &sys_led;
++ led-running = &sys_led;
++ led-upgrade = &sys_led;
+ };
+
+ chosen {
+@@ -48,19 +54,22 @@
+ pinctrl-names = "default";
+
+ lan_led: led-0 {
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_LAN;
+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+- label = "nanopi-r2s:green:lan";
+ };
+
+ sys_led: led-1 {
++ color = <LED_COLOR_ID_RED>;
++ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
+- label = "nanopi-r2s:red:sys";
+ default-state = "on";
+ };
+
+ wan_led: led-2 {
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_WAN;
+ gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>;
+- label = "nanopi-r2s:green:wan";
+ };
+ };
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
+@@ -13,6 +13,11 @@
+ aliases {
+ mmc0 = &sdmmc;
+ mmc1 = &emmc;
++
++ led-boot = &power_led;
++ led-failsafe = &power_led;
++ led-running = &power_led;
++ led-upgrade = &power_led;
+ };
+
+ chosen {
--- /dev/null
+From 2795c8b31a686bdb8338f9404d18ef7a154f0d75 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+Date: Sun, 26 Jul 2020 13:32:59 +0200
+Subject: [PATCH] arm64: rockchip: add OF node for USB eth on NanoPi R2S
+
+This adds the OF node for the USB3 ethernet adapter on the FriendlyARM
+NanoPi R2S. Add the correct value for the RTL8153 LED configuration
+register to match the blink behavior of the other port on the device.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+---
+ arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts | 7 +++++++
+ 1 file changed, 1 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts
+@@ -406,6 +406,7 @@
+ rtl8153: device@2 {
+ compatible = "usbbda,8153";
+ reg = <2>;
++ realtek,led-data = <0x87>;
+ };
+ };
+
--- /dev/null
+From: David Bauer <mail@david-bauer.net>
+Subject: arm64: dts: rockchip: disable UHS modes for NanoPi R4S
+
+The NanoPi R4S leaves the SD card in 1.8V signalling when rebooting
+while U-Boot requires the card to be in 3.3V mode.
+
+Remove UHS support from the SD controller so the card remains in 3.3V
+mode. This reduces transfer speeds but ensures a reboot whether from
+userspace or following a kernel panic is always working.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
+@@ -335,7 +335,6 @@
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+- sd-uhs-sdr104;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vcc_sdio>;
+ status = "okay";
+--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
+@@ -112,6 +112,11 @@
+ status = "disabled";
+ };
+
++&sdmmc {
++ /delete-property/ sd-uhs-sdr104;
++ cap-sd-highspeed;
++};
++
+ &u2phy0_host {
+ phy-supply = <&vdd_5v>;
+ };
--- /dev/null
+--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
+@@ -19,6 +19,13 @@
+ model = "FriendlyElec NanoPi R4S";
+ compatible = "friendlyarm,nanopi-r4s", "rockchip,rk3399";
+
++ aliases {
++ led-boot = &sys_led;
++ led-failsafe = &sys_led;
++ led-running = &sys_led;
++ led-upgrade = &sys_led;
++ };
++
+ /delete-node/ display-subsystem;
+
+ gpio-leds {
--- /dev/null
+From d2166e3b3680bd2b206aebf1e1ce4c0d346f3c50 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Fri, 19 May 2023 12:10:52 +0800
+Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Orange Pi R1
+ Plus
+
+Add OpenWrt's LED aliases for showing system status.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+ .../dts/rockchip/rk3328-orangepi-r1-plus.dts | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
+@@ -17,6 +17,11 @@
+ aliases {
+ ethernet1 = &rtl8153;
+ mmc0 = &sdmmc;
++
++ led-boot = &status_led;
++ led-failsafe = &status_led;
++ led-running = &status_led;
++ led-upgrade = &status_led;
+ };
+
+ chosen {
+@@ -41,11 +46,10 @@
+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+ };
+
+- led-1 {
++ status_led: led-1 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+ };
+
+ led-2 {
--- /dev/null
+From b46a530d12ada422b9d5b2b97059e0d3ed950b40 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Fri, 19 May 2023 12:38:04 +0800
+Subject: [PATCH] arm64: dts: rockchip: add LED configuration to Orange Pi R1
+ Plus
+
+Add the correct value for the RTL8153 LED configuration register to
+match the blink behavior of the other port on the device.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+ arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus.dts
+@@ -365,6 +365,7 @@
+ rtl8153: device@2 {
+ compatible = "usbbda,8153";
+ reg = <2>;
++ realtek,led-data = <0x87>;
+ };
+ };
+
--- /dev/null
+--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
+@@ -15,6 +15,13 @@
+ model = "FriendlyElec NanoPC-T4";
+ compatible = "friendlyarm,nanopc-t4", "rockchip,rk3399";
+
++ aliases {
++ led-boot = &status_led;
++ led-failsafe = &status_led;
++ led-running = &status_led;
++ led-upgrade = &status_led;
++ };
++
+ vcc12v0_sys: vcc12v0-sys {
+ compatible = "regulator-fixed";
+ regulator-always-on;
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Tue Jun 20 16:45:27 2023 +0800
+Subject: [PATCH] arm64: dts: rockchip: Update LED properties for NanoPi R5
+ series
+
+Add OpenWrt's LED aliases for showing system status.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5c.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5c.dts
+@@ -40,7 +40,6 @@
+ power_led: led-power {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_POWER;
+- linux,default-trigger = "heartbeat";
+ gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_HIGH>;
+ };
+
+--- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dts
+@@ -39,7 +39,6 @@
+ power_led: led-power {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_POWER;
+- linux,default-trigger = "heartbeat";
+ gpios = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
+ };
+
+--- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
+@@ -18,6 +18,11 @@
+ aliases {
+ mmc0 = &sdmmc0;
+ mmc1 = &sdhci;
++
++ led-boot = &power_led;
++ led-failsafe = &power_led;
++ led-running = &power_led;
++ led-upgrade = &power_led;
+ };
+
+ chosen: chosen {
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Marius Durbaca <mariusd84@gmail.com>
+Date: Tue Feb 20 15:05:27 2024 +0200
+Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Radxa
+CM3 IO board
+
+Add OpenWrt's LED aliases for showing system status.
+
+Suggested-by: Tianling Shen <cnsztl@immortalwrt.org>
+Signed-off-by: Marius Durbaca <mariusd84@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
+@@ -16,6 +16,10 @@
+ aliases {
+ ethernet0 = &gmac1;
+ mmc1 = &sdmmc0;
++ led-boot = &status_led;
++ led-failsafe = &status_led;
++ led-running = &status_led;
++ led-upgrade = &status_led;
+ };
+
+ chosen: chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
+@@ -17,7 +17,7 @@
+ leds {
+ compatible = "gpio-leds";
+
+- led-0 {
++ status_led: led-0 {
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
--- /dev/null
+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 {
--- /dev/null
+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");
--- /dev/null
+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
+@@ -1807,6 +1807,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>;
KERNELNAME:=Image dtbs
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
+++ /dev/null
-CONFIG_64BIT=y
-CONFIG_ARCH_CLOCKSOURCE_INIT=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=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_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_STACKWALK=y
-CONFIG_ARCH_WANTS_THP_SWAP=y
-CONFIG_ASN1=y
-CONFIG_ASSOCIATIVE_ARRAY=y
-CONFIG_ATA=y
-CONFIG_ATA_VERBOSE_ERROR=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CAVIUM_PTP=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
-CONFIG_CLK_SIFIVE=y
-CONFIG_CLK_SIFIVE_PRCI=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_COMPAT_BRK=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_COREDUMP=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_CPU_ISOLATION=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CRC7=y
-CONFIG_CRC_ITU_T=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_RSA=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_EDAC=y
-# CONFIG_EDAC_DEBUG is not set
-CONFIG_EDAC_LEGACY_SYSFS=y
-CONFIG_EDAC_SIFIVE=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EFI=y
-CONFIG_EFIVAR_FS=m
-# 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 is not set
-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_ELF_CORE=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_FAILOVER=y
-CONFIG_FAT_FS=y
-CONFIG_FHANDLE=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_FRAME_POINTER=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_INJECTION=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_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_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_CDEV_V1=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_SIFIVE=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HID=y
-CONFIG_HID_GENERIC=y
-CONFIG_HOTPLUG_PCI=y
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-CONFIG_HOTPLUG_PCI_PCIE=y
-CONFIG_HOTPLUG_PCI_SHPC=y
-CONFIG_HVC_DRIVER=y
-CONFIG_HVC_RISCV_SBI=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_OCORES=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-# CONFIG_IOMMU_DEBUGFS is not set
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_IO_URING=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_KALLSYMS=y
-CONFIG_KEYS=y
-CONFIG_LEDS_PWM=y
-CONFIG_LEDS_TRIGGER_DISK=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-CONFIG_LIBFDT=y
-CONFIG_LOCALVERSION_AUTO=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_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MICROSEMI_PHY=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_CADENCE=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMC_SPI=y
-CONFIG_MMIOWB=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MODULE_SECTIONS=y
-CONFIG_MPILIB=y
-CONFIG_MQ_IOSCHED_DEADLINE=y
-CONFIG_MQ_IOSCHED_KYBER=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_NET_FAILOVER=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NONPORTABLE is not set
-CONFIG_NR_CPUS=8
-CONFIG_NVMEM=y
-CONFIG_NVMEM_SYSFS=y
-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_OID_REGISTRY=y
-CONFIG_PADATA=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_PCIEAER=y
-CONFIG_PCIEAER_INJECT=m
-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_DPC=y
-CONFIG_PCIE_DW=y
-CONFIG_PCIE_DW_HOST=y
-CONFIG_PCIE_ECRC=y
-CONFIG_PCIE_FU740=y
-CONFIG_PCIE_PTM=y
-CONFIG_PCIE_XILINX=y
-CONFIG_PCI_DEBUG=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_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCI_SW_SWITCHTEC=y
-CONFIG_PGTABLE_LEVELS=5
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PORTABLE=y
-CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_RESET_GPIO_RESTART=y
-CONFIG_POWER_RESET_RESTART=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_RESET_SYSCON_POWEROFF=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_SIFIVE=y
-CONFIG_PWM_SYSFS=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_RCU_TRACE=y
-CONFIG_RD_GZIP=y
-CONFIG_REALTEK_PHY=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-# CONFIG_RESET_ATTACK_MITIGATION is not set
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_SIMPLE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RISCV=y
-CONFIG_RISCV_ALTERNATIVE=y
-# CONFIG_RISCV_BOOT_SPINWAIT is not set
-CONFIG_RISCV_DMA_NONCOHERENT=y
-CONFIG_RISCV_INTC=y
-CONFIG_RISCV_ISA_C=y
-CONFIG_RISCV_ISA_SVPBMT=y
-CONFIG_RISCV_ISA_ZICBOM=y
-CONFIG_RISCV_SBI=y
-CONFIG_RISCV_SBI_V01=y
-CONFIG_RISCV_TIMER=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_EFI is not set
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCHED_DEBUG=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_EXAR=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-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_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SG_POOL=y
-CONFIG_SIFIVE_CCACHE=y
-CONFIG_SIFIVE_PLIC=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-# CONFIG_SOC_MICROCHIP_POLARFIRE is not set
-CONFIG_SOC_SIFIVE=y
-# CONFIG_SOC_STARFIVE is not set
-# CONFIG_SOC_VIRT is not set
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_SIFIVE=y
-CONFIG_SRCU=y
-CONFIG_STACKTRACE=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-# CONFIG_SYSFB_SIMPLEFB is not set
-CONFIG_THREAD_INFO_IN_TASK=y
-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_TRACE_CLOCK=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_TUNE_GENERIC=y
-CONFIG_UCS2_STRING=y
-CONFIG_UEVENT_HELPER_PATH=""
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-CONFIG_USB_EHCI_PCI=y
-CONFIG_USB_HID=y
-CONFIG_USB_NET_DRIVERS=y
-CONFIG_USB_PCI=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-# CONFIG_USB_UHCI_HCD is not set
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PCI=y
-# CONFIG_USB_XHCI_PLATFORM is not set
-CONFIG_VFAT_FS=y
-CONFIG_VGA_ARB=y
-CONFIG_VGA_ARB_MAX_GPUS=16
-CONFIG_VMAP_STACK=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
+++ /dev/null
-From ab5c8f5492cce16ff2104393e2f1fa64a3ff6e88 Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Wed, 17 Feb 2021 06:06:14 -0800
-Subject: [PATCH 1/7] riscv: sifive: fu740: cpu{1,2,3,4} set compatible to
- sifive,u74-mc
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
-@@ -39,7 +39,7 @@
- };
- };
- cpu1: cpu@1 {
-- compatible = "sifive,bullet0", "riscv";
-+ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
- d-cache-block-size = <64>;
- d-cache-sets = <64>;
- d-cache-size = <32768>;
-@@ -63,7 +63,7 @@
- };
- };
- cpu2: cpu@2 {
-- compatible = "sifive,bullet0", "riscv";
-+ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
- d-cache-block-size = <64>;
- d-cache-sets = <64>;
- d-cache-size = <32768>;
-@@ -87,7 +87,7 @@
- };
- };
- cpu3: cpu@3 {
-- compatible = "sifive,bullet0", "riscv";
-+ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
- d-cache-block-size = <64>;
- d-cache-sets = <64>;
- d-cache-size = <32768>;
-@@ -111,7 +111,7 @@
- };
- };
- cpu4: cpu@4 {
-- compatible = "sifive,bullet0", "riscv";
-+ compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
- d-cache-block-size = <64>;
- d-cache-sets = <64>;
- d-cache-size = <32768>;
+++ /dev/null
-From 14ede57943bc4209755d08daf93ac7be967d7fbe Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Mon, 13 Sep 2021 02:18:30 -0700
-Subject: [PATCH 4/7] riscv: sifive: unmatched: add gpio-poweroff node
-
-Add gpio-poweroff node to allow powering off the system.
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
-@@ -86,6 +86,11 @@
- };
- };
- };
-+
-+ gpio-poweroff {
-+ compatible = "gpio-poweroff";
-+ gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
-+ };
- };
-
- &uart0 {
+++ /dev/null
-From d3cf2859a056273400fbdf9d389b75750ff6ca5e Mon Sep 17 00:00:00 2001
-From: David Abdurachmanov <david.abdurachmanov@sifive.com>
-Date: Fri, 14 May 2021 05:27:51 -0700
-Subject: [PATCH 6/7] riscv: sifive: unleashed: define opp table (cpufreq)
-
-Source: https://github.com/sifive/riscv-linux/commits/dev/paulw/cpufreq-dt-aloe-v5.3-rc4
-
-Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
----
- arch/riscv/Kconfig | 8 +++++
- arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 5 ++++
- .../riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 34 ++++++++++++++++++++++
- 3 files changed, 47 insertions(+)
-
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -711,6 +711,14 @@ config PORTABLE
- select OF
- select MMU
-
-+menu "CPU Power Management"
-+
-+source "drivers/cpuidle/Kconfig"
-+
-+source "drivers/cpufreq/Kconfig"
-+
-+endmenu
-+
- menu "Power management options"
-
- source "kernel/power/Kconfig"
---- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
-+++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
-@@ -30,6 +30,7 @@
- i-cache-size = <16384>;
- reg = <0>;
- riscv,isa = "rv64imac";
-+ clocks = <&prci FU540_PRCI_CLK_COREPLL>;
- status = "disabled";
- cpu0_intc: interrupt-controller {
- #interrupt-cells = <1>;
-@@ -54,6 +55,7 @@
- reg = <1>;
- riscv,isa = "rv64imafdc";
- tlb-split;
-+ clocks = <&prci FU540_PRCI_CLK_COREPLL>;
- next-level-cache = <&l2cache>;
- cpu1_intc: interrupt-controller {
- #interrupt-cells = <1>;
-@@ -78,6 +80,7 @@
- reg = <2>;
- riscv,isa = "rv64imafdc";
- tlb-split;
-+ clocks = <&prci FU540_PRCI_CLK_COREPLL>;
- next-level-cache = <&l2cache>;
- cpu2_intc: interrupt-controller {
- #interrupt-cells = <1>;
-@@ -102,6 +105,7 @@
- reg = <3>;
- riscv,isa = "rv64imafdc";
- tlb-split;
-+ clocks = <&prci FU540_PRCI_CLK_COREPLL>;
- next-level-cache = <&l2cache>;
- cpu3_intc: interrupt-controller {
- #interrupt-cells = <1>;
-@@ -126,6 +130,7 @@
- reg = <4>;
- riscv,isa = "rv64imafdc";
- tlb-split;
-+ clocks = <&prci FU540_PRCI_CLK_COREPLL>;
- next-level-cache = <&l2cache>;
- cpu4_intc: interrupt-controller {
- #interrupt-cells = <1>;
---- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
-+++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
-@@ -80,6 +80,40 @@
- label = "d4";
- };
- };
-+
-+ fu540_c000_opp_table: opp-table {
-+ compatible = "operating-points-v2";
-+ opp-shared;
-+
-+ opp-350000000 {
-+ opp-hz = /bits/ 64 <350000000>;
-+ };
-+ opp-700000000 {
-+ opp-hz = /bits/ 64 <700000000>;
-+ };
-+ opp-999999999 {
-+ opp-hz = /bits/ 64 <999999999>;
-+ };
-+ opp-1400000000 {
-+ opp-hz = /bits/ 64 <1400000000>;
-+ };
-+ };
-+};
-+
-+&cpu0 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
-+};
-+&cpu1 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
-+};
-+&cpu2 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
-+};
-+&cpu3 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
-+};
-+&cpu4 {
-+ operating-points-v2 = <&fu540_c000_opp_table>;
- };
-
- &uart0 {
FEATURES:=usb ext4 display rootfs-part rtc squashfs
SUBTARGETS:=cortexa8 cortexa7 cortexa53
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
KERNELNAME:=zImage dtbs
+++ /dev/null
-# CONFIG_AHCI_SUNXI is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_FORCE_MAX_ORDER=11
-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=416
-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_SUNXI=y
-CONFIG_ARCH_SUNXI_MC_SMP=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=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_CCI=y
-CONFIG_ARM_CCI400_COMMON=y
-CONFIG_ARM_CCI400_PORT_CTRL=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_CRYPTO=y
-CONFIG_ARM_ERRATA_643719=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_LPAE=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_PSCI=y
-CONFIG_ARM_PSCI_FW=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ATA=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_AXP20X_POWER=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_PWM=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_PM=y
-CONFIG_BOUNCE=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CAN=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLK_SUNXI=y
-CONFIG_CLK_SUNXI_CLOCKS=y
-CONFIG_CLK_SUNXI_PRCM_SUN6I=y
-CONFIG_CLK_SUNXI_PRCM_SUN8I=y
-CONFIG_CLK_SUNXI_PRCM_SUN9I=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONNECTOR=y
-CONFIG_CONSOLE_TRANSLATIONS=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_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_HAS_ASID=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_CRC_T10DIF=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CRCT10DIF=y
-CONFIG_CRYPTO_CRCT10DIF_ARM_CE=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEV_ALLWINNER=y
-CONFIG_CRYPTO_DEV_SUN4I_SS=y
-# CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG is not set
-CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG=y
-# CONFIG_CRYPTO_DEV_SUN8I_CE is not set
-# CONFIG_CRYPTO_DEV_SUN8I_SS is not set
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_DES=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_REMAP=y
-CONFIG_DMA_SUN4I=y
-CONFIG_DMA_SUN6I=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_DVB_CORE=y
-CONFIG_DWMAC_GENERIC=y
-# CONFIG_DWMAC_SUN8I is not set
-CONFIG_DWMAC_SUNXI=y
-CONFIG_DYNAMIC_DEBUG=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_ELF_CORE=y
-CONFIG_EXT4_FS=y
-CONFIG_EXTCON=y
-CONFIG_F2FS_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_FOREIGN_ENDIAN=y
-CONFIG_FB_LITTLE_ENDIAN=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_SIMPLE=y
-CONFIG_FB_TILEBLITTING=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=y
-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
-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_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_GPIO_CDEV=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_HOTPLUG_CPU=y
-CONFIG_HWMON=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_TIMERIOMEM=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_MV64XXX=y
-CONFIG_I2C_SUN6I_P2WI=y
-CONFIG_IIO=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_INPUT_AXP20X_PEK=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_KALLSYMS=y
-CONFIG_KEYBOARD_SUN4I_LRADC=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-CONFIG_KSM=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_LCD_PLATFORM=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_CLUT224=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_MACH_SUN4I=y
-CONFIG_MACH_SUN5I=y
-CONFIG_MACH_SUN6I=y
-CONFIG_MACH_SUN7I=y
-CONFIG_MACH_SUN8I=y
-CONFIG_MACH_SUN9I=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MDIO_SUN4I=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_MEMFD_CREATE=y
-CONFIG_MFD_AXP20X=y
-CONFIG_MFD_AXP20X_I2C=y
-CONFIG_MFD_AXP20X_RSB=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SUN6I_PRCM=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_SUNXI=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_FIT_FW=y
-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_ALLWINNER=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NO_HZ=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=8
-CONFIG_NVMEM=y
-CONFIG_NVMEM_SUNXI_SID=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_PCS_XPCS=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PHY_SUN4I_USB=y
-# CONFIG_PHY_SUN50I_USB3 is not set
-# CONFIG_PHY_SUN6I_MIPI_DPHY is not set
-CONFIG_PHY_SUN9I_USB=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_AXP209=y
-# CONFIG_PINCTRL_SUN20I_D1 is not set
-CONFIG_PINCTRL_SUN4I_A10=y
-# CONFIG_PINCTRL_SUN50I_A100 is not set
-# CONFIG_PINCTRL_SUN50I_A100_R is not set
-# CONFIG_PINCTRL_SUN50I_A64 is not set
-# CONFIG_PINCTRL_SUN50I_A64_R is not set
-# CONFIG_PINCTRL_SUN50I_H5 is not set
-# CONFIG_PINCTRL_SUN50I_H6 is not set
-# CONFIG_PINCTRL_SUN50I_H616 is not set
-# CONFIG_PINCTRL_SUN50I_H616_R is not set
-# CONFIG_PINCTRL_SUN50I_H6_R is not set
-CONFIG_PINCTRL_SUN5I=y
-CONFIG_PINCTRL_SUN6I_A31=y
-CONFIG_PINCTRL_SUN6I_A31_R=y
-CONFIG_PINCTRL_SUN8I_A23=y
-CONFIG_PINCTRL_SUN8I_A23_R=y
-CONFIG_PINCTRL_SUN8I_A33=y
-CONFIG_PINCTRL_SUN8I_A83T=y
-CONFIG_PINCTRL_SUN8I_A83T_R=y
-CONFIG_PINCTRL_SUN8I_H3=y
-CONFIG_PINCTRL_SUN8I_H3_R=y
-CONFIG_PINCTRL_SUN8I_V3S=y
-CONFIG_PINCTRL_SUN9I_A80=y
-CONFIG_PINCTRL_SUN9I_A80_R=y
-CONFIG_PINCTRL_SUNXI=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_OPP=y
-CONFIG_PM_SLEEP=y
-CONFIG_PM_SLEEP_SMP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PROC_EVENTS=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_SUN4I=y
-CONFIG_PWM_SYSFS=y
-CONFIG_RATIONAL=y
-CONFIG_REALTEK_PHY=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_AXP20X=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_GPIO=y
-CONFIG_REGULATOR_SY8106A=y
-CONFIG_RELAY=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_SIMPLE=y
-CONFIG_RESET_SUNXI=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SATA_HOST=y
-CONFIG_SATA_PMP=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SDIO_UART=y
-CONFIG_SECURITYFS=y
-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=8
-CONFIG_SERIAL_8250_RUNTIME_UARTS=8
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SND=y
-CONFIG_SND_COMPRESS_OFFLOAD=y
-CONFIG_SND_JACK=y
-CONFIG_SND_JACK_INPUT_DEV=y
-CONFIG_SND_PCM=y
-CONFIG_SND_SIMPLE_CARD=y
-CONFIG_SND_SIMPLE_CARD_UTILS=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_I2C_AND_SPI=y
-# CONFIG_SND_SUN4I_I2S is not set
-# CONFIG_SND_SUN4I_SPDIF is not set
-# CONFIG_SND_SUN50I_DMIC is not set
-# CONFIG_SND_SUN8I_CODEC is not set
-# CONFIG_SND_SUN8I_CODEC_ANALOG is not set
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_SUN4I=y
-CONFIG_SPI_SUN6I=y
-CONFIG_SRCU=y
-CONFIG_STMMAC_ETH=y
-CONFIG_STMMAC_PLATFORM=y
-CONFIG_SUN4I_A10_CCU=y
-# CONFIG_SUN4I_EMAC is not set
-CONFIG_SUN4I_TIMER=y
-CONFIG_SUN5I_CCU=y
-CONFIG_SUN5I_HSTIMER=y
-CONFIG_SUN6I_A31_CCU=y
-# CONFIG_SUN6I_RTC_CCU is not set
-CONFIG_SUN8I_A23_CCU=y
-CONFIG_SUN8I_A33_CCU=y
-CONFIG_SUN8I_A83T_CCU=y
-CONFIG_SUN8I_DE2_CCU=y
-CONFIG_SUN8I_H3_CCU=y
-CONFIG_SUN8I_R40_CCU=y
-CONFIG_SUN8I_R_CCU=y
-CONFIG_SUN8I_THERMAL=y
-CONFIG_SUN8I_V3S_CCU=y
-CONFIG_SUN9I_A80_CCU=y
-CONFIG_SUNXI_CCU=y
-CONFIG_SUNXI_MBUS=y
-CONFIG_SUNXI_RSB=y
-CONFIG_SUNXI_SRAM=y
-CONFIG_SUNXI_WATCHDOG=y
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=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_HWMON=y
-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
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_DWC2=y
-CONFIG_USB_DWC2_HOST=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_NET_DRIVERS=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USERIO=y
-CONFIG_USE_OF=y
-CONFIG_VFAT_FS=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VHOST=y
-CONFIG_VHOST_IOTLB=y
-CONFIG_VHOST_NET=y
-# CONFIG_VIDEO_SUN4I_CSI is not set
-# CONFIG_VIDEO_SUN6I_CSI is not set
-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_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_ZBOOT_ROM_TEXT=0
+++ /dev/null
-CONFIG_64BIT=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_STACKWALK=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_ERRATUM_2051678=y
-CONFIG_ARM64_ERRATUM_2077057=y
-CONFIG_ARM64_ERRATUM_2658417=y
-CONFIG_ARM64_ERRATUM_2054223=y
-CONFIG_ARM64_ERRATUM_2067961=y
-CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PA_BITS=48
-CONFIG_ARM64_PA_BITS_48=y
-CONFIG_ARM64_TAGGED_ADDR_ABI=y
-CONFIG_ARM64_VA_BITS=39
-CONFIG_ARM64_VA_BITS_39=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
-CONFIG_ARM_GIC_V3=y
-CONFIG_ARM_GIC_V3_ITS=y
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
-CONFIG_CPU_LITTLE_ENDIAN=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_BLAKE2S=y
-CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_GHASH_ARM64_CE=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_SHA1_ARM64_CE=y
-CONFIG_CRYPTO_SIMD=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DWMAC_SUN8I=y
-CONFIG_EEPROM_AT24=y
-CONFIG_FRAME_POINTER=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_CSUM=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_MDIO_BUS_MUX=y
-CONFIG_MICREL_PHY=y
-# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MOTORCOMM_PHY=y
-CONFIG_MUSB_PIO_ONLY=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NOP_USB_XCEIV=y
-CONFIG_NO_IOPORT_MAP=y
-CONFIG_PARTITION_PERCPU=y
-CONFIG_PHY_SUN50I_USB3=y
-CONFIG_PINCTRL_SUN50I_A100=y
-CONFIG_PINCTRL_SUN50I_A100_R=y
-CONFIG_PINCTRL_SUN50I_A64=y
-CONFIG_PINCTRL_SUN50I_A64_R=y
-CONFIG_PINCTRL_SUN50I_H5=y
-CONFIG_PINCTRL_SUN50I_H6=y
-CONFIG_PINCTRL_SUN50I_H6_R=y
-CONFIG_PINCTRL_SUN50I_H616=y
-CONFIG_PINCTRL_SUN50I_H616_R=y
-# CONFIG_PREEMPT_DYNAMIC is not set
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
-# CONFIG_SCHED_CLUSTER is not set
-# CONFIG_SHADOW_CALL_STACK is not set
-# CONFIG_SND_SUN50I_CODEC_ANALOG is not set
-CONFIG_SOUND_OSS_CORE_PRECLAIM=y
-CONFIG_SPARSEMEM=y
-CONFIG_SPARSEMEM_EXTREME=y
-CONFIG_SPARSEMEM_VMEMMAP=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SUN50I_A100_CCU=y
-CONFIG_SUN50I_A100_R_CCU=y
-CONFIG_SUN50I_A64_CCU=y
-CONFIG_SUN50I_DE2_BUS=y
-CONFIG_SUN50I_ERRATUM_UNKNOWN1=y
-CONFIG_SUN50I_H616_CCU=y
-CONFIG_SUN50I_H6_CCU=y
-CONFIG_SUN50I_H6_R_CCU=y
-# CONFIG_SUN6I_RTC_CCU is not set
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_UNMAP_KERNEL_AT_EL0=y
-CONFIG_USB_MUSB_DUAL_ROLE=y
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_SUNXI=y
-CONFIG_USB_PHY=y
-CONFIG_VMAP_STACK=y
-CONFIG_ZONE_DMA32=y
-CONFIG_SURFACE_PLATFORMS=y
-# CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set
-# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set
-# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set
-# CONFIG_PAGE_TABLE_CHECK is not set
-CONFIG_RANDOMIZE_KSTACK_OFFSET=y
-# CONFIG_ARCH_NXP is not set
+++ /dev/null
-CONFIG_B53=y
-CONFIG_B53_MDIO_DRIVER=y
-CONFIG_CRYPTO_BLAKE2S_ARM=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_DWMAC_SUN8I=y
-CONFIG_GRO_CELLS=y
-# CONFIG_HARDEN_BRANCH_HISTORY is not set
-# CONFIG_HARDEN_BRANCH_PREDICTOR is not set
-# CONFIG_MACH_SUN4I is not set
-# CONFIG_MACH_SUN5I is not set
-CONFIG_MDIO_BUS_MUX=y
-CONFIG_MICREL_PHY=y
-CONFIG_MUSB_PIO_ONLY=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_SWITCHDEV=y
-CONFIG_NOP_USB_XCEIV=y
-CONFIG_RTC_DRV_SUN6I=y
-CONFIG_USB_MUSB_DUAL_ROLE=y
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_SUNXI=y
-CONFIG_USB_PHY=y
+++ /dev/null
-# CONFIG_ARM_LPAE is not set
-CONFIG_CRYPTO_BLAKE2S_ARM=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-# CONFIG_MACH_SUN6I is not set
-# CONFIG_MACH_SUN7I is not set
-# CONFIG_MACH_SUN8I is not set
-# CONFIG_MACH_SUN9I is not set
-CONFIG_PGTABLE_LEVELS=2
-# CONFIG_PHY_SUN9I_USB is not set
-# CONFIG_SPI_SUN6I is not set
-# CONFIG_SUN8I_A83T_CCU is not set
-# CONFIG_SUN8I_THERMAL is not set
KERNEL := kernel-bin | uImage none
IMAGES := sdcard.img.gz
IMAGE/sdcard.img.gz := sunxi-sdcard | append-metadata | gzip
-ifdef CONFIG_LINUX_6_6
SUNXI_DTS_DIR :=allwinner/
-endif
SUNXI_DTS = $$(SUNXI_DTS_DIR)$$(SOC)-$(lastword $(subst _, ,$(1)))
endef
endef
TARGET_DEVICES += lemaker_bananapro
+define Device/licheepi_licheepi-zero-dock
+ DEVICE_VENDOR := LicheePi
+ DEVICE_MODEL := Zero with Dock (V3s)
+ DEVICE_PACKAGES:=kmod-rtc-sunxi
+ SOC := sun8i-v3s
+endef
+TARGET_DEVICES += licheepi_licheepi-zero-dock
+
define Device/linksprite_pcduino3
DEVICE_VENDOR := LinkSprite
DEVICE_MODEL := pcDuino3
+++ /dev/null
-From 28a1a6474c5053bae01bd29946b4d5ede539176b Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Mon, 31 Oct 2022 11:13:52 +0000
-Subject: [PATCH] dt-bindings: usb: Add H616 compatible string
-
-The Allwinner H616 contains four fully OHCI/EHCI compatible USB host
-controllers, so just add their compatible strings to the list of
-generic OHCI/EHCI controllers.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20221031111358.3387297-2-andre.przywara@arm.com
-Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
----
- Documentation/devicetree/bindings/usb/generic-ehci.yaml | 1 +
- Documentation/devicetree/bindings/usb/generic-ohci.yaml | 1 +
- 2 files changed, 2 insertions(+)
-
---- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml
-+++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml
-@@ -30,6 +30,7 @@ properties:
- - allwinner,sun4i-a10-ehci
- - allwinner,sun50i-a64-ehci
- - allwinner,sun50i-h6-ehci
-+ - allwinner,sun50i-h616-ehci
- - allwinner,sun5i-a13-ehci
- - allwinner,sun6i-a31-ehci
- - allwinner,sun7i-a20-ehci
---- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml
-+++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml
-@@ -20,6 +20,7 @@ properties:
- - allwinner,sun4i-a10-ohci
- - allwinner,sun50i-a64-ohci
- - allwinner,sun50i-h6-ohci
-+ - allwinner,sun50i-h616-ohci
- - allwinner,sun5i-a13-ohci
- - allwinner,sun6i-a31-ohci
- - allwinner,sun7i-a20-ohci
+++ /dev/null
-From 6964affe65066651eca21e97247d3b7cac5153dc Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Mon, 31 Oct 2022 11:13:53 +0000
-Subject: [PATCH] dt-bindings: phy: Add special clock for Allwinner H616 PHY
-
-The USB PHY IP in the Allwinner H616 SoC requires a quirk that involves
-some resources from port 2's PHY and HCI IP. In particular the PMU clock
-for port 2 must be surely ungated before accessing the REG_HCI_PHY_CTL
-register of port 2. To allow each USB port to be controlled
-independently of port 2, we need a handle to that particular PMU clock
-in the *PHY* node, as the HCI and PHY part might be handled by separate
-drivers.
-
-Add that clock to the requirements of the H616 PHY binding, so that a
-PHY driver can apply the quirk in isolation, without requiring help from
-port 2's HCI driver.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20221031111358.3387297-3-andre.przywara@arm.com
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- .../phy/allwinner,sun8i-h3-usb-phy.yaml | 26 +++++++++++++++++++
- 1 file changed, 26 insertions(+)
-
---- a/Documentation/devicetree/bindings/phy/allwinner,sun8i-h3-usb-phy.yaml
-+++ b/Documentation/devicetree/bindings/phy/allwinner,sun8i-h3-usb-phy.yaml
-@@ -36,18 +36,22 @@ properties:
- - const: pmu3
-
- clocks:
-+ minItems: 4
- items:
- - description: USB OTG PHY bus clock
- - description: USB Host 0 PHY bus clock
- - description: USB Host 1 PHY bus clock
- - description: USB Host 2 PHY bus clock
-+ - description: PMU clock for host port 2
-
- clock-names:
-+ minItems: 4
- items:
- - const: usb0_phy
- - const: usb1_phy
- - const: usb2_phy
- - const: usb3_phy
-+ - const: pmu2_clk
-
- resets:
- items:
-@@ -96,6 +100,28 @@ required:
- - resets
- - reset-names
-
-+allOf:
-+ - if:
-+ properties:
-+ compatible:
-+ contains:
-+ enum:
-+ - allwinner,sun50i-h616-usb-phy
-+ then:
-+ properties:
-+ clocks:
-+ minItems: 5
-+
-+ clock-names:
-+ minItems: 5
-+ else:
-+ properties:
-+ clocks:
-+ maxItems: 4
-+
-+ clock-names:
-+ maxItems: 4
-+
- additionalProperties: false
-
- examples:
+++ /dev/null
-From f40cf244c3feb4e1a442f8029b691add2c65b3ab Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Mon, 31 Oct 2022 11:13:56 +0000
-Subject: [PATCH] arm64: dts: allwinner: h616: Add USB nodes
-
-Add the nodes for the MUSB and the four USB host controllers to the SoC
-.dtsi, along with the PHY node needed to bind all of them together.
-
-EHCI/OHCI and MUSB are compatible to previous SoCs, but the PHY requires
-some quirks (handled in the driver).
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Link: https://lore.kernel.org/r/20221031111358.3387297-6-andre.przywara@arm.com
-Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
----
- .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 160 ++++++++++++++++++
- 1 file changed, 160 insertions(+)
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
-@@ -504,6 +504,166 @@
- };
- };
-
-+ usbotg: usb@5100000 {
-+ compatible = "allwinner,sun50i-h616-musb",
-+ "allwinner,sun8i-h3-musb";
-+ reg = <0x05100000 0x0400>;
-+ clocks = <&ccu CLK_BUS_OTG>;
-+ resets = <&ccu RST_BUS_OTG>;
-+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
-+ interrupt-names = "mc";
-+ phys = <&usbphy 0>;
-+ phy-names = "usb";
-+ extcon = <&usbphy 0>;
-+ status = "disabled";
-+ };
-+
-+ usbphy: phy@5100400 {
-+ compatible = "allwinner,sun50i-h616-usb-phy";
-+ reg = <0x05100400 0x24>,
-+ <0x05101800 0x14>,
-+ <0x05200800 0x14>,
-+ <0x05310800 0x14>,
-+ <0x05311800 0x14>;
-+ reg-names = "phy_ctrl",
-+ "pmu0",
-+ "pmu1",
-+ "pmu2",
-+ "pmu3";
-+ clocks = <&ccu CLK_USB_PHY0>,
-+ <&ccu CLK_USB_PHY1>,
-+ <&ccu CLK_USB_PHY2>,
-+ <&ccu CLK_USB_PHY3>,
-+ <&ccu CLK_BUS_EHCI2>;
-+ clock-names = "usb0_phy",
-+ "usb1_phy",
-+ "usb2_phy",
-+ "usb3_phy",
-+ "pmu2_clk";
-+ resets = <&ccu RST_USB_PHY0>,
-+ <&ccu RST_USB_PHY1>,
-+ <&ccu RST_USB_PHY2>,
-+ <&ccu RST_USB_PHY3>;
-+ reset-names = "usb0_reset",
-+ "usb1_reset",
-+ "usb2_reset",
-+ "usb3_reset";
-+ status = "disabled";
-+ #phy-cells = <1>;
-+ };
-+
-+ ehci0: usb@5101000 {
-+ compatible = "allwinner,sun50i-h616-ehci",
-+ "generic-ehci";
-+ reg = <0x05101000 0x100>;
-+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&ccu CLK_BUS_OHCI0>,
-+ <&ccu CLK_BUS_EHCI0>,
-+ <&ccu CLK_USB_OHCI0>;
-+ resets = <&ccu RST_BUS_OHCI0>,
-+ <&ccu RST_BUS_EHCI0>;
-+ phys = <&usbphy 0>;
-+ phy-names = "usb";
-+ status = "disabled";
-+ };
-+
-+ ohci0: usb@5101400 {
-+ compatible = "allwinner,sun50i-h616-ohci",
-+ "generic-ohci";
-+ reg = <0x05101400 0x100>;
-+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&ccu CLK_BUS_OHCI0>,
-+ <&ccu CLK_USB_OHCI0>;
-+ resets = <&ccu RST_BUS_OHCI0>;
-+ phys = <&usbphy 0>;
-+ phy-names = "usb";
-+ status = "disabled";
-+ };
-+
-+ ehci1: usb@5200000 {
-+ compatible = "allwinner,sun50i-h616-ehci",
-+ "generic-ehci";
-+ reg = <0x05200000 0x100>;
-+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&ccu CLK_BUS_OHCI1>,
-+ <&ccu CLK_BUS_EHCI1>,
-+ <&ccu CLK_USB_OHCI1>;
-+ resets = <&ccu RST_BUS_OHCI1>,
-+ <&ccu RST_BUS_EHCI1>;
-+ phys = <&usbphy 1>;
-+ phy-names = "usb";
-+ status = "disabled";
-+ };
-+
-+ ohci1: usb@5200400 {
-+ compatible = "allwinner,sun50i-h616-ohci",
-+ "generic-ohci";
-+ reg = <0x05200400 0x100>;
-+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&ccu CLK_BUS_OHCI1>,
-+ <&ccu CLK_USB_OHCI1>;
-+ resets = <&ccu RST_BUS_OHCI1>;
-+ phys = <&usbphy 1>;
-+ phy-names = "usb";
-+ status = "disabled";
-+ };
-+
-+ ehci2: usb@5310000 {
-+ compatible = "allwinner,sun50i-h616-ehci",
-+ "generic-ehci";
-+ reg = <0x05310000 0x100>;
-+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&ccu CLK_BUS_OHCI2>,
-+ <&ccu CLK_BUS_EHCI2>,
-+ <&ccu CLK_USB_OHCI2>;
-+ resets = <&ccu RST_BUS_OHCI2>,
-+ <&ccu RST_BUS_EHCI2>;
-+ phys = <&usbphy 2>;
-+ phy-names = "usb";
-+ status = "disabled";
-+ };
-+
-+ ohci2: usb@5310400 {
-+ compatible = "allwinner,sun50i-h616-ohci",
-+ "generic-ohci";
-+ reg = <0x05310400 0x100>;
-+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&ccu CLK_BUS_OHCI2>,
-+ <&ccu CLK_USB_OHCI2>;
-+ resets = <&ccu RST_BUS_OHCI2>;
-+ phys = <&usbphy 2>;
-+ phy-names = "usb";
-+ status = "disabled";
-+ };
-+
-+ ehci3: usb@5311000 {
-+ compatible = "allwinner,sun50i-h616-ehci",
-+ "generic-ehci";
-+ reg = <0x05311000 0x100>;
-+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&ccu CLK_BUS_OHCI3>,
-+ <&ccu CLK_BUS_EHCI3>,
-+ <&ccu CLK_USB_OHCI3>;
-+ resets = <&ccu RST_BUS_OHCI3>,
-+ <&ccu RST_BUS_EHCI3>;
-+ phys = <&usbphy 3>;
-+ phy-names = "usb";
-+ status = "disabled";
-+ };
-+
-+ ohci3: usb@5311400 {
-+ compatible = "allwinner,sun50i-h616-ohci",
-+ "generic-ohci";
-+ reg = <0x05311400 0x100>;
-+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&ccu CLK_BUS_OHCI3>,
-+ <&ccu CLK_USB_OHCI3>;
-+ resets = <&ccu RST_BUS_OHCI3>;
-+ phys = <&usbphy 3>;
-+ phy-names = "usb";
-+ status = "disabled";
-+ };
-+
- rtc: rtc@7000000 {
- compatible = "allwinner,sun50i-h616-rtc";
- reg = <0x07000000 0x400>;
+++ /dev/null
-From db5f028309ede13767e2ba356c1975ac37a4fd6c Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Mon, 31 Oct 2022 11:13:57 +0000
-Subject: [PATCH] arm64: dts: allwinner: h616: OrangePi Zero 2: Add USB nodes
-
-The OrangePi Zero 2 has one USB-A host port, VBUS is provided by
-a GPIO controlled regulator.
-The USB-C port is meant to power the board, but is also connected to
-the USB 0 port, which we configure as an MUSB peripheral.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Link: https://lore.kernel.org/r/20221031111358.3387297-7-andre.przywara@arm.com
-Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
----
- .../allwinner/sun50i-h616-orangepi-zero2.dts | 41 +++++++++++++++++++
- 1 file changed, 41 insertions(+)
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
-@@ -49,8 +49,24 @@
- regulator-max-microvolt = <5000000>;
- regulator-always-on;
- };
-+
-+ reg_usb1_vbus: regulator-usb1-vbus {
-+ compatible = "regulator-fixed";
-+ regulator-name = "usb1-vbus";
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ vin-supply = <®_vcc5v>;
-+ enable-active-high;
-+ gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */
-+ };
-+};
-+
-+&ehci1 {
-+ status = "okay";
- };
-
-+/* USB 2 & 3 are on headers only. */
-+
- &emac0 {
- pinctrl-names = "default";
- pinctrl-0 = <&ext_rgmii_pins>;
-@@ -76,6 +92,10 @@
- status = "okay";
- };
-
-+&ohci1 {
-+ status = "okay";
-+};
-+
- &r_rsb {
- status = "okay";
-
-@@ -211,3 +231,24 @@
- pinctrl-0 = <&uart0_ph_pins>;
- status = "okay";
- };
-+
-+&usbotg {
-+ /*
-+ * PHY0 pins are connected to a USB-C socket, but a role switch
-+ * is not implemented: both CC pins are pulled to GND.
-+ * The VBUS pins power the device, so a fixed peripheral mode
-+ * is the best choice.
-+ * The board can be powered via GPIOs, in this case port0 *can*
-+ * act as a host (with a cable/adapter ignoring CC), as VBUS is
-+ * then provided by the GPIOs. Any user of this setup would
-+ * need to adjust the DT accordingly: dr_mode set to "host",
-+ * enabling OHCI0 and EHCI0.
-+ */
-+ dr_mode = "peripheral";
-+ status = "okay";
-+};
-+
-+&usbphy {
-+ usb1_vbus-supply = <®_usb1_vbus>;
-+ status = "okay";
-+};
+++ /dev/null
-From 322bf103204b8f786547acbeed85569254e7088f Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Fri, 4 Aug 2023 18:08:54 +0100
-Subject: [PATCH] arm64: dts: allwinner: h616: Split Orange Pi Zero 2 DT
-
-The Orange Pi Zero 2 got a successor (Zero 3), which shares quite some
-DT nodes with the Zero 2, but comes with a different PMIC.
-
-Move the common parts (except the PMIC) into a new shared file, and
-include that from the existing board .dts file.
-
-No functional change, the generated DTB is the same, except for some
-phandle numbering differences.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Link: https://lore.kernel.org/r/20230804170856.1237202-2-andre.przywara@arm.com
-Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
----
- .../allwinner/sun50i-h616-orangepi-zero.dtsi | 134 ++++++++++++++++++
- .../allwinner/sun50i-h616-orangepi-zero2.dts | 119 +---------------
- 2 files changed, 135 insertions(+), 118 deletions(-)
- create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi
-
---- /dev/null
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi
-@@ -0,0 +1,134 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+/*
-+ * Copyright (C) 2020 Arm Ltd.
-+ *
-+ * DT nodes common between Orange Pi Zero 2 and Orange Pi Zero 3.
-+ * Excludes PMIC nodes and properties, since they are different between the two.
-+ */
-+
-+#include "sun50i-h616.dtsi"
-+
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/interrupt-controller/arm-gic.h>
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ aliases {
-+ ethernet0 = &emac0;
-+ serial0 = &uart0;
-+ };
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-0 {
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */
-+ default-state = "on";
-+ };
-+
-+ led-1 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */
-+ };
-+ };
-+
-+ reg_vcc5v: vcc5v {
-+ /* board wide 5V supply directly from the USB-C socket */
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc-5v";
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ regulator-always-on;
-+ };
-+
-+ reg_usb1_vbus: regulator-usb1-vbus {
-+ compatible = "regulator-fixed";
-+ regulator-name = "usb1-vbus";
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ vin-supply = <®_vcc5v>;
-+ enable-active-high;
-+ gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */
-+ };
-+};
-+
-+&ehci1 {
-+ status = "okay";
-+};
-+
-+/* USB 2 & 3 are on headers only. */
-+
-+&emac0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&ext_rgmii_pins>;
-+ phy-mode = "rgmii";
-+ phy-handle = <&ext_rgmii_phy>;
-+ allwinner,rx-delay-ps = <3100>;
-+ allwinner,tx-delay-ps = <700>;
-+ status = "okay";
-+};
-+
-+&mdio0 {
-+ ext_rgmii_phy: ethernet-phy@1 {
-+ compatible = "ethernet-phy-ieee802.3-c22";
-+ reg = <1>;
-+ };
-+};
-+
-+&mmc0 {
-+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
-+ bus-width = <4>;
-+ status = "okay";
-+};
-+
-+&ohci1 {
-+ status = "okay";
-+};
-+
-+&spi0 {
-+ status = "okay";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>;
-+
-+ flash@0 {
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ compatible = "jedec,spi-nor";
-+ reg = <0>;
-+ spi-max-frequency = <40000000>;
-+ };
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_ph_pins>;
-+ status = "okay";
-+};
-+
-+&usbotg {
-+ /*
-+ * PHY0 pins are connected to a USB-C socket, but a role switch
-+ * is not implemented: both CC pins are pulled to GND.
-+ * The VBUS pins power the device, so a fixed peripheral mode
-+ * is the best choice.
-+ * The board can be powered via GPIOs, in this case port0 *can*
-+ * act as a host (with a cable/adapter ignoring CC), as VBUS is
-+ * then provided by the GPIOs. Any user of this setup would
-+ * need to adjust the DT accordingly: dr_mode set to "host",
-+ * enabling OHCI0 and EHCI0.
-+ */
-+ dr_mode = "peripheral";
-+ status = "okay";
-+};
-+
-+&usbphy {
-+ usb1_vbus-supply = <®_usb1_vbus>;
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
-@@ -5,95 +5,19 @@
-
- /dts-v1/;
-
--#include "sun50i-h616.dtsi"
--
--#include <dt-bindings/gpio/gpio.h>
--#include <dt-bindings/interrupt-controller/arm-gic.h>
--#include <dt-bindings/leds/common.h>
-+#include "sun50i-h616-orangepi-zero.dtsi"
-
- / {
- model = "OrangePi Zero2";
- compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616";
--
-- aliases {
-- ethernet0 = &emac0;
-- serial0 = &uart0;
-- };
--
-- chosen {
-- stdout-path = "serial0:115200n8";
-- };
--
-- leds {
-- compatible = "gpio-leds";
--
-- led-0 {
-- function = LED_FUNCTION_POWER;
-- color = <LED_COLOR_ID_RED>;
-- gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */
-- default-state = "on";
-- };
--
-- led-1 {
-- function = LED_FUNCTION_STATUS;
-- color = <LED_COLOR_ID_GREEN>;
-- gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */
-- };
-- };
--
-- reg_vcc5v: vcc5v {
-- /* board wide 5V supply directly from the USB-C socket */
-- compatible = "regulator-fixed";
-- regulator-name = "vcc-5v";
-- regulator-min-microvolt = <5000000>;
-- regulator-max-microvolt = <5000000>;
-- regulator-always-on;
-- };
--
-- reg_usb1_vbus: regulator-usb1-vbus {
-- compatible = "regulator-fixed";
-- regulator-name = "usb1-vbus";
-- regulator-min-microvolt = <5000000>;
-- regulator-max-microvolt = <5000000>;
-- vin-supply = <®_vcc5v>;
-- enable-active-high;
-- gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; /* PC16 */
-- };
--};
--
--&ehci1 {
-- status = "okay";
- };
-
--/* USB 2 & 3 are on headers only. */
--
- &emac0 {
-- pinctrl-names = "default";
-- pinctrl-0 = <&ext_rgmii_pins>;
-- phy-mode = "rgmii";
-- phy-handle = <&ext_rgmii_phy>;
- phy-supply = <®_dcdce>;
-- allwinner,rx-delay-ps = <3100>;
-- allwinner,tx-delay-ps = <700>;
-- status = "okay";
--};
--
--&mdio0 {
-- ext_rgmii_phy: ethernet-phy@1 {
-- compatible = "ethernet-phy-ieee802.3-c22";
-- reg = <1>;
-- };
- };
-
- &mmc0 {
- vmmc-supply = <®_dcdce>;
-- cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
-- bus-width = <4>;
-- status = "okay";
--};
--
--&ohci1 {
-- status = "okay";
- };
-
- &r_rsb {
-@@ -211,44 +135,3 @@
- vcc-ph-supply = <®_aldo1>;
- vcc-pi-supply = <®_aldo1>;
- };
--
--&spi0 {
-- status = "okay";
-- pinctrl-names = "default";
-- pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>;
--
-- flash@0 {
-- #address-cells = <1>;
-- #size-cells = <1>;
-- compatible = "jedec,spi-nor";
-- reg = <0>;
-- spi-max-frequency = <40000000>;
-- };
--};
--
--&uart0 {
-- pinctrl-names = "default";
-- pinctrl-0 = <&uart0_ph_pins>;
-- status = "okay";
--};
--
--&usbotg {
-- /*
-- * PHY0 pins are connected to a USB-C socket, but a role switch
-- * is not implemented: both CC pins are pulled to GND.
-- * The VBUS pins power the device, so a fixed peripheral mode
-- * is the best choice.
-- * The board can be powered via GPIOs, in this case port0 *can*
-- * act as a host (with a cable/adapter ignoring CC), as VBUS is
-- * then provided by the GPIOs. Any user of this setup would
-- * need to adjust the DT accordingly: dr_mode set to "host",
-- * enabling OHCI0 and EHCI0.
-- */
-- dr_mode = "peripheral";
-- status = "okay";
--};
--
--&usbphy {
-- usb1_vbus-supply = <®_usb1_vbus>;
-- status = "okay";
--};
+++ /dev/null
-From f1b3ddb3ecc2eec1f912383e01156c226daacfab Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Fri, 4 Aug 2023 18:08:56 +0100
-Subject: [PATCH] arm64: dts: allwinner: h616: Add OrangePi Zero 3 board
- support
-
-The OrangePi Zero 3 is a development board based on the Allwinner H618 SoC,
-which seems to be just an H616 with more L2 cache. The board itself is a
-slightly updated version of the Orange Pi Zero 2. It features:
-- Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
-- 1/1.5/2/4 GiB LPDDR4 DRAM SKUs (only up to 1GB on the Zero2)
-- AXP313a PMIC (more capable AXP305 on the Zero2)
-- Raspberry-Pi-1 compatible GPIO header
-- extra 13 pin expansion header, exposing pins for 2x USB 2.0 ports
-- 1 USB 2.0 host port
-- 1 USB 2.0 type C port (power supply + OTG)
-- MicroSD slot
-- on-board 16MiB bootable SPI NOR flash (only 2MB on the Zero2)
-- 1Gbps Ethernet port (via Motorcomm YT8531 PHY) (RTL8211 on the Zero2)
-- micro-HDMI port
-- (yet) unsupported Allwinner WiFi/BT chip
-
-Add the devicetree file describing the currently supported features,
-namely LEDs, SD card, PMIC, SPI flash, USB. Ethernet seems unstable at
-the moment, though the basic functionality works.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Link: https://lore.kernel.org/r/20230804170856.1237202-4-andre.przywara@arm.com
-Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
----
- arch/arm64/boot/dts/allwinner/Makefile | 1 +
- .../allwinner/sun50i-h618-orangepi-zero3.dts | 94 +++++++++++++++++++
- 2 files changed, 95 insertions(+)
- create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
-
---- a/arch/arm64/boot/dts/allwinner/Makefile
-+++ b/arch/arm64/boot/dts/allwinner/Makefile
-@@ -40,3 +40,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-ta
- dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6-mini.dtb
- dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
- dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
-+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
---- /dev/null
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
-@@ -0,0 +1,94 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+/*
-+ * Copyright (C) 2023 Arm Ltd.
-+ */
-+
-+/dts-v1/;
-+
-+#include "sun50i-h616-orangepi-zero.dtsi"
-+
-+/ {
-+ model = "OrangePi Zero3";
-+ compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618";
-+};
-+
-+&emac0 {
-+ phy-supply = <®_dldo1>;
-+};
-+
-+&ext_rgmii_phy {
-+ motorcomm,clk-out-frequency-hz = <125000000>;
-+};
-+
-+&mmc0 {
-+ /*
-+ * The schematic shows the card detect pin wired up to PF6, via an
-+ * inverter, but it just doesn't work.
-+ */
-+ broken-cd;
-+ vmmc-supply = <®_dldo1>;
-+};
-+
-+&r_i2c {
-+ status = "okay";
-+
-+ axp313: pmic@36 {
-+ compatible = "x-powers,axp313a";
-+ reg = <0x36>;
-+ #interrupt-cells = <1>;
-+ interrupt-controller;
-+ interrupt-parent = <&pio>;
-+ interrupts = <2 9 IRQ_TYPE_LEVEL_LOW>; /* PC9 */
-+
-+ vin1-supply = <®_vcc5v>;
-+ vin2-supply = <®_vcc5v>;
-+ vin3-supply = <®_vcc5v>;
-+
-+ regulators {
-+ /* Supplies VCC-PLL, so needs to be always on. */
-+ reg_aldo1: aldo1 {
-+ regulator-always-on;
-+ regulator-min-microvolt = <1800000>;
-+ regulator-max-microvolt = <1800000>;
-+ regulator-name = "vcc1v8";
-+ };
-+
-+ /* Supplies VCC-IO, so needs to be always on. */
-+ reg_dldo1: dldo1 {
-+ regulator-always-on;
-+ regulator-min-microvolt = <3300000>;
-+ regulator-max-microvolt = <3300000>;
-+ regulator-name = "vcc3v3";
-+ };
-+
-+ reg_dcdc1: dcdc1 {
-+ regulator-always-on;
-+ regulator-min-microvolt = <810000>;
-+ regulator-max-microvolt = <990000>;
-+ regulator-name = "vdd-gpu-sys";
-+ };
-+
-+ reg_dcdc2: dcdc2 {
-+ regulator-always-on;
-+ regulator-min-microvolt = <810000>;
-+ regulator-max-microvolt = <1100000>;
-+ regulator-name = "vdd-cpu";
-+ };
-+
-+ reg_dcdc3: dcdc3 {
-+ regulator-always-on;
-+ regulator-min-microvolt = <1100000>;
-+ regulator-max-microvolt = <1100000>;
-+ regulator-name = "vdd-dram";
-+ };
-+ };
-+ };
-+};
-+
-+&pio {
-+ vcc-pc-supply = <®_dldo1>;
-+ vcc-pf-supply = <®_dldo1>;
-+ vcc-pg-supply = <®_aldo1>;
-+ vcc-ph-supply = <®_dldo1>;
-+ vcc-pi-supply = <®_dldo1>;
-+};
+++ /dev/null
-From b9622937d95809ef89904583191571a9fa326402 Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Sun, 29 Oct 2023 15:40:09 +0800
-Subject: [PATCH] arm64: dts: allwinner: h616: update emac for Orange Pi Zero 3
-
-The current emac setting is not suitable for Orange Pi Zero 3,
-move it back to Orange Pi Zero 2 DT. Also update phy mode and
-delay values for emac on Orange Pi Zero 3.
-With these changes, Ethernet now looks stable.
-
-Fixes: 322bf103204b ("arm64: dts: allwinner: h616: Split Orange Pi Zero 2 DT")
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
-Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Link: https://lore.kernel.org/r/20231029074009.7820-2-amadeus@jmu.edu.cn
-Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
----
- arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi | 3 ---
- arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts | 3 +++
- arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts | 2 ++
- 3 files changed, 5 insertions(+), 3 deletions(-)
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero.dtsi
-@@ -68,10 +68,7 @@
- &emac0 {
- pinctrl-names = "default";
- pinctrl-0 = <&ext_rgmii_pins>;
-- phy-mode = "rgmii";
- phy-handle = <&ext_rgmii_phy>;
-- allwinner,rx-delay-ps = <3100>;
-- allwinner,tx-delay-ps = <700>;
- status = "okay";
- };
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
-@@ -13,6 +13,9 @@
- };
-
- &emac0 {
-+ allwinner,rx-delay-ps = <3100>;
-+ allwinner,tx-delay-ps = <700>;
-+ phy-mode = "rgmii";
- phy-supply = <®_dcdce>;
- };
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
-@@ -13,6 +13,8 @@
- };
-
- &emac0 {
-+ allwinner,tx-delay-ps = <700>;
-+ phy-mode = "rgmii-rxid";
- phy-supply = <®_dldo1>;
- };
-
+++ /dev/null
-From 951992797378a2177946400438f4d23c9fceae5b Mon Sep 17 00:00:00 2001
-From: Martin Botka <martin.botka@somainline.org>
-Date: Tue, 12 Sep 2023 14:25:13 +0200
-Subject: [PATCH] arm64: dts: allwinner: h616: Add SID controller node
-
-Add node for the H616 SID controller
-
-Signed-off-by: Martin Botka <martin.botka@somainline.org>
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Link: https://lore.kernel.org/r/20230912-sid-h616-v3-2-ee18e1c5bbb5@somainline.org
-Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
----
- arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
-@@ -133,6 +133,13 @@
- #reset-cells = <1>;
- };
-
-+ sid: efuse@3006000 {
-+ compatible = "allwinner,sun50i-h616-sid", "allwinner,sun50i-a64-sid";
-+ reg = <0x03006000 0x1000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ };
-+
- watchdog: watchdog@30090a0 {
- compatible = "allwinner,sun50i-h616-wdt",
- "allwinner,sun6i-a31-wdt";
+++ /dev/null
-From 898d96c5464b69af44f6407c5de81ebc349d574b Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Mon, 19 Feb 2024 15:36:33 +0000
-Subject: [PATCH] soc: sunxi: sram: export register 0 for THS on H616
-
-The Allwinner H616 SoC contains a mysterious bit at register offset 0x0
-in the SRAM control block. If bit 16 is set (the reset value), the
-temperature readings of the THS are way off, leading to reports about
-200C, at normal ambient temperatures. Clearing this bits brings the
-reported values down to the expected values.
-The BSP code clears this bit in firmware (U-Boot), and has an explicit
-comment about this, but offers no real explanation.
-
-Experiments in U-Boot show that register 0x0 has no effect on the SRAM C
-visibility: all tested bit settings still allow full read and write
-access by the CPU to the whole of SRAM C. Only bit 24 of the register at
-offset 0x4 makes all of SRAM C inaccessible by the CPU. So modelling
-the THS switch functionality as an SRAM region would not reflect reality.
-
-Since we should not rely on firmware settings, allow other code (the THS
-driver) to access this register, by exporting it through the already
-existing regmap. This mimics what we already do for the LDO control and
-the EMAC register.
-
-To avoid concurrent accesses to the same register at the same time, by
-the SRAM switch code and the regmap code, use the same lock to protect
-the access. The regmap subsystem allows to use an existing lock, so we
-just need to hook in there.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20240219153639.179814-2-andre.przywara@arm.com
----
- drivers/soc/sunxi/sunxi_sram.c | 22 ++++++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
---- a/drivers/soc/sunxi/sunxi_sram.c
-+++ b/drivers/soc/sunxi/sunxi_sram.c
-@@ -284,6 +284,7 @@ EXPORT_SYMBOL(sunxi_sram_release);
- struct sunxi_sramc_variant {
- int num_emac_clocks;
- bool has_ldo_ctrl;
-+ bool has_ths_offset;
- };
-
- static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
-@@ -305,8 +306,10 @@ static const struct sunxi_sramc_variant
-
- static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
- .num_emac_clocks = 2,
-+ .has_ths_offset = true,
- };
-
-+#define SUNXI_SRAM_THS_OFFSET_REG 0x0
- #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30
- #define SUNXI_SYS_LDO_CTRL_REG 0x150
-
-@@ -315,6 +318,8 @@ static bool sunxi_sram_regmap_accessible
- {
- const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
-
-+ if (reg == SUNXI_SRAM_THS_OFFSET_REG && variant->has_ths_offset)
-+ return true;
- if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
- reg < SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
- return true;
-@@ -324,6 +329,20 @@ static bool sunxi_sram_regmap_accessible
- return false;
- }
-
-+static void sunxi_sram_lock(void *_lock)
-+{
-+ spinlock_t *lock = _lock;
-+
-+ spin_lock(lock);
-+}
-+
-+static void sunxi_sram_unlock(void *_lock)
-+{
-+ spinlock_t *lock = _lock;
-+
-+ spin_unlock(lock);
-+}
-+
- static struct regmap_config sunxi_sram_regmap_config = {
- .reg_bits = 32,
- .val_bits = 32,
-@@ -333,6 +352,9 @@ static struct regmap_config sunxi_sram_r
- /* other devices have no business accessing other registers */
- .readable_reg = sunxi_sram_regmap_accessible_reg,
- .writeable_reg = sunxi_sram_regmap_accessible_reg,
-+ .lock = sunxi_sram_lock,
-+ .unlock = sunxi_sram_unlock,
-+ .lock_arg = &sram_lock,
- };
-
- static int __init sunxi_sram_probe(struct platform_device *pdev)
+++ /dev/null
-From ebbf19e36d021f253425344b4d4b987f3b7d9be5 Mon Sep 17 00:00:00 2001
-From: Maxim Kiselev <bigunclemax@gmail.com>
-Date: Mon, 18 Dec 2023 00:06:23 +0300
-Subject: [PATCH] thermal/drivers/sun8i: Add D1/T113s THS controller support
-
-This patch adds a thermal sensor controller support for the D1/T113s,
-which is similar to the one on H6, but with only one sensor and
-different scale and offset values.
-
-Signed-off-by: Maxim Kiselev <bigunclemax@gmail.com>
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Reviewed-by: Andre Przywara <andre.przywara@arm.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20231217210629.131486-3-bigunclemax@gmail.com
----
- drivers/thermal/sun8i_thermal.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/drivers/thermal/sun8i_thermal.c
-+++ b/drivers/thermal/sun8i_thermal.c
-@@ -610,6 +610,18 @@ static const struct ths_thermal_chip sun
- .calc_temp = sun8i_ths_calc_temp,
- };
-
-+static const struct ths_thermal_chip sun20i_d1_ths = {
-+ .sensor_num = 1,
-+ .has_bus_clk_reset = true,
-+ .offset = 188552,
-+ .scale = 673,
-+ .temp_data_base = SUN50I_H6_THS_TEMP_DATA,
-+ .calibrate = sun50i_h6_ths_calibrate,
-+ .init = sun50i_h6_thermal_init,
-+ .irq_ack = sun50i_h6_irq_ack,
-+ .calc_temp = sun8i_ths_calc_temp,
-+};
-+
- static const struct of_device_id of_ths_match[] = {
- { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
- { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
-@@ -618,6 +630,7 @@ static const struct of_device_id of_ths_
- { .compatible = "allwinner,sun50i-a100-ths", .data = &sun50i_a100_ths },
- { .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths },
- { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths },
-+ { .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths },
- { /* sentinel */ },
- };
- MODULE_DEVICE_TABLE(of, of_ths_match);
+++ /dev/null
-From 14f118aa50fe7c7c7330f56d007ecacca487cea8 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Mon, 19 Feb 2024 15:36:35 +0000
-Subject: [PATCH] thermal/drivers/sun8i: Explain unknown H6 register value
-
-So far we were ORing in some "unknown" value into the THS control
-register on the Allwinner H6. This part of the register is not explained
-in the H6 manual, but the H616 manual details those bits, and on closer
-inspection the THS IP blocks in both SoCs seem very close:
-- The BSP code for both SoCs writes the same values into THS_CTRL.
-- The reset values of at least the first three registers are the same.
-
-Replace the "unknown" value with its proper meaning: "acquire time",
-most probably the sample part of the sample & hold circuit of the ADC,
-according to its explanation in the H616 manual.
-
-No functional change, just a macro rename and adjustment.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Acked-by: Vasily Khoruzhick <anarsoul@gmail.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20240219153639.179814-4-andre.przywara@arm.com
----
- drivers/thermal/sun8i_thermal.c | 29 ++++++++++++++++-------------
- 1 file changed, 16 insertions(+), 13 deletions(-)
-
---- a/drivers/thermal/sun8i_thermal.c
-+++ b/drivers/thermal/sun8i_thermal.c
-@@ -50,7 +50,8 @@
- #define SUN8I_THS_CTRL2_T_ACQ1(x) ((GENMASK(15, 0) & (x)) << 16)
- #define SUN8I_THS_DATA_IRQ_STS(x) BIT(x + 8)
-
--#define SUN50I_THS_CTRL0_T_ACQ(x) ((GENMASK(15, 0) & (x)) << 16)
-+#define SUN50I_THS_CTRL0_T_ACQ(x) (GENMASK(15, 0) & ((x) - 1))
-+#define SUN50I_THS_CTRL0_T_SAMPLE_PER(x) ((GENMASK(15, 0) & ((x) - 1)) << 16)
- #define SUN50I_THS_FILTER_EN BIT(2)
- #define SUN50I_THS_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
- #define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12)
-@@ -410,25 +411,27 @@ static int sun8i_h3_thermal_init(struct
- return 0;
- }
-
--/*
-- * Without this undocumented value, the returned temperatures would
-- * be higher than real ones by about 20C.
-- */
--#define SUN50I_H6_CTRL0_UNK 0x0000002f
--
- static int sun50i_h6_thermal_init(struct ths_device *tmdev)
- {
- int val;
-
- /*
-- * T_acq = 20us
-- * clkin = 24MHz
-- *
-- * x = T_acq * clkin - 1
-- * = 479
-+ * The manual recommends an overall sample frequency of 50 KHz (20us,
-+ * 480 cycles at 24 MHz), which provides plenty of time for both the
-+ * acquisition time (>24 cycles) and the actual conversion time
-+ * (>14 cycles).
-+ * The lower half of the CTRL register holds the "acquire time", in
-+ * clock cycles, which the manual recommends to be 2us:
-+ * 24MHz * 2us = 48 cycles.
-+ * The high half of THS_CTRL encodes the sample frequency, in clock
-+ * cycles: 24MHz * 20us = 480 cycles.
-+ * This is explained in the H616 manual, but apparently wrongly
-+ * described in the H6 manual, although the BSP code does the same
-+ * for both SoCs.
- */
- regmap_write(tmdev->regmap, SUN50I_THS_CTRL0,
-- SUN50I_H6_CTRL0_UNK | SUN50I_THS_CTRL0_T_ACQ(479));
-+ SUN50I_THS_CTRL0_T_ACQ(48) |
-+ SUN50I_THS_CTRL0_T_SAMPLE_PER(480));
- /* average over 4 samples */
- regmap_write(tmdev->regmap, SUN50I_H6_THS_MFC,
- SUN50I_THS_FILTER_EN |
+++ /dev/null
-From 6c04a419a4c5fb18edefc44dd676fb95c7f6c55d Mon Sep 17 00:00:00 2001
-From: Maksim Kiselev <bigunclemax@gmail.com>
-Date: Mon, 19 Feb 2024 15:36:36 +0000
-Subject: [PATCH] thermal/drivers/sun8i: Extend H6 calibration to support 4
- sensors
-
-The H616 SoC resembles the H6 thermal sensor controller, with a few
-changes like four sensors.
-
-Extend sun50i_h6_ths_calibrate() function to support calibration of
-these sensors.
-
-Co-developed-by: Martin Botka <martin.botka@somainline.org>
-Signed-off-by: Martin Botka <martin.botka@somainline.org>
-Signed-off-by: Maksim Kiselev <bigunclemax@gmail.com>
-Reviewed-by: Andre Przywara <andre.przywara@arm.com>
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Acked-by: Vasily Khoruzhick <anarsoul@gmail.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20240219153639.179814-5-andre.przywara@arm.com
----
- drivers/thermal/sun8i_thermal.c | 28 ++++++++++++++++++++--------
- 1 file changed, 20 insertions(+), 8 deletions(-)
-
---- a/drivers/thermal/sun8i_thermal.c
-+++ b/drivers/thermal/sun8i_thermal.c
-@@ -224,16 +224,21 @@ static int sun50i_h6_ths_calibrate(struc
- struct device *dev = tmdev->dev;
- int i, ft_temp;
-
-- if (!caldata[0] || callen < 2 + 2 * tmdev->chip->sensor_num)
-+ if (!caldata[0])
- return -EINVAL;
-
- /*
- * efuse layout:
- *
-- * 0 11 16 32
-- * +-------+-------+-------+
-- * |temp| |sensor0|sensor1|
-- * +-------+-------+-------+
-+ * 0 11 16 27 32 43 48 57
-+ * +----------+-----------+-----------+-----------+
-+ * | temp | |sensor0| |sensor1| |sensor2| |
-+ * +----------+-----------+-----------+-----------+
-+ * ^ ^ ^
-+ * | | |
-+ * | | sensor3[11:8]
-+ * | sensor3[7:4]
-+ * sensor3[3:0]
- *
- * The calibration data on the H6 is the ambient temperature and
- * sensor values that are filled during the factory test stage.
-@@ -246,9 +251,16 @@ static int sun50i_h6_ths_calibrate(struc
- ft_temp = (caldata[0] & FT_TEMP_MASK) * 100;
-
- for (i = 0; i < tmdev->chip->sensor_num; i++) {
-- int sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK;
-- int cdata, offset;
-- int sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
-+ int sensor_reg, sensor_temp, cdata, offset;
-+
-+ if (i == 3)
-+ sensor_reg = (caldata[1] >> 12)
-+ | ((caldata[2] >> 12) << 4)
-+ | ((caldata[3] >> 12) << 8);
-+ else
-+ sensor_reg = caldata[i + 1] & TEMP_CALIB_MASK;
-+
-+ sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
-
- /*
- * Calibration data is CALIBRATE_DEFAULT - (calculated
+++ /dev/null
-From f8b54d1120b81ed57bed96cc8e814ba08886d1e5 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Mon, 19 Feb 2024 15:36:37 +0000
-Subject: [PATCH] thermal/drivers/sun8i: Add SRAM register access code
-
-The Allwinner H616 SoC needs to clear a bit in one register in the SRAM
-controller, to report reasonable temperature values. On reset, bit 16 in
-register 0x3000000 is set, which leads to the driver reporting
-temperatures around 200C. Clearing this bit brings the values down to the
-expected range. The BSP code does a one-time write in U-Boot, with a
-comment just mentioning the effect on the THS, but offering no further
-explanation.
-
-To not rely on firmware to set things up for us, add code that queries
-the SRAM controller device via a DT phandle link, then clear just this
-single bit.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Acked-by: Vasily Khoruzhick <anarsoul@gmail.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20240219153639.179814-6-andre.przywara@arm.com
----
- drivers/thermal/sun8i_thermal.c | 51 +++++++++++++++++++++++++++++++++
- 1 file changed, 51 insertions(+)
-
---- a/drivers/thermal/sun8i_thermal.c
-+++ b/drivers/thermal/sun8i_thermal.c
-@@ -15,6 +15,7 @@
- #include <linux/module.h>
- #include <linux/nvmem-consumer.h>
- #include <linux/of_device.h>
-+#include <linux/of_platform.h>
- #include <linux/platform_device.h>
- #include <linux/regmap.h>
- #include <linux/reset.h>
-@@ -68,6 +69,7 @@ struct tsensor {
- struct ths_thermal_chip {
- bool has_mod_clk;
- bool has_bus_clk_reset;
-+ bool needs_sram;
- int sensor_num;
- int offset;
- int scale;
-@@ -85,12 +87,16 @@ struct ths_device {
- const struct ths_thermal_chip *chip;
- struct device *dev;
- struct regmap *regmap;
-+ struct regmap_field *sram_regmap_field;
- struct reset_control *reset;
- struct clk *bus_clk;
- struct clk *mod_clk;
- struct tsensor sensor[MAX_SENSOR_NUM];
- };
-
-+/* The H616 needs to have a bit 16 in the SRAM control register cleared. */
-+static const struct reg_field sun8i_ths_sram_reg_field = REG_FIELD(0x0, 16, 16);
-+
- /* Temp Unit: millidegree Celsius */
- static int sun8i_ths_calc_temp(struct ths_device *tmdev,
- int id, int reg)
-@@ -337,6 +343,34 @@ static void sun8i_ths_reset_control_asse
- reset_control_assert(data);
- }
-
-+static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node)
-+{
-+ struct device_node *sram_node;
-+ struct platform_device *sram_pdev;
-+ struct regmap *regmap = NULL;
-+
-+ sram_node = of_parse_phandle(node, "allwinner,sram", 0);
-+ if (!sram_node)
-+ return ERR_PTR(-ENODEV);
-+
-+ sram_pdev = of_find_device_by_node(sram_node);
-+ if (!sram_pdev) {
-+ /* platform device might not be probed yet */
-+ regmap = ERR_PTR(-EPROBE_DEFER);
-+ goto out_put_node;
-+ }
-+
-+ /* If no regmap is found then the other device driver is at fault */
-+ regmap = dev_get_regmap(&sram_pdev->dev, NULL);
-+ if (!regmap)
-+ regmap = ERR_PTR(-EINVAL);
-+
-+ platform_device_put(sram_pdev);
-+out_put_node:
-+ of_node_put(sram_node);
-+ return regmap;
-+}
-+
- static int sun8i_ths_resource_init(struct ths_device *tmdev)
- {
- struct device *dev = tmdev->dev;
-@@ -381,6 +415,19 @@ static int sun8i_ths_resource_init(struc
- if (ret)
- return ret;
-
-+ if (tmdev->chip->needs_sram) {
-+ struct regmap *regmap;
-+
-+ regmap = sun8i_ths_get_sram_regmap(dev->of_node);
-+ if (IS_ERR(regmap))
-+ return PTR_ERR(regmap);
-+ tmdev->sram_regmap_field = devm_regmap_field_alloc(dev,
-+ regmap,
-+ sun8i_ths_sram_reg_field);
-+ if (IS_ERR(tmdev->sram_regmap_field))
-+ return PTR_ERR(tmdev->sram_regmap_field);
-+ }
-+
- ret = sun8i_ths_calibrate(tmdev);
- if (ret)
- return ret;
-@@ -427,6 +474,10 @@ static int sun50i_h6_thermal_init(struct
- {
- int val;
-
-+ /* The H616 needs to have a bit in the SRAM control register cleared. */
-+ if (tmdev->sram_regmap_field)
-+ regmap_field_write(tmdev->sram_regmap_field, 0);
-+
- /*
- * The manual recommends an overall sample frequency of 50 KHz (20us,
- * 480 cycles at 24 MHz), which provides plenty of time for both the
+++ /dev/null
-From e7dbfa19572a1440a2e67ef70f94ff204849a0a8 Mon Sep 17 00:00:00 2001
-From: Martin Botka <martin.botka@somainline.org>
-Date: Mon, 19 Feb 2024 15:36:38 +0000
-Subject: [PATCH] thermal/drivers/sun8i: Add support for H616 THS controller
-
-Add support for the thermal sensor found in H616 SoCs, is the same as
-the H6 thermal sensor controller, but with four sensors.
-Also the registers readings are wrong, unless a bit in the first SYS_CFG
-register cleared, so set exercise the SRAM regmap to take care of that.
-
-Signed-off-by: Martin Botka <martin.botka@somainline.org>
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
-Acked-by: Vasily Khoruzhick <anarsoul@gmail.com>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20240219153639.179814-7-andre.przywara@arm.com
----
- drivers/thermal/sun8i_thermal.c | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/drivers/thermal/sun8i_thermal.c
-+++ b/drivers/thermal/sun8i_thermal.c
-@@ -688,6 +688,20 @@ static const struct ths_thermal_chip sun
- .calc_temp = sun8i_ths_calc_temp,
- };
-
-+static const struct ths_thermal_chip sun50i_h616_ths = {
-+ .sensor_num = 4,
-+ .has_bus_clk_reset = true,
-+ .needs_sram = true,
-+ .ft_deviation = 8000,
-+ .offset = 263655,
-+ .scale = 810,
-+ .temp_data_base = SUN50I_H6_THS_TEMP_DATA,
-+ .calibrate = sun50i_h6_ths_calibrate,
-+ .init = sun50i_h6_thermal_init,
-+ .irq_ack = sun50i_h6_irq_ack,
-+ .calc_temp = sun8i_ths_calc_temp,
-+};
-+
- static const struct of_device_id of_ths_match[] = {
- { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
- { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
-@@ -697,6 +711,7 @@ static const struct of_device_id of_ths_
- { .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths },
- { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths },
- { .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths },
-+ { .compatible = "allwinner,sun50i-h616-ths", .data = &sun50i_h616_ths },
- { /* sentinel */ },
- };
- MODULE_DEVICE_TABLE(of, of_ths_match);
+++ /dev/null
-From 9ac53d5532cc4bb595bbee86ccba2172ccc336c3 Mon Sep 17 00:00:00 2001
-From: Mark Brown <broonie@kernel.org>
-Date: Tue, 23 Jan 2024 23:33:07 +0000
-Subject: [PATCH] thermal/drivers/sun8i: Don't fail probe due to zone
- registration failure
-
-Currently the sun8i thermal driver will fail to probe if any of the
-thermal zones it is registering fails to register with the thermal core.
-Since we currently do not define any trip points for the GPU thermal
-zones on at least A64 or H5 this means that we have no thermal support
-on these platforms:
-
-[ 1.698703] thermal_sys: Failed to find 'trips' node
-[ 1.698707] thermal_sys: Failed to find trip points for thermal-sensor id=1
-
-even though the main CPU thermal zone on both SoCs is fully configured.
-This does not seem ideal, while we may not be able to use all the zones
-it seems better to have those zones which are usable be operational.
-Instead just carry on registering zones if we get any non-deferral
-error, allowing use of those zones which are usable.
-
-This means that we also need to update the interrupt handler to not
-attempt to notify the core for events on zones which we have not
-registered, I didn't see an ability to mask individual interrupts and
-I would expect that interrupts would still be indicated in the ISR even
-if they were masked.
-
-Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
-Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
-Signed-off-by: Mark Brown <broonie@kernel.org>
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-Link: https://lore.kernel.org/r/20240123-thermal-sun8i-registration-v3-1-3e5771b1bbdd@kernel.org
----
- drivers/thermal/sun8i_thermal.c | 16 ++++++++++++++--
- 1 file changed, 14 insertions(+), 2 deletions(-)
-
---- a/drivers/thermal/sun8i_thermal.c
-+++ b/drivers/thermal/sun8i_thermal.c
-@@ -197,6 +197,9 @@ static irqreturn_t sun8i_irq_thread(int
- int i;
-
- for_each_set_bit(i, &irq_bitmap, tmdev->chip->sensor_num) {
-+ /* We allow some zones to not register. */
-+ if (IS_ERR(tmdev->sensor[i].tzd))
-+ continue;
- thermal_zone_device_update(tmdev->sensor[i].tzd,
- THERMAL_EVENT_UNSPECIFIED);
- }
-@@ -531,8 +534,17 @@ static int sun8i_ths_register(struct ths
- i,
- &tmdev->sensor[i],
- &ths_ops);
-- if (IS_ERR(tmdev->sensor[i].tzd))
-- return PTR_ERR(tmdev->sensor[i].tzd);
-+
-+ /*
-+ * If an individual zone fails to register for reasons
-+ * other than probe deferral (eg, a bad DT) then carry
-+ * on, other zones might register successfully.
-+ */
-+ if (IS_ERR(tmdev->sensor[i].tzd)) {
-+ if (PTR_ERR(tmdev->sensor[i].tzd) == -EPROBE_DEFER)
-+ return PTR_ERR(tmdev->sensor[i].tzd);
-+ continue;
-+ }
-
- if (devm_thermal_add_hwmon_sysfs(tmdev->sensor[i].tzd))
- dev_warn(tmdev->dev,
+++ /dev/null
-From f4318af40544b8e7ff5a6b667ede60e6cf808262 Mon Sep 17 00:00:00 2001
-From: Martin Botka <martin.botka@somainline.org>
-Date: Mon, 19 Feb 2024 15:36:39 +0000
-Subject: [PATCH] arm64: dts: allwinner: h616: Add thermal sensor and zones
-
-There are four thermal sensors:
-- CPU
-- GPU
-- VE
-- DRAM
-
-Add the thermal sensor configuration and the thermal zones.
-
-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>
-Link: https://lore.kernel.org/r/20240219153639.179814-8-andre.przywara@arm.com
-Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
----
- .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 88 +++++++++++++++++++
- 1 file changed, 88 insertions(+)
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
-@@ -9,6 +9,7 @@
- #include <dt-bindings/clock/sun6i-rtc.h>
- #include <dt-bindings/reset/sun50i-h616-ccu.h>
- #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
-+#include <dt-bindings/thermal/thermal.h>
-
- / {
- interrupt-parent = <&gic>;
-@@ -138,6 +139,10 @@
- reg = <0x03006000 0x1000>;
- #address-cells = <1>;
- #size-cells = <1>;
-+
-+ ths_calibration: thermal-sensor-calibration@14 {
-+ reg = <0x14 0x8>;
-+ };
- };
-
- watchdog: watchdog@30090a0 {
-@@ -511,6 +516,19 @@
- };
- };
-
-+ ths: thermal-sensor@5070400 {
-+ compatible = "allwinner,sun50i-h616-ths";
-+ reg = <0x05070400 0x400>;
-+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&ccu CLK_BUS_THS>;
-+ clock-names = "bus";
-+ resets = <&ccu RST_BUS_THS>;
-+ nvmem-cells = <&ths_calibration>;
-+ nvmem-cell-names = "calibration";
-+ allwinner,sram = <&syscon>;
-+ #thermal-sensor-cells = <1>;
-+ };
-+
- usbotg: usb@5100000 {
- compatible = "allwinner,sun50i-h616-musb",
- "allwinner,sun8i-h3-musb";
-@@ -755,4 +773,74 @@
- #size-cells = <0>;
- };
- };
-+
-+ thermal-zones {
-+ cpu-thermal {
-+ polling-delay-passive = <500>;
-+ polling-delay = <1000>;
-+ thermal-sensors = <&ths 2>;
-+ sustainable-power = <1000>;
-+
-+ trips {
-+ cpu_threshold: cpu-trip-0 {
-+ temperature = <60000>;
-+ type = "passive";
-+ hysteresis = <0>;
-+ };
-+ cpu_target: cpu-trip-1 {
-+ temperature = <70000>;
-+ type = "passive";
-+ hysteresis = <0>;
-+ };
-+ cpu_critical: cpu-trip-2 {
-+ temperature = <110000>;
-+ type = "critical";
-+ hysteresis = <0>;
-+ };
-+ };
-+ };
-+
-+ gpu-thermal {
-+ polling-delay-passive = <500>;
-+ polling-delay = <1000>;
-+ thermal-sensors = <&ths 0>;
-+ sustainable-power = <1100>;
-+
-+ trips {
-+ gpu_temp_critical: gpu-trip-0 {
-+ temperature = <110000>;
-+ type = "critical";
-+ hysteresis = <0>;
-+ };
-+ };
-+ };
-+
-+ ve-thermal {
-+ polling-delay-passive = <0>;
-+ polling-delay = <0>;
-+ thermal-sensors = <&ths 1>;
-+
-+ trips {
-+ ve_temp_critical: ve-trip-0 {
-+ temperature = <110000>;
-+ type = "critical";
-+ hysteresis = <0>;
-+ };
-+ };
-+ };
-+
-+ ddr-thermal {
-+ polling-delay-passive = <0>;
-+ polling-delay = <0>;
-+ thermal-sensors = <&ths 3>;
-+
-+ trips {
-+ ddr_temp_critical: ddr-trip-0 {
-+ temperature = <110000>;
-+ type = "critical";
-+ hysteresis = <0>;
-+ };
-+ };
-+ };
-+ };
- };
+++ /dev/null
-From a896bc1d79e3c00f0aacfe225499d811775616f3 Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Sun, 10 Oct 2021 21:50:17 +0800
-Subject: [PATCH] arm64: allwinner: add OF node for USB eth on NanoPi R1S H5
-
-This adds the OF node for the USB3 ethernet adapter on the FriendlyARM
-NanoPi R1S H5. Add the correct value for the RTL8153 LED configuration
-register to match the blink behavior of the other port on the device.
-
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
----
- arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts
-@@ -116,6 +116,13 @@
-
- &ehci1 {
- status = "okay";
-+
-+ usb-eth@1 {
-+ compatible = "realtek,rtl8153";
-+ reg = <1>;
-+
-+ realtek,led-data = <0x78>;
-+ };
- };
-
- &ehci2 {
+++ /dev/null
---- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
-@@ -59,7 +59,7 @@
-
- key-sw4 {
- label = "sw4";
-- linux,code = <BTN_0>;
-+ linux,code = <KEY_POWER>;
- gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
- wakeup-source;
- };
-@@ -220,7 +220,7 @@
- };
-
- &usb_otg {
-- dr_mode = "otg";
-+ dr_mode = "host";
- status = "okay";
- };
-
+++ /dev/null
-From 7d87d3dafc4b1ea5659eb71ee6c5fd5308490d1f Mon Sep 17 00:00:00 2001
-From: Oskari Lemmela <oskari@lemmela.net>
-Date: Mon, 31 Dec 2018 07:44:49 +0200
-Subject: [PATCH] arm64: allwinner: a64-sopine: Add Sopine flash partitions.
-
-First 896kB to u-boot. Enough space for SPL, u-boot and ATF.
-Next 128kB to u-boot environment and rest to firmware.
-
-Firmware partition is compatible FIT image dynamic splitting.
-
-Signed-off-by: Oskari Lemmela <oskari@lemmela.net>
----
- .../boot/dts/allwinner/sun50i-a64-sopine.dtsi | 22 +++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
-@@ -58,6 +58,28 @@
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <40000000>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "u-boot";
-+ reg = <0x000000 0x0E0000>;
-+ };
-+
-+ partition@e0000 {
-+ label = "u-boot-env";
-+ reg = <0x0E0000 0x020000>;
-+ };
-+
-+ partition@100000 {
-+ compatible = "denx,fit";
-+ label = "firmware";
-+ reg = <0x100000 0xF00000>;
-+ };
-+ };
- };
- };
-
+++ /dev/null
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -1352,6 +1352,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
- sun8i-a83t-cubietruck-plus.dtb \
- sun8i-a83t-tbs-a711.dtb \
- sun8i-h2-plus-bananapi-m2-zero.dtb \
-+ sun8i-h2-plus-bananapi-p2-zero.dtb \
- sun8i-h2-plus-libretech-all-h3-cc.dtb \
- sun8i-h2-plus-orangepi-r1.dtb \
- sun8i-h2-plus-orangepi-zero.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-p2-zero.dts
-@@ -0,0 +1,279 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+/*
-+ * Copyright (C) 2023 Zoltan HERPAI <wigyori@uid0.hu>
-+ *
-+ * Based on sun8i-h2-plus-bananapi-m2-zero.dts, which is:
-+ * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
-+ */
-+
-+/dts-v1/;
-+#include "sun8i-h3.dtsi"
-+#include "sunxi-common-regulators.dtsi"
-+
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+ model = "Banana Pi BPI-P2-Zero";
-+ compatible = "sinovoip,bpi-p2-zero", "allwinner,sun8i-h2-plus";
-+
-+ aliases {
-+ serial0 = &uart0;
-+ serial1 = &uart1;
-+ };
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ connector {
-+ compatible = "hdmi-connector";
-+ type = "c";
-+
-+ port {
-+ hdmi_con_in: endpoint {
-+ remote-endpoint = <&hdmi_out_con>;
-+ };
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ pwr_led {
-+ label = "bananapi-p2-zero:red:pwr";
-+ gpios = <&r_pio 0 10 GPIO_ACTIVE_LOW>; /* PL10 */
-+ default-state = "on";
-+ };
-+ };
-+
-+ gpio_keys {
-+ compatible = "gpio-keys";
-+
-+ sw4 {
-+ label = "power";
-+ linux,code = <BTN_0>;
-+ gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ reg_vdd_cpux: vdd-cpux-regulator {
-+ compatible = "regulator-gpio";
-+ regulator-name = "vdd-cpux";
-+ regulator-type = "voltage";
-+ regulator-boot-on;
-+ regulator-always-on;
-+ regulator-min-microvolt = <1100000>;
-+ regulator-max-microvolt = <1300000>;
-+ regulator-ramp-delay = <50>; /* 4ms */
-+
-+ gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL1 */
-+ enable-active-high;
-+ gpios-states = <0x1>;
-+ states = <1100000 0>, <1300000 1>;
-+ };
-+
-+ reg_vcc_dram: vcc-dram {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc-dram";
-+ regulator-min-microvolt = <1500000>;
-+ regulator-max-microvolt = <1500000>;
-+ regulator-always-on;
-+ regulator-boot-on;
-+ enable-active-high;
-+ gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; /* PL9 */
-+ vin-supply = <®_vcc5v0>;
-+ };
-+
-+ reg_vcc1v2: vcc1v2 {
-+ compatible = "regulator-fixed";
-+ regulator-name = "vcc1v2";
-+ regulator-min-microvolt = <1200000>;
-+ regulator-max-microvolt = <1200000>;
-+ regulator-always-on;
-+ regulator-boot-on;
-+ enable-active-high;
-+ gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
-+ vin-supply = <®_vcc5v0>;
-+ };
-+
-+ poweroff {
-+ compatible = "regulator-poweroff";
-+ cpu-supply = <®_vcc1v2>;
-+ };
-+
-+ wifi_pwrseq: wifi_pwrseq {
-+ compatible = "mmc-pwrseq-simple";
-+ reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
-+ clocks = <&rtc 1>;
-+ clock-names = "ext_clock";
-+ };
-+};
-+
-+&cpu0 {
-+ cpu-supply = <®_vdd_cpux>;
-+};
-+
-+&de {
-+ status = "okay";
-+};
-+
-+&ehci0 {
-+ status = "okay";
-+};
-+
-+&emac {
-+ phy-handle = <&int_mii_phy>;
-+ phy-mode = "mii";
-+ allwinner,leds-active-low;
-+ status = "okay";
-+};
-+
-+&hdmi {
-+ status = "okay";
-+};
-+
-+&hdmi_out {
-+ hdmi_out_con: endpoint {
-+ remote-endpoint = <&hdmi_con_in>;
-+ };
-+};
-+
-+&mmc0 {
-+ vmmc-supply = <®_vcc3v3>;
-+ bus-width = <4>;
-+ /*
-+ * On the production batch of this board the card detect GPIO is
-+ * high active (card inserted), although on the early samples it's
-+ * low active.
-+ */
-+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
-+ status = "okay";
-+};
-+
-+&mmc1 {
-+ vmmc-supply = <®_vcc3v3>;
-+ vqmmc-supply = <®_vcc3v3>;
-+ mmc-pwrseq = <&wifi_pwrseq>;
-+ bus-width = <4>;
-+ non-removable;
-+ status = "okay";
-+
-+ brcmf: wifi@1 {
-+ reg = <1>;
-+ compatible = "brcm,bcm4329-fmac";
-+ interrupt-parent = <&pio>;
-+ interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 / EINT10 */
-+ interrupt-names = "host-wake";
-+ };
-+};
-+
-+&ohci0 {
-+ status = "okay";
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_pa_pins>;
-+ status = "okay";
-+};
-+
-+&uart1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
-+ uart-has-rtscts;
-+ status = "okay";
-+
-+ bluetooth {
-+ compatible = "brcm,bcm43438-bt";
-+ max-speed = <1500000>;
-+ clocks = <&rtc 1>;
-+ clock-names = "lpo";
-+ vbat-supply = <®_vcc3v3>;
-+ vddio-supply = <®_vcc3v3>;
-+ device-wakeup-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */
-+ host-wakeup-gpios = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */
-+ shutdown-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
-+ };
-+
-+};
-+
-+&pio {
-+ gpio-line-names =
-+ /* PA */
-+ "CON2-P13", "CON2-P11", "CON2-P22", "CON2-P15",
-+ "CON3-P03", "CON3-P02", "CON2-P07", "CON2-P29",
-+ "CON2-P31", "CON2-P33", "CON2-P35", "CON2-P05",
-+ "CON2-P03", "CON2-P08", "CON2-P10", "CON2-P16",
-+ "CON2-P12", "CON2-P37", "CON2-P28", "CON2-P27",
-+ "CON2-P40", "CON2-P38", "", "",
-+ "", "", "", "", "", "", "", "",
-+
-+ /* PB */
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+
-+ /* PC */
-+ "CON2-P19", "CON2-P21", "CON2-P23", "CON2-P24",
-+ "CON2-P18", "", "", "CON2-P26",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+
-+ /* PD */
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "CSI-PWR-EN", "",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+
-+ /* PE */
-+ "CN3-P17", "CN3-P13", "CN3-P09", "CN3-P07",
-+ "CN3-P19", "CN3-P21", "CN3-P22", "CN3-P20",
-+ "CN3-P18", "CN3-P16", "CN3-P14", "CN3-P12",
-+ "CN3-P05", "CN3-P03", "CN3-P06", "CN3-P08",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+
-+ /* PF */
-+ "SDC0-D1", "SDC0-D0", "SDC0-CLK", "SDC0-CMD", "SDC0-D3",
-+ "SDC0-D2", "SDC0-DET", "",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+
-+ /* PG */
-+ "WL-SDIO-CLK", "WL-SDIO-CMD", "WL-SDIO-D0", "WL-SDIO-D1",
-+ "WL-SDIO-D2", "WL-SDIO-D3", "BT-UART-TX", "BT-UART-RX",
-+ "BT-UART-RTS", "BT-UART-CTS", "WL-WAKE-AP", "BT-WAKE-AP",
-+ "BT-RST-N", "AP-WAKE-BT", "", "",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "";
-+};
-+
-+&r_pio {
-+ gpio-line-names =
-+ /* PL */
-+ "", "CPUX-SET", "CON2-P32", "POWER-KEY", "CON2-P36",
-+ "VCC-IO-EN", "USB0-ID", "WL-PWR-EN",
-+ "PWR-STB", "PWR-DRAM", "PWR-LED", "IR-RX", "", "", "", "",
-+ "", "", "", "", "", "", "", "",
-+ "", "", "", "", "", "", "", "";
-+};
-+
-+&usb_otg {
-+ dr_mode = "otg";
-+ status = "okay";
-+};
-+
-+&usbphy {
-+ usb0_id_det-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
-+ /*
-+ * There're two micro-USB connectors, one is power-only and another is
-+ * OTG. The Vbus of these two connectors are connected together, so
-+ * the external USB device will be powered just by the power input
-+ * from the power-only USB port.
-+ */
-+ status = "okay";
-+};
+++ /dev/null
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz>
-Date: Thu, 26 Mar 2020 10:09:19 +0100
-Subject: [PATCH] arm64: dts: allwinner: a64: olinuxino: add status LED aliases
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Petr Štetiar <ynezz@true.cz>
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
-@@ -15,6 +15,10 @@
- aliases {
- ethernet0 = &emac;
- serial0 = &uart0;
-+ led-boot = &led_user;
-+ led-failsafe = &led_user;
-+ led-running = &led_user;
-+ led-upgrade = &led_user;
- };
-
- chosen {
-@@ -35,7 +39,7 @@
- leds {
- compatible = "gpio-leds";
-
-- led-0 {
-+ led_user: led-0 {
- label = "a64-olinuxino:red:user";
- gpios = <&pio 4 17 GPIO_ACTIVE_HIGH>; /* PE17 */
- };
+++ /dev/null
-From 1845163a052efac124f00656eb72f38947630a42 Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Sun, 10 Oct 2021 21:50:18 +0800
-Subject: [PATCH] arm64: dts: allwinner: NanoPi R1S H5: add status LED aliases
-
-Use the SYS LED on the casing for showing system status.
-
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
----
- arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dts
-@@ -23,6 +23,11 @@
- ethernet0 = &emac;
- ethernet1 = &rtl8189etv;
- serial0 = &uart0;
-+
-+ led-boot = &led_sys;
-+ led-failsafe = &led_sys;
-+ led-running = &led_sys;
-+ led-upgrade = &led_sys;
- };
-
- chosen {
-@@ -38,7 +43,7 @@
- gpios = <&pio 0 9 GPIO_ACTIVE_HIGH>;
- };
-
-- led-1 {
-+ led_sys: led-1 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_RED>;
- gpios = <&pio 0 10 GPIO_ACTIVE_HIGH>;
+++ /dev/null
---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts
-@@ -41,3 +41,7 @@
- reg = <1>;
- };
- };
-+
-+&pwm {
-+ status = "okay";
-+};
+++ /dev/null
---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
-@@ -42,6 +42,11 @@
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-+
-+ wifi_pwrseq: wifi_pwrseq {
-+ compatible = "mmc-pwrseq-simple";
-+ reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
-+ };
- };
-
- &ac_power_supply {
-@@ -102,6 +107,21 @@
- reg = <1>;
- };
- };
-+
-+&mmc1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&mmc1_pins>;
-+ vmmc-supply = <®_dldo4>;
-+ vqmmc-supply = <®_eldo1>;
-+ mmc-pwrseq = <&wifi_pwrseq>;
-+ bus-width = <4>;
-+ non-removable;
-+ status = "okay";
-+
-+ rtl8723cs: wifi@1 {
-+ reg = <1>;
-+ };
-+};
-
- &mmc2 {
- pinctrl-names = "default";
---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
-@@ -35,6 +35,11 @@
- };
- };
- };
-+
-+ wifi_pwrseq: wifi_pwrseq {
-+ compatible = "mmc-pwrseq-simple";
-+ reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
-+ };
- };
-
- &codec {
-@@ -124,6 +129,21 @@
- status = "okay";
- };
-
-+&mmc1 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&mmc1_pins>;
-+ vmmc-supply = <®_dldo4>;
-+ vqmmc-supply = <®_eldo1>;
-+ mmc-pwrseq = <&wifi_pwrseq>;
-+ bus-width = <4>;
-+ non-removable;
-+ status = "okay";
-+
-+ rtl8723cs: wifi@1 {
-+ reg = <1>;
-+ };
-+};
-+
- &ohci0 {
- status = "okay";
- };
CONFIG_MICROCODE_LATE_LOADING=y
CONFIG_MIGRATION=y
CONFIG_MITIGATION_RFDS=y
+CONFIG_MITIGATION_SPECTRE_BHI=y
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_SPARSE_IRQ=y
-# CONFIG_SPECTRE_BHI_AUTO is not set
-# CONFIG_SPECTRE_BHI_OFF is not set
-CONFIG_SPECTRE_BHI_ON=y
CONFIG_SPECULATION_MITIGATIONS=y
CONFIG_SRCU=y
# CONFIG_STATIC_CALL_SELFTEST is not set
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_CYRIX_32=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_SPARSE_IRQ=y
-CONFIG_SPECULATION_MITIGATIONS=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
# CONFIG_STATIC_CALL_SELFTEST is not set
# CONFIG_STRICT_SIGALTSTACK_SIZE is not set
Build firmware image for Zynq 7000 SoC devices.
endef
-KERNEL_PATCHVER:=5.15
-KERNEL_TESTING_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.1
include $(INCLUDE_DIR)/target.mk
+++ /dev/null
-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_CRYPTO=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_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_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_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLKSRC_VERSATILE=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_COMPAT_32BIT_TIME=y
-CONFIG_CONNECTOR=y
-CONFIG_CONSOLE_TRANSLATIONS=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_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_RNG2=y
-CONFIG_DCACHE_WORD_ACCESS=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_REMAP=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DRM=y
-CONFIG_DRM_BRIDGE=y
-CONFIG_DRM_FBDEV_EMULATION=y
-CONFIG_DRM_FBDEV_OVERALLOC=100
-CONFIG_DRM_KMS_HELPER=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_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_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_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_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_HANDLE_DOMAIN_IRQ=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_ICST=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_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_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_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_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_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_PROC_EVENTS=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_R8169=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_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_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_INTC is not set
-# 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
default "arm-unknown-linux-gnu" if arm
default "armeb-unknown-linux-gnu" if armeb
default "i486-unknown-linux-gnu" if i386
+ default "loongarch64-unknown-linux-gnu" if loongarch64
default "mips-unknown-linux-gnu" if mips
default "mipsel-unknown-linux-gnu" if mipsel
default "powerpc-unknown-linux-gnu" if powerpc
default "arm-unknown-linux-gnu-" if arm
default "armeb-unknown-linux-gnu-" if armeb
default "i486-unknown-linux-gnu-" if i386
+ default "loongarch64-unknown-linux-gnu-" if loongarch64
default "mips-unknown-linux-gnu-" if mips
default "mipsel-unknown-linux-gnu-" if mipsel
default "powerpc-unknown-linux-gnu-" if powerpc
default "/opt/cross/arm-unknown-linux-gnu" if arm
default "/opt/cross/armeb-unknown-linux-gnu" if armeb
default "/opt/cross/i486-unknown-linux-gnu" if i386
+ default "/opt/cross/loongarch64-unknown-linux-gnu" if loongarch64
default "/opt/cross/mips-unknown-linux-gnu" if mips
default "/opt/cross/mipsel-unknown-linux-gnu" if mipsel
default "/opt/cross/powerpc-unknown-linux-gnu" if powerpc
config GCC_USE_VERSION_13
bool "gcc 13.x"
+
+ config GCC_USE_VERSION_14
+ bool "gcc 14.x"
endchoice
config GCC_USE_GRAPHITE
default y if GCC_USE_VERSION_12
bool
+config GCC_VERSION_14
+ default y if GCC_USE_VERSION_14
+ bool
+
config GCC_VERSION
string
default EXTERNAL_GCC_VERSION if EXTERNAL_TOOLCHAIN && !NATIVE_TOOLCHAIN
default "11.3.0" if GCC_VERSION_11
default "12.3.0" if GCC_VERSION_12
+ default "14.1.0" if GCC_VERSION_14
default "13.2.0"
config GCC_USE_DEFAULT_VERSION
PKG_HASH:=e275e76442a6067341a27f04c5c6b83d8613144004c0413528863dc6b5c743da
endif
+ifeq ($(PKG_VERSION),14.1.0)
+ PKG_HASH:=e283c654987afe3de9d8080bc0bd79534b5ca0d681a73a11ff2b5d3767426840
+endif
+
PATCH_DIR=../patches-$(GCC_MAJOR_VERSION).x
BUGURL=http://bugs.openwrt.org/
--- /dev/null
+From a80c68a08604b0ac625ac7fc59eae40b551b1176 Mon Sep 17 00:00:00 2001
+From: Peng Fan <fanpeng@loongson.cn>
+Date: Wed, 19 Apr 2023 16:23:42 +0800
+Subject: [PATCH] LoongArch: Fix MUSL_DYNAMIC_LINKER
+
+The system based on musl has no '/lib64', so change it.
+
+https://wiki.musl-libc.org/guidelines-for-distributions.html,
+"Multilib/multi-arch" section of this introduces it.
+
+gcc/
+ * config/loongarch/gnu-user.h (MUSL_DYNAMIC_LINKER): Redefine.
+
+Signed-off-by: Peng Fan <fanpeng@loongson.cn>
+Suggested-by: Xi Ruoyao <xry111@xry111.site>
+---
+ gcc/config/loongarch/gnu-user.h | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/gcc/config/loongarch/gnu-user.h b/gcc/config/loongarch/gnu-user.h
+index aecaa02a199..fa1a5211419 100644
+--- a/gcc/config/loongarch/gnu-user.h
++++ b/gcc/config/loongarch/gnu-user.h
+@@ -33,9 +33,14 @@ along with GCC; see the file COPYING3. If not see
+ #define GLIBC_DYNAMIC_LINKER \
+ "/lib" ABI_GRLEN_SPEC "/ld-linux-loongarch-" ABI_SPEC ".so.1"
+
++#define MUSL_ABI_SPEC \
++ "%{mabi=lp64d:-lp64d}" \
++ "%{mabi=lp64f:-lp64f}" \
++ "%{mabi=lp64s:-lp64s}"
++
+ #undef MUSL_DYNAMIC_LINKER
+ #define MUSL_DYNAMIC_LINKER \
+- "/lib" ABI_GRLEN_SPEC "/ld-musl-loongarch-" ABI_SPEC ".so.1"
++ "/lib/ld-musl-loongarch" ABI_GRLEN_SPEC MUSL_ABI_SPEC ".so.1"
+
+ #undef GNU_USER_TARGET_LINK_SPEC
+ #define GNU_USER_TARGET_LINK_SPEC \
+--
+2.39.3
--- /dev/null
+From 8bccee51f0deac64b79cd9ad75df599422f4c8ff Mon Sep 17 00:00:00 2001
+From: Lulu Cheng <chenglulu@loongson.cn>
+Date: Sat, 18 Nov 2023 11:04:42 +0800
+Subject: [PATCH] LoongArch: Modify MUSL_DYNAMIC_LINKER.
+
+Use no suffix at all in the musl dynamic linker name for hard
+float ABI. Use -sf and -sp suffixes in musl dynamic linker name
+for soft float and single precision ABIs. The following table
+outlines the musl interpreter names for the LoongArch64 ABI names.
+
+musl interpreter | LoongArch64 ABI
+--------------------------- | -----------------
+ld-musl-loongarch64.so.1 | loongarch64-lp64d
+ld-musl-loongarch64-sp.so.1 | loongarch64-lp64f
+ld-musl-loongarch64-sf.so.1 | loongarch64-lp64s
+
+gcc/ChangeLog:
+
+ * config/loongarch/gnu-user.h (MUSL_ABI_SPEC): Modify suffix.
+---
+ gcc/config/loongarch/gnu-user.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/gcc/config/loongarch/gnu-user.h b/gcc/config/loongarch/gnu-user.h
+index 9616d6e8a0b..e9f4bcef1d4 100644
+--- a/gcc/config/loongarch/gnu-user.h
++++ b/gcc/config/loongarch/gnu-user.h
+@@ -34,9 +34,9 @@ along with GCC; see the file COPYING3. If not see
+ "/lib" ABI_GRLEN_SPEC "/ld-linux-loongarch-" ABI_SPEC ".so.1"
+
+ #define MUSL_ABI_SPEC \
+- "%{mabi=lp64d:-lp64d}" \
+- "%{mabi=lp64f:-lp64f}" \
+- "%{mabi=lp64s:-lp64s}"
++ "%{mabi=lp64d:}" \
++ "%{mabi=lp64f:-sp}" \
++ "%{mabi=lp64s:-sf}"
+
+ #undef MUSL_DYNAMIC_LINKER
+ #define MUSL_DYNAMIC_LINKER \
+--
+2.39.3
+
--- /dev/null
+commit 81cc26c706b2bc8c8c1eb1a322e5c5157900836e
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Sun Oct 19 21:45:51 2014 +0000
+
+ gcc: do not assume that the Mac OS X filesystem is case insensitive
+
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+
+ SVN-Revision: 42973
+
+--- a/include/filenames.h
++++ b/include/filenames.h
+@@ -44,11 +44,6 @@ extern "C" {
+ # define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c)
+ # define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f)
+ #else /* not DOSish */
+-# if defined(__APPLE__)
+-# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
+-# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1
+-# endif
+-# endif /* __APPLE__ */
+ # define HAS_DRIVE_SPEC(f) (0)
+ # define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c)
+ # define IS_ABSOLUTE_PATH(f) IS_UNIX_ABSOLUTE_PATH (f)
--- /dev/null
+--- a/gcc/real.h
++++ b/gcc/real.h
+@@ -77,8 +77,10 @@ struct GTY(()) real_value {
+ + (REAL_VALUE_TYPE_SIZE%HOST_BITS_PER_WIDE_INT ? 1 : 0)) /* round up */
+
+ /* Verify the guess. */
++#ifndef __LP64__
+ extern char test_real_width
+ [sizeof (REAL_VALUE_TYPE) <= REAL_WIDTH * sizeof (HOST_WIDE_INT) ? 1 : -1];
++#endif
+
+ /* Calculate the format for CONST_DOUBLE. We need as many slots as
+ are necessary to overlay a REAL_VALUE_TYPE on them. This could be
--- /dev/null
+commit 098bd91f5eae625c7d2ee621e10930fc4434e5e2
+Author: Luka Perkov <luka@openwrt.org>
+Date: Tue Feb 26 16:16:33 2013 +0000
+
+ gcc: don't build documentation
+
+ This closes #13039.
+
+ Signed-off-by: Luka Perkov <luka@openwrt.org>
+
+ SVN-Revision: 35807
+
+--- a/gcc/Makefile.in
++++ b/gcc/Makefile.in
+@@ -3549,18 +3549,10 @@ doc/gcc.info: $(TEXI_GCC_FILES)
+ doc/gccint.info: $(TEXI_GCCINT_FILES)
+ doc/cppinternals.info: $(TEXI_CPPINT_FILES)
+
+-doc/%.info: %.texi
+- if [ x$(BUILD_INFO) = xinfo ]; then \
+- $(MAKEINFO) $(MAKEINFOFLAGS) -I . -I $(gcc_docdir) \
+- -I $(gcc_docdir)/include -o $@ $<; \
+- fi
++doc/%.info:
+
+ # Duplicate entry to handle renaming of gccinstall.info
+-doc/gccinstall.info: $(TEXI_GCCINSTALL_FILES)
+- if [ x$(BUILD_INFO) = xinfo ]; then \
+- $(MAKEINFO) $(MAKEINFOFLAGS) -I $(gcc_docdir) \
+- -I $(gcc_docdir)/include -o $@ $<; \
+- fi
++doc/gccinstall.info:
+
+ doc/cpp.dvi: $(TEXI_CPP_FILES)
+ doc/gcc.dvi: $(TEXI_GCC_FILES)
--- /dev/null
+Fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84790.
+MIPS16 functions have a static assembler prologue which clobbers
+registers v0 and v1. Add these register clobbers to function call
+instructions.
+
+--- a/gcc/config/mips/mips.cc
++++ b/gcc/config/mips/mips.cc
+@@ -3227,6 +3227,12 @@ mips_emit_call_insn (rtx pattern, rtx or
+ emit_insn (gen_update_got_version ());
+ }
+
++ if (TARGET_MIPS16 && TARGET_USE_GOT)
++ {
++ clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), MIPS16_PIC_TEMP);
++ clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), MIPS_PROLOGUE_TEMP (word_mode));
++ }
++
+ if (TARGET_MIPS16
+ && TARGET_EXPLICIT_RELOCS
+ && TARGET_CALL_CLOBBERED_GP)
--- /dev/null
+--- a/gcc/gcc.cc
++++ b/gcc/gcc.cc
+@@ -985,7 +985,9 @@ proper position among the other output f
+ #endif
+
+ #ifndef LINK_SSP_SPEC
+-#ifdef TARGET_LIBC_PROVIDES_SSP
++#if DEFAULT_LIBC == LIBC_MUSL
++#define LINK_SSP_SPEC "-lssp_nonshared"
++#elif defined(TARGET_LIBC_PROVIDES_SSP)
+ #define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all" \
+ "|fstack-protector-strong|fstack-protector-explicit:}"
+ #else
--- /dev/null
+commit ecf7671b769fe96f7b5134be442089f8bdba55d2
+Author: Felix Fietkau <nbd@nbd.name>
+Date: Thu Aug 4 20:29:45 2016 +0200
+
+gcc: add a patch to generate better code with Os on mips
+
+Also happens to reduce compressed code size a bit
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+
+--- a/gcc/config/mips/mips.cc
++++ b/gcc/config/mips/mips.cc
+@@ -20444,7 +20444,7 @@ mips_option_override (void)
+ flag_pcc_struct_return = 0;
+
+ /* Decide which rtx_costs structure to use. */
+- if (optimize_size)
++ if (0 && optimize_size)
+ mips_cost = &mips_rtx_cost_optimize_size;
+ else
+ mips_cost = &mips_rtx_cost_data[mips_tune];
--- /dev/null
+commit 8570c4be394cff7282f332f97da2ff569a927ddb
+Author: Imre Kaloz <kaloz@openwrt.org>
+Date: Wed Feb 2 20:06:12 2011 +0000
+
+ fixup arm soft-float symbols
+
+ SVN-Revision: 25325
+
+--- a/libgcc/config/arm/t-linux
++++ b/libgcc/config/arm/t-linux
+@@ -1,6 +1,10 @@
+ LIB1ASMSRC = arm/lib1funcs.S
+ LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \
+- _ctzsi2 _arm_addsubdf3 _arm_addsubsf3
++ _ctzsi2 _arm_addsubdf3 _arm_addsubsf3 \
++ _arm_negdf2 _arm_muldivdf3 _arm_cmpdf2 _arm_unorddf2 \
++ _arm_fixdfsi _arm_fixunsdfsi _arm_truncdfsf2 \
++ _arm_negsf2 _arm_muldivsf3 _arm_cmpsf2 _arm_unordsf2 \
++ _arm_fixsfsi _arm_fixunssfsi
+
+ # Just for these, we omit the frame pointer since it makes such a big
+ # difference.
+--- a/gcc/config/arm/linux-elf.h
++++ b/gcc/config/arm/linux-elf.h
+@@ -58,8 +58,6 @@
+ %{shared:-lc} \
+ %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
+
+-#define LIBGCC_SPEC "%{mfloat-abi=soft*:-lfloat} -lgcc"
+-
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
+
+ #define LINUX_TARGET_LINK_SPEC "%{h*} \
--- /dev/null
+commit c96312958c0621e72c9b32da5bc224ffe2161384
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Mon Oct 19 23:26:09 2009 +0000
+
+ gcc: create a proper libgcc_pic.a static library for relinking (4.3.3+ for now, backport will follow)
+
+ SVN-Revision: 18086
+
+--- a/libgcc/Makefile.in
++++ b/libgcc/Makefile.in
+@@ -940,11 +940,12 @@ $(libgcov-driver-objects): %$(objext): $
+
+ # Static libraries.
+ libgcc.a: $(libgcc-objects)
++libgcc_pic.a: $(libgcc-s-objects)
+ libgcov.a: $(libgcov-objects)
+ libunwind.a: $(libunwind-objects)
+ libgcc_eh.a: $(libgcc-eh-objects)
+
+-libgcc.a libgcov.a libunwind.a libgcc_eh.a:
++libgcc.a libgcov.a libunwind.a libgcc_eh.a libgcc_pic.a:
+ -rm -f $@
+
+ objects="$(objects)"; \
+@@ -968,7 +969,7 @@ all: libunwind.a
+ endif
+
+ ifeq ($(enable_shared),yes)
+-all: libgcc_eh.a libgcc_s$(SHLIB_EXT)
++all: libgcc_eh.a libgcc_pic.a libgcc_s$(SHLIB_EXT)
+ ifneq ($(LIBUNWIND),)
+ all: libunwind$(SHLIB_EXT)
+ libgcc_s$(SHLIB_EXT): libunwind$(SHLIB_EXT)
+@@ -1174,6 +1175,10 @@ install-shared:
+ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_eh.a
+ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_eh.a
+
++ $(INSTALL_DATA) libgcc_pic.a $(mapfile) $(DESTDIR)$(inst_libdir)/
++ chmod 644 $(DESTDIR)$(inst_libdir)/libgcc_pic.a
++ $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc_pic.a
++
+ $(subst @multilib_dir@,$(MULTIDIR),$(subst \
+ @shlib_base_name@,libgcc_s,$(subst \
+ @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIB_INSTALL))))
--- /dev/null
+commit 7edc8ca5456d9743dd0075eb3cc5b04f4f24c8cc
+Author: Imre Kaloz <kaloz@openwrt.org>
+Date: Wed Feb 2 19:34:36 2011 +0000
+
+ add armv4 fixup patches
+
+ SVN-Revision: 25322
+
+
+--- a/gcc/config/arm/linux-eabi.h
++++ b/gcc/config/arm/linux-eabi.h
+@@ -88,10 +88,15 @@
+ #define MUSL_DYNAMIC_LINKER \
+ "/lib/ld-musl-arm" MUSL_DYNAMIC_LINKER_E "%{mfloat-abi=hard:hf}%{mfdpic:-fdpic}.so.1"
+
++/* For armv4 we pass --fix-v4bx to linker to support EABI */
++#undef TARGET_FIX_V4BX_SPEC
++#define TARGET_FIX_V4BX_SPEC " %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*"\
++ "|march=armv4|mcpu=fa526|mcpu=fa626:--fix-v4bx}"
++
+ /* At this point, bpabi.h will have clobbered LINK_SPEC. We want to
+ use the GNU/Linux version, not the generic BPABI version. */
+ #undef LINK_SPEC
+-#define LINK_SPEC EABI_LINK_SPEC \
++#define LINK_SPEC EABI_LINK_SPEC TARGET_FIX_V4BX_SPEC \
+ LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \
+ LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC)
+
--- /dev/null
+commit dcfc40358b5a3cae7320c17f8d1cebd5ad5540cd
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Sun Feb 12 20:25:47 2012 +0000
+
+ gcc 4.6: port over the missing patch 850-use_shared_libgcc.patch to prevent libgcc crap from leaking into every single binary
+
+ SVN-Revision: 30486
+--- a/gcc/config/arm/linux-eabi.h
++++ b/gcc/config/arm/linux-eabi.h
+@@ -129,10 +129,6 @@
+ "%{Ofast|ffast-math|funsafe-math-optimizations:%{!shared:crtfastmath.o%s}} " \
+ LINUX_OR_ANDROID_LD (GNU_USER_TARGET_ENDFILE_SPEC, ANDROID_ENDFILE_SPEC)
+
+-/* Use the default LIBGCC_SPEC, not the version in linux-elf.h, as we
+- do not use -lfloat. */
+-#undef LIBGCC_SPEC
+-
+ /* Clear the instruction cache from `beg' to `end'. This is
+ implemented in lib1funcs.S, so ensure an error if this definition
+ is used. */
+--- a/gcc/config/linux.h
++++ b/gcc/config/linux.h
+@@ -58,6 +58,10 @@ see the files COPYING3 and COPYING.RUNTI
+ builtin_assert ("system=posix"); \
+ } while (0)
+
++#ifndef LIBGCC_SPEC
++#define LIBGCC_SPEC "%{static|static-libgcc:-lgcc}%{!static:%{!static-libgcc:-lgcc_s}}"
++#endif
++
+ /* Determine which dynamic linker to use depending on whether GLIBC or
+ uClibc or Bionic or musl is the default C library and whether
+ -muclibc or -mglibc or -mbionic or -mmusl has been passed to change
+--- a/libgcc/mkmap-symver.awk
++++ b/libgcc/mkmap-symver.awk
+@@ -136,5 +136,5 @@ function output(lib) {
+ else if (inherit[lib])
+ printf("} %s;\n", inherit[lib]);
+ else
+- printf ("\n local:\n\t*;\n};\n");
++ printf ("\n\t*;\n};\n");
+ }
+--- a/gcc/config/rs6000/linux.h
++++ b/gcc/config/rs6000/linux.h
+@@ -70,6 +70,9 @@
+ #undef CPP_OS_DEFAULT_SPEC
+ #define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
+
++#undef LIBGCC_SPEC
++#define LIBGCC_SPEC "%{!static:%{!static-libgcc:-lgcc_s}} -lgcc"
++
+ #undef LINK_SHLIB_SPEC
+ #define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}} \
+ %{static-pie:-static -pie --no-dynamic-linker -z text}"
--- /dev/null
+commit 64661de100da1ec1061ef3e5e400285dce115e6b
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Sun May 10 13:16:35 2015 +0000
+
+ gcc: add some size optimization patches
+
+ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+
+ SVN-Revision: 45664
+
+--- a/libgcc/config/t-libunwind
++++ b/libgcc/config/t-libunwind
+@@ -2,8 +2,7 @@
+
+ HOST_LIBGCC2_CFLAGS += -DUSE_GAS_SYMVER
+
+-LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c \
+- $(srcdir)/unwind-compat.c $(srcdir)/unwind-dw2-fde-compat.c
++LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
+ LIB2ADDEHSTATIC = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
+
+ # Override the default value from t-slibgcc-elf-ver and mention -lunwind
--- /dev/null
+--- a/gcc/config/rs6000/rs6000-logue.cc
++++ b/gcc/config/rs6000/rs6000-logue.cc
+@@ -344,7 +344,7 @@ rs6000_savres_strategy (rs6000_stack_t *
+ /* Define cutoff for using out-of-line functions to save registers. */
+ if (DEFAULT_ABI == ABI_V4 || TARGET_ELF)
+ {
+- if (!optimize_size)
++ if (1)
+ {
+ strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
+ strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
--- /dev/null
+--- a/libgcc/crtstuff.c
++++ b/libgcc/crtstuff.c
+@@ -152,7 +152,7 @@ call_ ## FUNC (void) \
+ #endif
+
+ #if !defined(USE_TM_CLONE_REGISTRY) && defined(OBJECT_FORMAT_ELF)
+-# define USE_TM_CLONE_REGISTRY 1
++# define USE_TM_CLONE_REGISTRY 0
+ #elif !defined(USE_TM_CLONE_REGISTRY)
+ # define USE_TM_CLONE_REGISTRY 0
+ #endif
--- /dev/null
+--- a/libgcc/config/mips/t-mips16
++++ b/libgcc/config/mips/t-mips16
+@@ -42,3 +42,6 @@ SYNC_CFLAGS = -mno-mips16
+
+ # Version these symbols if building libgcc.so.
+ SHLIB_MAPFILES += $(srcdir)/config/mips/libgcc-mips16.ver
++
++CRTSTUFF_T_CFLAGS += -mno-mips16
++CRTSTUFF_T_CFLAGS_S += -mno-mips16
--- /dev/null
+commit 99368862e44740ff4fd33760893f04e14f9dbdf1
+Author: Felix Fietkau <nbd@openwrt.org>
+Date: Tue Jul 31 00:52:27 2007 +0000
+
+ Port the mbsd_multi patch from freewrt, which adds -fhonour-copts. This will emit warnings in packages that don't use our target cflags properly
+
+ SVN-Revision: 8256
+
+ This patch brings over a feature from MirBSD:
+ * -fhonour-copts
+ If this option is not given, it's warned (depending
+ on environment variables). This is to catch errors
+ of misbuilt packages which override CFLAGS themselves.
+
+ This patch was authored by Thorsten Glaser <tg at mirbsd.de>
+ with copyright assignment to the FSF in effect.
+
+--- a/gcc/c-family/c-opts.cc
++++ b/gcc/c-family/c-opts.cc
+@@ -108,6 +108,9 @@ static size_t include_cursor;
+ /* Whether any standard preincluded header has been preincluded. */
+ static bool done_preinclude;
+
++/* Check if a port honours COPTS. */
++static int honour_copts = 0;
++
+ static void handle_OPT_d (const char *);
+ static void set_std_cxx98 (int);
+ static void set_std_cxx11 (int);
+@@ -498,6 +501,12 @@ c_common_handle_option (size_t scode, co
+ flag_no_builtin = !value;
+ break;
+
++ case OPT_fhonour_copts:
++ if (c_language == clk_c) {
++ honour_copts++;
++ }
++ break;
++
+ case OPT_fconstant_string_class_:
+ constant_string_class_name = arg;
+ break;
+@@ -1291,6 +1300,47 @@ c_common_init (void)
+ return false;
+ }
+
++ if (c_language == clk_c) {
++ char *ev = getenv ("GCC_HONOUR_COPTS");
++ int evv;
++ if (ev == NULL)
++ evv = -1;
++ else if ((*ev == '0') || (*ev == '\0'))
++ evv = 0;
++ else if (*ev == '1')
++ evv = 1;
++ else if (*ev == '2')
++ evv = 2;
++ else if (*ev == 's')
++ evv = -1;
++ else {
++ warning (0, "unknown GCC_HONOUR_COPTS value, assuming 1");
++ evv = 1; /* maybe depend this on something like MIRBSD_NATIVE? */
++ }
++ if (evv == 1) {
++ if (honour_copts == 0) {
++ error ("someone does not honour COPTS at all in lenient mode");
++ return false;
++ } else if (honour_copts != 1) {
++ warning (0, "someone does not honour COPTS correctly, passed %d times",
++ honour_copts);
++ }
++ } else if (evv == 2) {
++ if (honour_copts == 0) {
++ error ("someone does not honour COPTS at all in strict mode");
++ return false;
++ } else if (honour_copts != 1) {
++ error ("someone does not honour COPTS correctly, passed %d times",
++ honour_copts);
++ return false;
++ }
++ } else if (evv == 0) {
++ if (honour_copts != 1)
++ inform (UNKNOWN_LOCATION, "someone does not honour COPTS correctly, passed %d times",
++ honour_copts);
++ }
++ }
++
+ return true;
+ }
+
+--- a/gcc/c-family/c.opt
++++ b/gcc/c-family/c.opt
+@@ -1910,6 +1910,9 @@ C++ ObjC++ Optimization Alias(fexception
+ fhonor-std
+ C++ ObjC++ WarnRemoved
+
++fhonour-copts
++C ObjC C++ ObjC++ RejectNegative
++
+ fhosted
+ C ObjC
+ Assume normal C execution environment.
+--- a/gcc/common.opt
++++ b/gcc/common.opt
+@@ -1881,6 +1881,9 @@ Enum(hardcfr_check_noreturn_calls) Strin
+ EnumValue
+ Enum(hardcfr_check_noreturn_calls) String(always) Value(HCFRNR_ALWAYS)
+
++fhonour-copts
++Common RejectNegative
++
+ ; Nonzero means ignore `#ident' directives. 0 means handle them.
+ ; Generate position-independent code for executables if possible
+ ; On SVR4 targets, it also controls whether or not to emit a
+--- a/gcc/doc/invoke.texi
++++ b/gcc/doc/invoke.texi
+@@ -10597,6 +10597,17 @@ This option is only supported for C and
+
+ This warning is upgraded to an error by @option{-pedantic-errors}.
+
++@item -fhonour-copts
++@opindex fhonour-copts
++If @env{GCC_HONOUR_COPTS} is set to 1, abort if this option is not
++given at least once, and warn if it is given more than once.
++If @env{GCC_HONOUR_COPTS} is set to 2, abort if this option is not
++given exactly once.
++If @env{GCC_HONOUR_COPTS} is set to 0 or unset, warn if this option
++is not given exactly once.
++The warning is quelled if @env{GCC_HONOUR_COPTS} is set to @samp{s}.
++This flag and environment variable only affect the C language.
++
+ @opindex Wstack-protector
+ @opindex Wno-stack-protector
+ @item -Wstack-protector
+--- a/gcc/opts.cc
++++ b/gcc/opts.cc
+@@ -2833,6 +2833,9 @@ common_handle_option (struct gcc_options
+ add_comma_separated_to_vector (&opts->x_flag_ignored_attributes, arg);
+ break;
+
++ case OPT_fhonour_copts:
++ break;
++
+ case OPT_Werror:
+ dc->set_warning_as_error_requested (value);
+ break;
--- /dev/null
+Author: Jo-Philipp Wich <jow@openwrt.org>
+Date: Sat Apr 21 03:02:39 2012 +0000
+
+ gcc: add patch to make the getenv() spec function nonfatal if requested environment variable is unset
+
+ SVN-Revision: 31390
+
+--- a/gcc/gcc.cc
++++ b/gcc/gcc.cc
+@@ -10319,8 +10319,10 @@ getenv_spec_function (int argc, const ch
+ }
+
+ if (!value)
+- fatal_error (input_location,
+- "environment variable %qs not defined", varname);
++ {
++ warning (input_location, "environment variable %qs not defined", varname);
++ value = "";
++ }
+
+ /* We have to escape every character of the environment variable so
+ they are not interpreted as active spec characters. A
--- /dev/null
+From dda6b050cd74a352670787a294596a9c56c21327 Mon Sep 17 00:00:00 2001
+From: Yousong Zhou <yszhou4tech@gmail.com>
+Date: Fri, 4 May 2018 18:20:53 +0800
+Subject: [PATCH] gotools: fix compilation when making cross compiler
+
+libgo is "the runtime support library for the Go programming language.
+This library is intended for use with the Go frontend."
+
+gccgo will link target files with libgo.so which depends on libgcc_s.so.1, but
+the linker will complain that it cannot find it. That's because shared libgcc
+is not present in the install directory yet. libgo.so was made without problem
+because gcc will emit -lgcc_s when compiled with -shared option. When gotools
+were being made, it was supplied with -static-libgcc thus no link option was
+provided. Check LIBGO in gcc/go/gcc-spec.c for how gccgo make a builtin spec
+for linking with libgo.so
+
+- GccgoCrossCompilation, https://github.com/golang/go/wiki/GccgoCrossCompilation
+- Cross-building instructions, http://www.eglibc.org/archives/patches/msg00078.html
+
+When 3-pass GCC compilation is used, shared libgcc runtime libraries will be
+available after gcc pass2 completed and will meet the gotools link requirement
+at gcc pass3
+---
+ gotools/Makefile.am | 4 +++-
+ gotools/Makefile.in | 4 +++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/gotools/Makefile.am
++++ b/gotools/Makefile.am
+@@ -26,6 +26,7 @@ PWD_COMMAND = $${PWDCMD-pwd}
+ STAMP = echo timestamp >
+
+ libgodir = ../$(target_noncanonical)/libgo
++libgccdir = ../$(target_noncanonical)/libgcc
+ LIBGODEP = $(libgodir)/libgo.la
+
+ LIBGOTOOL = $(libgodir)/libgotool.a
+@@ -41,7 +42,8 @@ GOCFLAGS = $(CFLAGS_FOR_TARGET)
+ GOCOMPILE = $(GOCOMPILER) $(GOCFLAGS)
+
+ AM_GOCFLAGS = -I $(libgodir)
+-AM_LDFLAGS = -L $(libgodir) -L $(libgodir)/.libs
++AM_LDFLAGS = -L $(libgodir) -L $(libgodir)/.libs \
++ -L $(libgccdir) -L $(libgccdir)/.libs -lgcc_s
+ GOLINK = $(GOCOMPILER) $(GOCFLAGS) $(AM_GOCFLAGS) $(LDFLAGS) $(AM_LDFLAGS) -o $@
+
+ libgosrcdir = $(srcdir)/../libgo/go
+--- a/gotools/Makefile.in
++++ b/gotools/Makefile.in
+@@ -337,6 +337,7 @@ mkinstalldirs = $(SHELL) $(toplevel_srcd
+ PWD_COMMAND = $${PWDCMD-pwd}
+ STAMP = echo timestamp >
+ libgodir = ../$(target_noncanonical)/libgo
++libgccdir = ../$(target_noncanonical)/libgcc
+ LIBGODEP = $(libgodir)/libgo.la
+ LIBGOTOOL = $(libgodir)/libgotool.a
+ @NATIVE_FALSE@GOCOMPILER = $(GOC)
+@@ -346,7 +347,8 @@ LIBGOTOOL = $(libgodir)/libgotool.a
+ GOCFLAGS = $(CFLAGS_FOR_TARGET)
+ GOCOMPILE = $(GOCOMPILER) $(GOCFLAGS)
+ AM_GOCFLAGS = -I $(libgodir)
+-AM_LDFLAGS = -L $(libgodir) -L $(libgodir)/.libs
++AM_LDFLAGS = -L $(libgodir) -L $(libgodir)/.libs \
++ -L $(libgccdir) -L $(libgccdir)/.libs -lgcc_s
+ GOLINK = $(GOCOMPILER) $(GOCFLAGS) $(AM_GOCFLAGS) $(LDFLAGS) $(AM_LDFLAGS) -o $@
+ libgosrcdir = $(srcdir)/../libgo/go
+ cmdsrcdir = $(libgosrcdir)/cmd
--- /dev/null
+commit 9c6e71079b46ad5433165feaa2001450f2017b56
+Author: Przemysław Buczkowski <prem@prem.moe>
+Date: Mon Aug 16 13:16:21 2021 +0100
+
+ GCC: Patch for Apple Silicon compatibility
+
+ This patch fixes a linker error occuring when compiling
+ the cross-compiler on macOS and ARM64 architecture.
+
+ Adapted from:
+ https://github.com/richfelker/musl-cross-make/issues/116#issuecomment-823612404
+
+ Change-Id: Ia3ee98a163bbb62689f42e2da83a5ef36beb0913
+ Reviewed-on: https://review.haiku-os.org/c/buildtools/+/4329
+ Reviewed-by: John Scipione <jscipione@gmail.com>
+ Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
+
+--- a/gcc/config/aarch64/aarch64.h
++++ b/gcc/config/aarch64/aarch64.h
+@@ -1410,7 +1410,7 @@ extern enum aarch64_code_model aarch64_c
+
+ /* Extra specs when building a native AArch64-hosted compiler.
+ Option rewriting rules based on host system. */
+-#if defined(__aarch64__)
++#if defined(__aarch64__) && ! defined(__APPLE__)
+ extern const char *host_detect_local_cpu (int argc, const char **argv);
+ #define HAVE_LOCAL_CPU_DETECT
+ # define EXTRA_SPEC_FUNCTIONS \
+--- a/gcc/config/host-darwin.cc
++++ b/gcc/config/host-darwin.cc
+@@ -23,6 +23,8 @@
+ #include "options.h"
+ #include "diagnostic-core.h"
+ #include "config/host-darwin.h"
++#include "hosthooks.h"
++#include "hosthooks-def.h"
+ #include <errno.h>
+
+ /* For Darwin (macOS only) platforms, without ASLR (PIE) enabled on the
+@@ -181,3 +183,5 @@ darwin_gt_pch_use_address (void *&addr,
+
+ return 1;
+ }
++
++const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
include $(TOPDIR)/rules.mk
PKG_NAME:=glibc
-PKG_VERSION:=2.37
+PKG_VERSION:=2.38
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=eee7525d35ec16bbe81435e41079ab72519d825c
-PKG_MIRROR_HASH:=fad5a67d9622b75bce5e3e8c91b07a6df0bf8b21cb001a6d06019a6ce4cff31f
+PKG_SOURCE_VERSION:=e9f05fa1c62c8044ff025963498063f73eb51c5f
+PKG_MIRROR_HASH:=fd61eb2caea0d4100638b8aa8285b0f1bc23af921c376516307c9ab8ac307739
PKG_SOURCE_URL:=https://sourceware.org/git/glibc.git
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.zst
PKG_CPE_ID:=cpe:/a:gnu:glibc
HOST_BUILD_DIR:=$(BUILD_DIR_TOOLCHAIN)/$(PKG_SOURCE_SUBDIR)
--without-gd \
--without-cvs \
--enable-add-ons \
+ --enable-crypt \
--$(if $(CONFIG_SOFT_FLOAT),without,with)-fp \
$(if $(CONFIG_PKG_CC_STACKPROTECTOR_REGULAR),--enable-stack-protector=yes) \
$(if $(CONFIG_PKG_CC_STACKPROTECTOR_STRONG),--enable-stack-protector=strong) \
$(if $(CONFIG_PKG_CC_STACKPROTECTOR_ALL),--enable-stack-protector=all) \
$(if $(CONFIG_PKG_RELRO_FULL),--enable-bind-now) \
+ $(if $(CONFIG_PKG_FORTIFY_SOURCE_1),--enable-fortify-source=1) \
+ $(if $(CONFIG_PKG_FORTIFY_SOURCE_2),--enable-fortify-source=2) \
--enable-kernel=5.15.0
export libc_cv_ssp=no
int totfails = 0;
int main (int argc, char *argv[]);
-@@ -119,13 +103,3 @@ put8 (char *cp)
+@@ -123,13 +107,3 @@ put8 (char *cp)
printf("%02x", t);
}
}
* Encode Binary Data:: Encoding and Decoding of Binary Data.
* Argz and Envz Vectors:: Null-separated string vectors.
@end menu
-@@ -2423,73 +2423,73 @@ functionality under a different name, su
+@@ -2512,73 +2512,73 @@ functionality under a different name, su
systems it may be in @file{strings.h} instead.
@end deftypefun
range [FROM - N + 1, FROM - 1]. If N is odd the first byte in FROM
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
-@@ -984,6 +984,12 @@ extern int getsubopt (char **__restrict
+@@ -1103,6 +1103,12 @@ extern int getsubopt (char **__restrict
#endif
--- a/Makeconfig
+++ b/Makeconfig
-@@ -631,6 +631,9 @@ else
+@@ -632,6 +632,9 @@ else
default-rpath = $(libdir)
endif
--- /dev/null
+--- a/Makefile
++++ b/Makefile
+@@ -218,6 +218,7 @@ $(DESTDIR)$(includedir)/%: $(srcdir)/inc
+
+ $(DESTDIR)$(LDSO_PATHNAME): $(DESTDIR)$(libdir)/libc.so
+ $(INSTALL) -D -l libc.so $@ || true
++ $(if $(filter loongarch64,$(ARCH)$(SUBARCH)),$(INSTALL) -D -l libc.so $(subst $(ARCH)$(SUBARCH).so.1,loongarch-lp64d.so.1,$@) || true)
+
+ install-libs: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(if $(SHARED_LIBS),$(DESTDIR)$(LDSO_PATHNAME),)
+
PKG_NAME:=elfutils
PKG_VERSION:=0.191
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://sourceware.org/$(PKG_NAME)/ftp/$(PKG_VERSION)
PKG_GNULIB_MODS = \
argp \
- dirname \
fts \
obstack \
progname \
+}
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
-@@ -31,6 +31,8 @@
+@@ -31,6 +31,7 @@
#include <libdwfl.h>
#include <libebl.h>
+#include <libeu.h>
-+#include <dirname.h>
#include <assert.h>
#include <dirent.h>
#include <errno.h>
+#endif
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
-@@ -32,8 +32,10 @@
+@@ -32,10 +32,10 @@
#include <stdbool.h>
#include <pthread.h>
+#include <libeu.h>
#include <libdw.h>
#include <dwarf.h>
-+#include <dirname.h>
-
+-
/* Known location expressions already decoded. */
+ struct loc_s
+ {
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -34,14 +34,12 @@ endif
--- /dev/null
+From bfba6445a778007f40af5cbfbe725e12c0fcafc6 Mon Sep 17 00:00:00 2001
+From: Tomas Volf <~@wolfsden.cz>
+Date: Tue, 5 Mar 2024 22:25:20 +0100
+Subject: [PATCH] gm_utils.cpp: Call clear instead of empty.
+
+Since the intention seem to be to erase the next word, I believe calling empty
+was a mistake and it should have been clear. Empty does nothing in this
+context.
+
+* src/gm_utils.cpp (wrap_cstr): Call clear.
+---
+ src/gm_utils.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/src/gm_utils.cpp
++++ b/src/gm_utils.cpp
+@@ -311,7 +311,7 @@ void wrap_cstr(string& wrapped, unsigned
+ // trim leading spaces
+ std::size_t pos = next_word.find_first_not_of(' ');
+ if( pos == std::string::npos )
+- next_word.empty();
++ next_word.clear();
+ else if( pos )
+ next_word.erase( 0, pos );
+
--- /dev/null
+From a3d0a0419a35bef9b80a6a12432ab30e2d1e0f5a Mon Sep 17 00:00:00 2001
+From: Tomas Volf <~@wolfsden.cz>
+Date: Tue, 5 Mar 2024 22:27:42 +0100
+Subject: [PATCH] gm_utils.h: Drop std::unary_function.
+
+I am not sure what it does, it is deprecated/removed (depending on C++ version)
+and the advice seems to be that is just is not necessary. So just remove it.
+
+* src/gm_utils.h (print_f, pair_print_f): Drop std::unary_function.
+---
+ src/gm_utils.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/src/gm_utils.h
++++ b/src/gm_utils.h
+@@ -117,7 +117,7 @@ bool string_contains(const char *s, cons
+ * Function object to print something into a stream (to be used with for_each)
+ */
+ template<class T>
+-struct print_f : public std::unary_function<T, void>
++struct print_f
+ {
+ print_f(std::ostream& out, const string &s = ", ") : os(out), sep(s) {}
+ void operator() (T x) { os << x << sep; }
+@@ -129,7 +129,7 @@ struct print_f : public std::unary_funct
+ * Function object to print a pair into two streams (to be used with for_each)
+ */
+ template<class T>
+-struct pair_print_f : public std::unary_function<T, void>
++struct pair_print_f
+ {
+ pair_print_f(std::ostream& out1, std::ostream& out2, const string &s = ", ") :
+ os1(out1), os2(out2), sep(s) {}
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __ASM_GENERIC_BITS_PER_LONG
+#define __ASM_GENERIC_BITS_PER_LONG
+
+#ifndef __BITS_PER_LONG
+/*
+ * In order to keep safe and avoid regression, only unify uapi
+ * bitsperlong.h for some archs which are using newer toolchains
+ * that have the definitions of __CHAR_BIT__ and __SIZEOF_LONG__.
+ * See the following link for more info:
+ * https://lore.kernel.org/linux-arch/b9624545-2c80-49a1-ac3c-39264a591f7b@app.fastmail.com/
+ */
+#if defined(__CHAR_BIT__) && defined(__SIZEOF_LONG__)
+#define __BITS_PER_LONG (__CHAR_BIT__ * __SIZEOF_LONG__)
+#else
+/*
+ * There seems to be no way of detecting this automatically from user
+ * space, so 64 bit architectures should override this in their
+ * bitsperlong.h. In particular, an architecture that supports
+ * both 32 and 64 bit user space must not rely on CONFIG_64BIT
+ * to decide it, but rather check a compiler provided macro.
+ */
+#define __BITS_PER_LONG 32
+#endif
+#endif
+
+#endif /* __ASM_GENERIC_BITS_PER_LONG */
--- /dev/null
+#ifndef __ASM_BYTEORDER_H
+#define __ASM_BYTEORDER_H
+
+#include <endian.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#include <linux/byteorder/little_endian.h>
+#else
+#include <linux/byteorder/big_endian.h>
+#endif
+
+#endif
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_GENERIC_ERRNO_BASE_H
+#define _ASM_GENERIC_ERRNO_BASE_H
+
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Argument list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+
+#endif
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_GENERIC_ERRNO_H
+#define _ASM_GENERIC_ERRNO_H
+
+#include <asm/errno-base.h>
+
+#define EDEADLK 35 /* Resource deadlock would occur */
+#define ENAMETOOLONG 36 /* File name too long */
+#define ENOLCK 37 /* No record locks available */
+
+/*
+ * This error code is special: arch syscall entry code will return
+ * -ENOSYS if users try to call a syscall that doesn't exist. To keep
+ * failures of syscalls that really do exist distinguishable from
+ * failures due to attempts to use a nonexistent syscall, syscall
+ * implementations should refrain from returning -ENOSYS.
+ */
+#define ENOSYS 38 /* Invalid system call number */
+
+#define ENOTEMPTY 39 /* Directory not empty */
+#define ELOOP 40 /* Too many symbolic links encountered */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define ENOMSG 42 /* No message of desired type */
+#define EIDRM 43 /* Identifier removed */
+#define ECHRNG 44 /* Channel number out of range */
+#define EL2NSYNC 45 /* Level 2 not synchronized */
+#define EL3HLT 46 /* Level 3 halted */
+#define EL3RST 47 /* Level 3 reset */
+#define ELNRNG 48 /* Link number out of range */
+#define EUNATCH 49 /* Protocol driver not attached */
+#define ENOCSI 50 /* No CSI structure available */
+#define EL2HLT 51 /* Level 2 halted */
+#define EBADE 52 /* Invalid exchange */
+#define EBADR 53 /* Invalid request descriptor */
+#define EXFULL 54 /* Exchange full */
+#define ENOANO 55 /* No anode */
+#define EBADRQC 56 /* Invalid request code */
+#define EBADSLT 57 /* Invalid slot */
+
+#define EDEADLOCK EDEADLK
+
+#define EBFONT 59 /* Bad font file format */
+#define ENOSTR 60 /* Device not a stream */
+#define ENODATA 61 /* No data available */
+#define ETIME 62 /* Timer expired */
+#define ENOSR 63 /* Out of streams resources */
+#define ENONET 64 /* Machine is not on the network */
+#define ENOPKG 65 /* Package not installed */
+#define EREMOTE 66 /* Object is remote */
+#define ENOLINK 67 /* Link has been severed */
+#define EADV 68 /* Advertise error */
+#define ESRMNT 69 /* Srmount error */
+#define ECOMM 70 /* Communication error on send */
+#define EPROTO 71 /* Protocol error */
+#define EMULTIHOP 72 /* Multihop attempted */
+#define EDOTDOT 73 /* RFS specific error */
+#define EBADMSG 74 /* Not a data message */
+#define EOVERFLOW 75 /* Value too large for defined data type */
+#define ENOTUNIQ 76 /* Name not unique on network */
+#define EBADFD 77 /* File descriptor in bad state */
+#define EREMCHG 78 /* Remote address changed */
+#define ELIBACC 79 /* Can not access a needed shared library */
+#define ELIBBAD 80 /* Accessing a corrupted shared library */
+#define ELIBSCN 81 /* .lib section in a.out corrupted */
+#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
+#define ELIBEXEC 83 /* Cannot exec a shared library directly */
+#define EILSEQ 84 /* Illegal byte sequence */
+#define ERESTART 85 /* Interrupted system call should be restarted */
+#define ESTRPIPE 86 /* Streams pipe error */
+#define EUSERS 87 /* Too many users */
+#define ENOTSOCK 88 /* Socket operation on non-socket */
+#define EDESTADDRREQ 89 /* Destination address required */
+#define EMSGSIZE 90 /* Message too long */
+#define EPROTOTYPE 91 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 92 /* Protocol not available */
+#define EPROTONOSUPPORT 93 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
+#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
+#define EADDRINUSE 98 /* Address already in use */
+#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
+#define ENETDOWN 100 /* Network is down */
+#define ENETUNREACH 101 /* Network is unreachable */
+#define ENETRESET 102 /* Network dropped connection because of reset */
+#define ECONNABORTED 103 /* Software caused connection abort */
+#define ECONNRESET 104 /* Connection reset by peer */
+#define ENOBUFS 105 /* No buffer space available */
+#define EISCONN 106 /* Transport endpoint is already connected */
+#define ENOTCONN 107 /* Transport endpoint is not connected */
+#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS 109 /* Too many references: cannot splice */
+#define ETIMEDOUT 110 /* Connection timed out */
+#define ECONNREFUSED 111 /* Connection refused */
+#define EHOSTDOWN 112 /* Host is down */
+#define EHOSTUNREACH 113 /* No route to host */
+#define EALREADY 114 /* Operation already in progress */
+#define EINPROGRESS 115 /* Operation now in progress */
+#define ESTALE 116 /* Stale file handle */
+#define EUCLEAN 117 /* Structure needs cleaning */
+#define ENOTNAM 118 /* Not a XENIX named type file */
+#define ENAVAIL 119 /* No XENIX semaphores available */
+#define EISNAM 120 /* Is a named type file */
+#define EREMOTEIO 121 /* Remote I/O error */
+#define EDQUOT 122 /* Quota exceeded */
+
+#define ENOMEDIUM 123 /* No medium found */
+#define EMEDIUMTYPE 124 /* Wrong medium type */
+#define ECANCELED 125 /* Operation Canceled */
+#define ENOKEY 126 /* Required key not available */
+#define EKEYEXPIRED 127 /* Key has expired */
+#define EKEYREVOKED 128 /* Key has been revoked */
+#define EKEYREJECTED 129 /* Key was rejected by service */
+
+/* for robust mutexes */
+#define EOWNERDEAD 130 /* Owner died */
+#define ENOTRECOVERABLE 131 /* State not recoverable */
+
+#define ERFKILL 132 /* Operation not possible due to RF-kill */
+
+#define EHWPOISON 133 /* Memory page has hardware error */
+
+#endif
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __ASM_GENERIC_POSIX_TYPES_H
+#define __ASM_GENERIC_POSIX_TYPES_H
+
+#include <asm/bitsperlong.h>
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.
+ *
+ * First the types that are often defined in different ways across
+ * architectures, so that you can override them.
+ */
+
+#ifndef __kernel_long_t
+typedef long __kernel_long_t;
+typedef unsigned long __kernel_ulong_t;
+#endif
+
+#ifndef __kernel_ino_t
+typedef __kernel_ulong_t __kernel_ino_t;
+#endif
+
+#ifndef __kernel_mode_t
+typedef unsigned int __kernel_mode_t;
+#endif
+
+#ifndef __kernel_pid_t
+typedef int __kernel_pid_t;
+#endif
+
+#ifndef __kernel_ipc_pid_t
+typedef int __kernel_ipc_pid_t;
+#endif
+
+#ifndef __kernel_uid_t
+typedef unsigned int __kernel_uid_t;
+typedef unsigned int __kernel_gid_t;
+#endif
+
+#ifndef __kernel_suseconds_t
+typedef __kernel_long_t __kernel_suseconds_t;
+#endif
+
+#ifndef __kernel_daddr_t
+typedef int __kernel_daddr_t;
+#endif
+
+#ifndef __kernel_uid32_t
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+#endif
+
+#ifndef __kernel_old_uid_t
+typedef __kernel_uid_t __kernel_old_uid_t;
+typedef __kernel_gid_t __kernel_old_gid_t;
+#endif
+
+#ifndef __kernel_old_dev_t
+typedef unsigned int __kernel_old_dev_t;
+#endif
+
+/*
+ * Most 32 bit architectures use "unsigned int" size_t,
+ * and all 64 bit architectures use "unsigned long" size_t.
+ */
+#ifndef __kernel_size_t
+#if __BITS_PER_LONG != 64
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+#else
+typedef __kernel_ulong_t __kernel_size_t;
+typedef __kernel_long_t __kernel_ssize_t;
+typedef __kernel_long_t __kernel_ptrdiff_t;
+#endif
+#endif
+
+#ifndef __kernel_fsid_t
+typedef struct {
+ int val[2];
+} __kernel_fsid_t;
+#endif
+
+/*
+ * anything below here should be completely generic
+ */
+typedef __kernel_long_t __kernel_off_t;
+typedef long long __kernel_loff_t;
+typedef __kernel_long_t __kernel_old_time_t;
+typedef __kernel_long_t __kernel_time_t;
+typedef long long __kernel_time64_t;
+typedef __kernel_long_t __kernel_clock_t;
+typedef int __kernel_timer_t;
+typedef int __kernel_clockid_t;
+typedef char * __kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+
+#endif /* __ASM_GENERIC_POSIX_TYPES_H */
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _ASM_GENERIC_SWAB_H
+#define _ASM_GENERIC_SWAB_H
+
+#include <asm/bitsperlong.h>
+
+/*
+ * 32 bit architectures typically (but not always) want to
+ * set __SWAB_64_THRU_32__. In user space, this is only
+ * valid if the compiler supports 64 bit data types.
+ */
+
+#if __BITS_PER_LONG == 32
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#define __SWAB_64_THRU_32__
+#endif
+#endif
+
+#endif /* _ASM_GENERIC_SWAB_H */
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_BYTEORDER_BIG_ENDIAN_H
+#define _LINUX_BYTEORDER_BIG_ENDIAN_H
+
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN 4321
+#endif
+#ifndef __BIG_ENDIAN_BITFIELD
+#define __BIG_ENDIAN_BITFIELD
+#endif
+
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/swab.h>
+
+#define __constant_htonl(x) ((__be32)(__u32)(x))
+#define __constant_ntohl(x) ((__u32)(__be32)(x))
+#define __constant_htons(x) ((__be16)(__u16)(x))
+#define __constant_ntohs(x) ((__u16)(__be16)(x))
+#define __constant_cpu_to_le64(x) ((__le64)___constant_swab64((x)))
+#define __constant_le64_to_cpu(x) ___constant_swab64((__u64)(__le64)(x))
+#define __constant_cpu_to_le32(x) ((__le32)___constant_swab32((x)))
+#define __constant_le32_to_cpu(x) ___constant_swab32((__u32)(__le32)(x))
+#define __constant_cpu_to_le16(x) ((__le16)___constant_swab16((x)))
+#define __constant_le16_to_cpu(x) ___constant_swab16((__u16)(__le16)(x))
+#define __constant_cpu_to_be64(x) ((__be64)(__u64)(x))
+#define __constant_be64_to_cpu(x) ((__u64)(__be64)(x))
+#define __constant_cpu_to_be32(x) ((__be32)(__u32)(x))
+#define __constant_be32_to_cpu(x) ((__u32)(__be32)(x))
+#define __constant_cpu_to_be16(x) ((__be16)(__u16)(x))
+#define __constant_be16_to_cpu(x) ((__u16)(__be16)(x))
+#define __cpu_to_le64(x) ((__le64)__swab64((x)))
+#define __le64_to_cpu(x) __swab64((__u64)(__le64)(x))
+#define __cpu_to_le32(x) ((__le32)__swab32((x)))
+#define __le32_to_cpu(x) __swab32((__u32)(__le32)(x))
+#define __cpu_to_le16(x) ((__le16)__swab16((x)))
+#define __le16_to_cpu(x) __swab16((__u16)(__le16)(x))
+#define __cpu_to_be64(x) ((__be64)(__u64)(x))
+#define __be64_to_cpu(x) ((__u64)(__be64)(x))
+#define __cpu_to_be32(x) ((__be32)(__u32)(x))
+#define __be32_to_cpu(x) ((__u32)(__be32)(x))
+#define __cpu_to_be16(x) ((__be16)(__u16)(x))
+#define __be16_to_cpu(x) ((__u16)(__be16)(x))
+
+static __always_inline __le64 __cpu_to_le64p(const __u64 *p)
+{
+ return (__le64)__swab64p(p);
+}
+static __always_inline __u64 __le64_to_cpup(const __le64 *p)
+{
+ return __swab64p((__u64 *)p);
+}
+static __always_inline __le32 __cpu_to_le32p(const __u32 *p)
+{
+ return (__le32)__swab32p(p);
+}
+static __always_inline __u32 __le32_to_cpup(const __le32 *p)
+{
+ return __swab32p((__u32 *)p);
+}
+static __always_inline __le16 __cpu_to_le16p(const __u16 *p)
+{
+ return (__le16)__swab16p(p);
+}
+static __always_inline __u16 __le16_to_cpup(const __le16 *p)
+{
+ return __swab16p((__u16 *)p);
+}
+static __always_inline __be64 __cpu_to_be64p(const __u64 *p)
+{
+ return (__be64)*p;
+}
+static __always_inline __u64 __be64_to_cpup(const __be64 *p)
+{
+ return (__u64)*p;
+}
+static __always_inline __be32 __cpu_to_be32p(const __u32 *p)
+{
+ return (__be32)*p;
+}
+static __always_inline __u32 __be32_to_cpup(const __be32 *p)
+{
+ return (__u32)*p;
+}
+static __always_inline __be16 __cpu_to_be16p(const __u16 *p)
+{
+ return (__be16)*p;
+}
+static __always_inline __u16 __be16_to_cpup(const __be16 *p)
+{
+ return (__u16)*p;
+}
+#define __cpu_to_le64s(x) __swab64s((x))
+#define __le64_to_cpus(x) __swab64s((x))
+#define __cpu_to_le32s(x) __swab32s((x))
+#define __le32_to_cpus(x) __swab32s((x))
+#define __cpu_to_le16s(x) __swab16s((x))
+#define __le16_to_cpus(x) __swab16s((x))
+#define __cpu_to_be64s(x) do { (void)(x); } while (0)
+#define __be64_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_be32s(x) do { (void)(x); } while (0)
+#define __be32_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_be16s(x) do { (void)(x); } while (0)
+#define __be16_to_cpus(x) do { (void)(x); } while (0)
+
+
+#endif /* _LINUX_BYTEORDER_BIG_ENDIAN_H */
--- /dev/null
+#include <asm/errno.h>
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
+#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H
+
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN 1234
+#endif
+#ifndef __LITTLE_ENDIAN_BITFIELD
+#define __LITTLE_ENDIAN_BITFIELD
+#endif
+
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/swab.h>
+
+#define __constant_htonl(x) ((__be32)___constant_swab32((x)))
+#define __constant_ntohl(x) ___constant_swab32((__be32)(x))
+#define __constant_htons(x) ((__be16)___constant_swab16((x)))
+#define __constant_ntohs(x) ___constant_swab16((__be16)(x))
+#define __constant_cpu_to_le64(x) ((__le64)(__u64)(x))
+#define __constant_le64_to_cpu(x) ((__u64)(__le64)(x))
+#define __constant_cpu_to_le32(x) ((__le32)(__u32)(x))
+#define __constant_le32_to_cpu(x) ((__u32)(__le32)(x))
+#define __constant_cpu_to_le16(x) ((__le16)(__u16)(x))
+#define __constant_le16_to_cpu(x) ((__u16)(__le16)(x))
+#define __constant_cpu_to_be64(x) ((__be64)___constant_swab64((x)))
+#define __constant_be64_to_cpu(x) ___constant_swab64((__u64)(__be64)(x))
+#define __constant_cpu_to_be32(x) ((__be32)___constant_swab32((x)))
+#define __constant_be32_to_cpu(x) ___constant_swab32((__u32)(__be32)(x))
+#define __constant_cpu_to_be16(x) ((__be16)___constant_swab16((x)))
+#define __constant_be16_to_cpu(x) ___constant_swab16((__u16)(__be16)(x))
+#define __cpu_to_le64(x) ((__le64)(__u64)(x))
+#define __le64_to_cpu(x) ((__u64)(__le64)(x))
+#define __cpu_to_le32(x) ((__le32)(__u32)(x))
+#define __le32_to_cpu(x) ((__u32)(__le32)(x))
+#define __cpu_to_le16(x) ((__le16)(__u16)(x))
+#define __le16_to_cpu(x) ((__u16)(__le16)(x))
+#define __cpu_to_be64(x) ((__be64)__swab64((x)))
+#define __be64_to_cpu(x) __swab64((__u64)(__be64)(x))
+#define __cpu_to_be32(x) ((__be32)__swab32((x)))
+#define __be32_to_cpu(x) __swab32((__u32)(__be32)(x))
+#define __cpu_to_be16(x) ((__be16)__swab16((x)))
+#define __be16_to_cpu(x) __swab16((__u16)(__be16)(x))
+
+static __always_inline __le64 __cpu_to_le64p(const __u64 *p)
+{
+ return (__le64)*p;
+}
+static __always_inline __u64 __le64_to_cpup(const __le64 *p)
+{
+ return (__u64)*p;
+}
+static __always_inline __le32 __cpu_to_le32p(const __u32 *p)
+{
+ return (__le32)*p;
+}
+static __always_inline __u32 __le32_to_cpup(const __le32 *p)
+{
+ return (__u32)*p;
+}
+static __always_inline __le16 __cpu_to_le16p(const __u16 *p)
+{
+ return (__le16)*p;
+}
+static __always_inline __u16 __le16_to_cpup(const __le16 *p)
+{
+ return (__u16)*p;
+}
+static __always_inline __be64 __cpu_to_be64p(const __u64 *p)
+{
+ return (__be64)__swab64p(p);
+}
+static __always_inline __u64 __be64_to_cpup(const __be64 *p)
+{
+ return __swab64p((__u64 *)p);
+}
+static __always_inline __be32 __cpu_to_be32p(const __u32 *p)
+{
+ return (__be32)__swab32p(p);
+}
+static __always_inline __u32 __be32_to_cpup(const __be32 *p)
+{
+ return __swab32p((__u32 *)p);
+}
+static __always_inline __be16 __cpu_to_be16p(const __u16 *p)
+{
+ return (__be16)__swab16p(p);
+}
+static __always_inline __u16 __be16_to_cpup(const __be16 *p)
+{
+ return __swab16p((__u16 *)p);
+}
+#define __cpu_to_le64s(x) do { (void)(x); } while (0)
+#define __le64_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_le32s(x) do { (void)(x); } while (0)
+#define __le32_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_le16s(x) do { (void)(x); } while (0)
+#define __le16_to_cpus(x) do { (void)(x); } while (0)
+#define __cpu_to_be64s(x) __swab64s((x))
+#define __be64_to_cpus(x) __swab64s((x))
+#define __cpu_to_be32s(x) __swab32s((x))
+#define __be32_to_cpus(x) __swab32s((x))
+#define __cpu_to_be16s(x) __swab16s((x))
+#define __be16_to_cpus(x) __swab16s((x))
+
+
+#endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_LINUX_STDDEF_H
+#define _UAPI_LINUX_STDDEF_H
+
+#ifndef __always_inline
+#define __always_inline inline
+#endif
+
+/**
+ * __struct_group() - Create a mirrored named and anonyomous struct
+ *
+ * @TAG: The tag name for the named sub-struct (usually empty)
+ * @NAME: The identifier name of the mirrored sub-struct
+ * @ATTRS: Any struct attributes (usually empty)
+ * @MEMBERS: The member declarations for the mirrored structs
+ *
+ * Used to create an anonymous union of two structs with identical layout
+ * and size: one anonymous and one named. The former's members can be used
+ * normally without sub-struct naming, and the latter can be used to
+ * reason about the start, end, and size of the group of struct members.
+ * The named struct can also be explicitly tagged for layer reuse, as well
+ * as both having struct attributes appended.
+ */
+#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
+ union { \
+ struct { MEMBERS } ATTRS; \
+ struct TAG { MEMBERS } ATTRS NAME; \
+ } ATTRS
+
+#ifdef __cplusplus
+/* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */
+#define __DECLARE_FLEX_ARRAY(T, member) \
+ T member[0]
+#else
+/**
+ * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
+ *
+ * @TYPE: The type of each flexible array element
+ * @NAME: The name of the flexible array member
+ *
+ * In order to have a flexible array member in a union or alone in a
+ * struct, it needs to be wrapped in an anonymous struct with at least 1
+ * named member, but that member can be empty.
+ */
+#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \
+ struct { \
+ struct { } __empty_ ## NAME; \
+ TYPE NAME[]; \
+ }
+#endif
+
+#ifndef __counted_by
+#define __counted_by(m)
+#endif
+
+#endif /* _UAPI_LINUX_STDDEF_H */
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_SWAB_H
+#define _LINUX_SWAB_H
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <asm/bitsperlong.h>
+#include <asm/swab.h>
+
+/*
+ * casts are necessary for constants, because we never know how for sure
+ * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
+ */
+#define ___constant_swab16(x) ((__u16)( \
+ (((__u16)(x) & (__u16)0x00ffU) << 8) | \
+ (((__u16)(x) & (__u16)0xff00U) >> 8)))
+
+#define ___constant_swab32(x) ((__u32)( \
+ (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
+ (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
+ (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
+ (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
+
+#define ___constant_swab64(x) ((__u64)( \
+ (((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \
+ (((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \
+ (((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \
+ (((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \
+ (((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \
+ (((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
+ (((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
+ (((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56)))
+
+#define ___constant_swahw32(x) ((__u32)( \
+ (((__u32)(x) & (__u32)0x0000ffffUL) << 16) | \
+ (((__u32)(x) & (__u32)0xffff0000UL) >> 16)))
+
+#define ___constant_swahb32(x) ((__u32)( \
+ (((__u32)(x) & (__u32)0x00ff00ffUL) << 8) | \
+ (((__u32)(x) & (__u32)0xff00ff00UL) >> 8)))
+
+/*
+ * Implement the following as inlines, but define the interface using
+ * macros to allow constant folding when possible:
+ * ___swab16, ___swab32, ___swab64, ___swahw32, ___swahb32
+ */
+
+static __inline__ __u16 __fswab16(__u16 val)
+{
+#if defined (__arch_swab16)
+ return __arch_swab16(val);
+#else
+ return ___constant_swab16(val);
+#endif
+}
+
+static __inline__ __u32 __fswab32(__u32 val)
+{
+#if defined(__arch_swab32)
+ return __arch_swab32(val);
+#else
+ return ___constant_swab32(val);
+#endif
+}
+
+static __inline__ __u64 __fswab64(__u64 val)
+{
+#if defined (__arch_swab64)
+ return __arch_swab64(val);
+#elif defined(__SWAB_64_THRU_32__)
+ __u32 h = val >> 32;
+ __u32 l = val & ((1ULL << 32) - 1);
+ return (((__u64)__fswab32(l)) << 32) | ((__u64)(__fswab32(h)));
+#else
+ return ___constant_swab64(val);
+#endif
+}
+
+static __inline__ __u32 __fswahw32(__u32 val)
+{
+#ifdef __arch_swahw32
+ return __arch_swahw32(val);
+#else
+ return ___constant_swahw32(val);
+#endif
+}
+
+static __inline__ __u32 __fswahb32(__u32 val)
+{
+#ifdef __arch_swahb32
+ return __arch_swahb32(val);
+#else
+ return ___constant_swahb32(val);
+#endif
+}
+
+/**
+ * __swab16 - return a byteswapped 16-bit value
+ * @x: value to byteswap
+ */
+#ifdef __HAVE_BUILTIN_BSWAP16__
+#define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
+#else
+#define __swab16(x) \
+ (__u16)(__builtin_constant_p(x) ? \
+ ___constant_swab16(x) : \
+ __fswab16(x))
+#endif
+
+/**
+ * __swab32 - return a byteswapped 32-bit value
+ * @x: value to byteswap
+ */
+#ifdef __HAVE_BUILTIN_BSWAP32__
+#define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
+#else
+#define __swab32(x) \
+ (__u32)(__builtin_constant_p(x) ? \
+ ___constant_swab32(x) : \
+ __fswab32(x))
+#endif
+
+/**
+ * __swab64 - return a byteswapped 64-bit value
+ * @x: value to byteswap
+ */
+#ifdef __HAVE_BUILTIN_BSWAP64__
+#define __swab64(x) (__u64)__builtin_bswap64((__u64)(x))
+#else
+#define __swab64(x) \
+ (__u64)(__builtin_constant_p(x) ? \
+ ___constant_swab64(x) : \
+ __fswab64(x))
+#endif
+
+static __always_inline unsigned long __swab(const unsigned long y)
+{
+#if __BITS_PER_LONG == 64
+ return __swab64(y);
+#else /* __BITS_PER_LONG == 32 */
+ return __swab32(y);
+#endif
+}
+
+/**
+ * __swahw32 - return a word-swapped 32-bit value
+ * @x: value to wordswap
+ *
+ * __swahw32(0x12340000) is 0x00001234
+ */
+#define __swahw32(x) \
+ (__builtin_constant_p((__u32)(x)) ? \
+ ___constant_swahw32(x) : \
+ __fswahw32(x))
+
+/**
+ * __swahb32 - return a high and low byte-swapped 32-bit value
+ * @x: value to byteswap
+ *
+ * __swahb32(0x12345678) is 0x34127856
+ */
+#define __swahb32(x) \
+ (__builtin_constant_p((__u32)(x)) ? \
+ ___constant_swahb32(x) : \
+ __fswahb32(x))
+
+/**
+ * __swab16p - return a byteswapped 16-bit value from a pointer
+ * @p: pointer to a naturally-aligned 16-bit value
+ */
+static __always_inline __u16 __swab16p(const __u16 *p)
+{
+#ifdef __arch_swab16p
+ return __arch_swab16p(p);
+#else
+ return __swab16(*p);
+#endif
+}
+
+/**
+ * __swab32p - return a byteswapped 32-bit value from a pointer
+ * @p: pointer to a naturally-aligned 32-bit value
+ */
+static __always_inline __u32 __swab32p(const __u32 *p)
+{
+#ifdef __arch_swab32p
+ return __arch_swab32p(p);
+#else
+ return __swab32(*p);
+#endif
+}
+
+/**
+ * __swab64p - return a byteswapped 64-bit value from a pointer
+ * @p: pointer to a naturally-aligned 64-bit value
+ */
+static __always_inline __u64 __swab64p(const __u64 *p)
+{
+#ifdef __arch_swab64p
+ return __arch_swab64p(p);
+#else
+ return __swab64(*p);
+#endif
+}
+
+/**
+ * __swahw32p - return a wordswapped 32-bit value from a pointer
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahw32() for details of wordswapping.
+ */
+static __inline__ __u32 __swahw32p(const __u32 *p)
+{
+#ifdef __arch_swahw32p
+ return __arch_swahw32p(p);
+#else
+ return __swahw32(*p);
+#endif
+}
+
+/**
+ * __swahb32p - return a high and low byteswapped 32-bit value from a pointer
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahb32() for details of high/low byteswapping.
+ */
+static __inline__ __u32 __swahb32p(const __u32 *p)
+{
+#ifdef __arch_swahb32p
+ return __arch_swahb32p(p);
+#else
+ return __swahb32(*p);
+#endif
+}
+
+/**
+ * __swab16s - byteswap a 16-bit value in-place
+ * @p: pointer to a naturally-aligned 16-bit value
+ */
+static __inline__ void __swab16s(__u16 *p)
+{
+#ifdef __arch_swab16s
+ __arch_swab16s(p);
+#else
+ *p = __swab16p(p);
+#endif
+}
+/**
+ * __swab32s - byteswap a 32-bit value in-place
+ * @p: pointer to a naturally-aligned 32-bit value
+ */
+static __always_inline void __swab32s(__u32 *p)
+{
+#ifdef __arch_swab32s
+ __arch_swab32s(p);
+#else
+ *p = __swab32p(p);
+#endif
+}
+
+/**
+ * __swab64s - byteswap a 64-bit value in-place
+ * @p: pointer to a naturally-aligned 64-bit value
+ */
+static __always_inline void __swab64s(__u64 *p)
+{
+#ifdef __arch_swab64s
+ __arch_swab64s(p);
+#else
+ *p = __swab64p(p);
+#endif
+}
+
+/**
+ * __swahw32s - wordswap a 32-bit value in-place
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahw32() for details of wordswapping
+ */
+static __inline__ void __swahw32s(__u32 *p)
+{
+#ifdef __arch_swahw32s
+ __arch_swahw32s(p);
+#else
+ *p = __swahw32p(p);
+#endif
+}
+
+/**
+ * __swahb32s - high and low byteswap a 32-bit value in-place
+ * @p: pointer to a naturally-aligned 32-bit value
+ *
+ * See __swahb32() for details of high and low byte swapping
+ */
+static __inline__ void __swahb32s(__u32 *p)
+{
+#ifdef __arch_swahb32s
+ __arch_swahb32s(p);
+#else
+ *p = __swahb32p(p);
+#endif
+}
+
+
+#endif /* _LINUX_SWAB_H */
include $(TOPDIR)/rules.mk
PKG_NAME:=mold
-PKG_VERSION:=2.30.0
+PKG_VERSION:=2.31.0
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL_FILE:=v$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/rui314/mold/archive/refs/tags
-PKG_HASH:=6e5178ccafe828fdb4ba0dd841d083ff6004d3cb41e56485143eb64c716345fd
+PKG_HASH:=3dc3af83a5d22a4b29971bfad17261851d426961c665480e2ca294e5c74aa1e5
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/cmake.mk
--keep-system-cflags \
--keep-system-libs \
--define-variable=prefix="${STAGING_PREFIX}" \
+--define-variable=prefix_host="${STAGING_DIR_HOST}" \
+--define-variable=prefix_hostpkg="${STAGING_DIR_HOSTPKG}" \
--define-variable=exec_prefix="${STAGING_PREFIX}" \
--define-variable=bindir="${STAGING_PREFIX}/bin" \
$PKG_CONFIG_EXTRAARGS "$@"