Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
@@ -10,6 +10,7 @@ FEATURES:=fpu dt gpio ramdisk squashfs usb
|
||||
SUBTARGETS:=nand sata
|
||||
|
||||
KERNEL_PATCHVER:=5.15
|
||||
KERNEL_TESTING_PATCHVER:=6.1
|
||||
|
||||
define Target/Description
|
||||
Build images for AppliedMicro APM821xx based boards.
|
||||
@@ -20,6 +21,7 @@ include $(INCLUDE_DIR)/target.mk
|
||||
KERNELNAME:=uImage
|
||||
|
||||
DEFAULT_PACKAGES += \
|
||||
kmod-leds-gpio kmod-i2c-core kmod-gpio-button-hotplug uboot-envtools
|
||||
kmod-leds-gpio kmod-i2c-core kmod-gpio-button-hotplug uboot-envtools \
|
||||
kmod-hw-crypto-4xx
|
||||
|
||||
$(eval $(call BuildTarget))
|
||||
|
||||
@@ -39,15 +39,11 @@ CONFIG_CRC16=y
|
||||
# CONFIG_CRC32_SARWATE is not set
|
||||
CONFIG_CRC32_SLICEBY8=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
CONFIG_CRYPTO_DEV_PPC4XX=y
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
# CONFIG_CRYPTO_MD5_PPC is not set
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
# CONFIG_CRYPTO_SHA1_PPC is not set
|
||||
CONFIG_DATA_SHIFT=12
|
||||
CONFIG_DMADEVICES=y
|
||||
@@ -96,8 +92,6 @@ CONFIG_GPIO_GENERIC_PLATFORM=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_PPC4XX=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
|
||||
250
target/linux/apm821xx/config-6.1
Normal file
250
target/linux/apm821xx/config-6.1
Normal file
@@ -0,0 +1,250 @@
|
||||
# CONFIG_40x is not set
|
||||
# CONFIG_440_CPU is not set
|
||||
CONFIG_44x=y
|
||||
CONFIG_464_CPU=y
|
||||
CONFIG_4xx=y
|
||||
CONFIG_4xx_SOC=y
|
||||
# CONFIG_ADVANCED_OPTIONS is not set
|
||||
CONFIG_APM821xx=y
|
||||
# CONFIG_APOLLO3G is not set
|
||||
# CONFIG_ARCHES is not set
|
||||
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_MAY_HAVE_PC_FDC=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=11
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=17
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=11
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
|
||||
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
|
||||
CONFIG_ARCH_SPLIT_ARG64=y
|
||||
CONFIG_ARCH_STACKWALK=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
|
||||
CONFIG_AUDIT_ARCH=y
|
||||
# CONFIG_BAMBOO is not set
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_BLUESTONE=y
|
||||
CONFIG_BOOKE=y
|
||||
CONFIG_BOOKE_OR_40x=y
|
||||
CONFIG_BOOKE_WDT=y
|
||||
# CONFIG_CANYONLANDS is not set
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="rootfstype=squashfs noinitrd"
|
||||
CONFIG_CMDLINE_FROM_BOOTLOADER=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
|
||||
CONFIG_COMPAT_32BIT_TIME=y
|
||||
CONFIG_CPU_BIG_ENDIAN=y
|
||||
CONFIG_CRC16=y
|
||||
# CONFIG_CRC32_SARWATE is not set
|
||||
CONFIG_CRC32_SLICEBY8=y
|
||||
CONFIG_CRYPTO_DEFLATE=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_UTILS=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
# CONFIG_CRYPTO_MD5_PPC is not set
|
||||
# CONFIG_CRYPTO_SHA1_PPC is not set
|
||||
CONFIG_DATA_SHIFT=12
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_DIRECT_REMAP=y
|
||||
CONFIG_DMA_ENGINE=y
|
||||
CONFIG_DMA_OF=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_DW_DMAC=y
|
||||
CONFIG_DW_DMAC_CORE=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
# CONFIG_EBONY is not set
|
||||
CONFIG_EDAC_ATOMIC_SCRUB=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
# CONFIG_EIGER is not set
|
||||
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
|
||||
CONFIG_EXTRA_TARGETS="uImage"
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FORCE_PCI=y
|
||||
# CONFIG_FSL_LBC is not set
|
||||
CONFIG_FWNODE_MDIO=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_FW_LOADER_SYSFS=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_ISA_DMA=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
# CONFIG_GEN_RTC is not set
|
||||
# CONFIG_GLACIER is not set
|
||||
CONFIG_GPIO_CDEV=y
|
||||
CONFIG_GPIO_GENERIC=y
|
||||
CONFIG_GPIO_GENERIC_PLATFORM=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_IBM_IIC=y
|
||||
CONFIG_IBM_EMAC=y
|
||||
CONFIG_IBM_EMAC_EMAC4=y
|
||||
CONFIG_IBM_EMAC_POLL_WEIGHT=32
|
||||
CONFIG_IBM_EMAC_RGMII=y
|
||||
CONFIG_IBM_EMAC_RXB=128
|
||||
CONFIG_IBM_EMAC_RX_COPY_THRESHOLD=256
|
||||
CONFIG_IBM_EMAC_TAH=y
|
||||
CONFIG_IBM_EMAC_TXB=128
|
||||
# CONFIG_ICON is not set
|
||||
CONFIG_ILLEGAL_POINTER_VALUE=0
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_ISA_DMA_API=y
|
||||
# CONFIG_JFFS2_FS is not set
|
||||
# CONFIG_KATMAI is not set
|
||||
CONFIG_KERNEL_START=0xc0000000
|
||||
CONFIG_LEDS_TRIGGER_MTD=y
|
||||
CONFIG_LEDS_TRIGGER_PATTERN=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_LOWMEM_SIZE=0x30000000
|
||||
# CONFIG_MATH_EMULATION is not set
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMU_GATHER_PAGE_SIZE=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y
|
||||
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||
# CONFIG_MTD_CFI_GEOMETRY is not set
|
||||
# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_SELFTESTS=y
|
||||
CONFIG_NOT_COHERENT_CACHE=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=1
|
||||
CONFIG_NR_IRQS=512
|
||||
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_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OLD_SIGACTION=y
|
||||
CONFIG_OLD_SIGSUSPEND=y
|
||||
CONFIG_PACKING=y
|
||||
CONFIG_PAGE_OFFSET=0xc0000000
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEAER=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PCI_MSI_ARCH_FALLBACKS=y
|
||||
CONFIG_PCI_MSI_IRQ_DOMAIN=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYSICAL_START=0x00000000
|
||||
CONFIG_PHYS_64BIT=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
# CONFIG_PMU_SYSFS is not set
|
||||
CONFIG_PPC=y
|
||||
CONFIG_PPC32=y
|
||||
CONFIG_PPC44x_SIMPLE=y
|
||||
CONFIG_PPC4xx_GPIO=y
|
||||
CONFIG_PPC4xx_PCI_EXPRESS=y
|
||||
# CONFIG_PPC64 is not set
|
||||
# CONFIG_PPC_47x is not set
|
||||
# CONFIG_PPC_85xx is not set
|
||||
# CONFIG_PPC_8xx is not set
|
||||
CONFIG_PPC_ADV_DEBUG_DACS=2
|
||||
CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
|
||||
CONFIG_PPC_ADV_DEBUG_DVCS=2
|
||||
CONFIG_PPC_ADV_DEBUG_IACS=4
|
||||
CONFIG_PPC_ADV_DEBUG_REGS=y
|
||||
# CONFIG_PPC_BOOK3S_32 is not set
|
||||
CONFIG_PPC_DCR=y
|
||||
CONFIG_PPC_DCR_NATIVE=y
|
||||
# CONFIG_PPC_EARLY_DEBUG is not set
|
||||
CONFIG_PPC_FPU=y
|
||||
CONFIG_PPC_FPU_REGS=y
|
||||
CONFIG_PPC_INDIRECT_PCI=y
|
||||
CONFIG_PPC_KUAP=y
|
||||
# CONFIG_PPC_KUAP_DEBUG is not set
|
||||
CONFIG_PPC_KUEP=y
|
||||
CONFIG_PPC_MMU_NOHASH=y
|
||||
CONFIG_PPC_PAGE_SHIFT=12
|
||||
# CONFIG_PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT is not set
|
||||
CONFIG_PPC_UDBG_16550=y
|
||||
CONFIG_PPC_WERROR=y
|
||||
CONFIG_PTE_64BIT=y
|
||||
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
|
||||
# CONFIG_RAINIER is not set
|
||||
CONFIG_RAS=y
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_RSEQ=y
|
||||
# CONFIG_SAM440EP is not set
|
||||
# CONFIG_SCOM_DEBUGFS is not set
|
||||
# CONFIG_SEQUOIA is not set
|
||||
# CONFIG_SERIAL_8250_FSL is not set
|
||||
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SGL_ALLOC=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_SRCU=y
|
||||
# CONFIG_STATIC_CALL_SELFTEST is not set
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
# CONFIG_TAISHAN is not set
|
||||
CONFIG_TARGET_CPU="464"
|
||||
CONFIG_TARGET_CPU_BOOL=y
|
||||
CONFIG_TASK_SIZE=0xc0000000
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_THREAD_SHIFT=13
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TINY_SRCU=y
|
||||
# CONFIG_TOOLCHAIN_DEFAULT_CPU is not set
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_VDSO32=y
|
||||
# CONFIG_VIRTIO_MENU is not set
|
||||
# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
|
||||
# CONFIG_WARP is not set
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_XZ_DEC_BCJ=y
|
||||
CONFIG_XZ_DEC_POWERPC=y
|
||||
# CONFIG_YOSEMITE is not set
|
||||
CONFIG_ZLIB_DEFLATE=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
@@ -47,8 +47,6 @@
|
||||
status = "okay";
|
||||
|
||||
nand {
|
||||
nand-is-boot-medium;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
|
||||
@@ -100,7 +100,7 @@ define Device/netgear_wndr4700
|
||||
kmod-dm kmod-fs-ext4 kmod-fs-vfat kmod-usb-ledtrig-usbport \
|
||||
kmod-md-mod kmod-nls-cp437 kmod-nls-iso8859-1 kmod-nls-iso8859-15 \
|
||||
kmod-nls-utf8 kmod-usb3 kmod-usb-dwc2 kmod-usb-storage \
|
||||
partx-utils
|
||||
partx-utils kmod-ata-dwc
|
||||
BOARD_NAME := wndr4700
|
||||
PAGESIZE := 2048
|
||||
SUBPAGESIZE := 512
|
||||
|
||||
33
target/linux/apm821xx/modules.mk
Normal file
33
target/linux/apm821xx/modules.mk
Normal file
@@ -0,0 +1,33 @@
|
||||
define KernelPackage/ata-dwc
|
||||
TITLE:=DesignWare Cores SATA support
|
||||
KCONFIG:=CONFIG_SATA_DWC
|
||||
FILES:=$(LINUX_DIR)/drivers/ata/sata_dwc_460ex.ko
|
||||
AUTOLOAD:=$(call AutoLoad,40,sata_dwc_460ex,1)
|
||||
$(call AddDepends/ata)
|
||||
endef
|
||||
|
||||
define KernelPackage/ata-dwc/description
|
||||
Platform support for the on-chip SATA controller.
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,ata-dwc))
|
||||
|
||||
define KernelPackage/hw-crypto-4xx
|
||||
TITLE:=Driver AMCC PPC4xx crypto accelerator
|
||||
KCONFIG:= \
|
||||
CONFIG_CRYPTO_HW=y \
|
||||
CONFIG_HW_RANDOM=y \
|
||||
CONFIG_CRYPTO_DEV_PPC4XX \
|
||||
CONFIG_HW_RANDOM_PPC4XX=y
|
||||
DEPENDS:=+kmod-random-core +kmod-crypto-manager \
|
||||
+kmod-crypto-ccm +kmod-crypto-gcm \
|
||||
+kmod-crypto-sha1 +kmod-crypto-sha256 +kmod-crypto-sha512
|
||||
FILES:=$(LINUX_DIR)/drivers/crypto/amcc/crypto4xx.ko
|
||||
AUTOLOAD:=$(call AutoLoad,09,sata_dwc_460ex,1)
|
||||
endef
|
||||
|
||||
define KernelPackage/hw-crypto-4xx/description
|
||||
Platform support for the on-chip crypto acceleration.
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,hw-crypto-4xx))
|
||||
@@ -2,14 +2,8 @@ CONFIG_AT803X_PHY=y
|
||||
CONFIG_AR8216_PHY=y
|
||||
# CONFIG_SATA_DWC_OLD_DMA is not set
|
||||
CONFIG_IKAREM=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_ATA_SFF=y
|
||||
CONFIG_ATA_BMDMA=y
|
||||
# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set
|
||||
CONFIG_SATA_PMP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_SATA_DWC=y
|
||||
# CONFIG_SATA_DWC_DEBUG is not set
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_GPIO_GENERIC=y
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
--- a/arch/powerpc/platforms/44x/Kconfig
|
||||
+++ b/arch/powerpc/platforms/44x/Kconfig
|
||||
@@ -118,6 +118,17 @@ config CANYONLANDS
|
||||
help
|
||||
This option enables support for the AMCC PPC460EX evaluation board.
|
||||
|
||||
+config APOLLO3G
|
||||
+ bool "Apollo3G"
|
||||
+ depends on 44x
|
||||
+ default n
|
||||
+ select PPC44x_SIMPLE
|
||||
+ select APM821xx
|
||||
+ select IBM_EMAC_RGMII
|
||||
+ select 460EX
|
||||
+ help
|
||||
+ This option enables support for the AMCC Apollo 3G board.
|
||||
+
|
||||
config GLACIER
|
||||
bool "Glacier"
|
||||
depends on 44x
|
||||
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
|
||||
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
|
||||
@@ -46,6 +46,7 @@ machine_device_initcall(ppc44x_simple, p
|
||||
* board.c file for it rather than adding it to this list.
|
||||
*/
|
||||
static char *board[] __initdata = {
|
||||
+ "amcc,apollo3g",
|
||||
"amcc,arches",
|
||||
"amcc,bamboo",
|
||||
"apm,bluestone",
|
||||
@@ -0,0 +1,51 @@
|
||||
--- a/arch/powerpc/platforms/4xx/pci.c
|
||||
+++ b/arch/powerpc/platforms/4xx/pci.c
|
||||
@@ -1061,15 +1061,24 @@ static int __init apm821xx_pciex_init_po
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
- * Do a software reset on PCIe ports.
|
||||
- * This code is to fix the issue that pci drivers doesn't re-assign
|
||||
- * bus number for PCIE devices after Uboot
|
||||
- * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
|
||||
- * PT quad port, SAS LSI 1064E)
|
||||
+ * Only reset the PHY when no link is currently established.
|
||||
+ * This is for the Atheros PCIe board which has problems to establish
|
||||
+ * the link (again) after this PHY reset. All other currently tested
|
||||
+ * PCIe boards don't show this problem.
|
||||
*/
|
||||
-
|
||||
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
|
||||
- mdelay(10);
|
||||
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
|
||||
+ if (!(val & 0x00001000)) {
|
||||
+ /*
|
||||
+ * Do a software reset on PCIe ports.
|
||||
+ * This code is to fix the issue that pci drivers doesn't re-assign
|
||||
+ * bus number for PCIE devices after Uboot
|
||||
+ * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
|
||||
+ * PT quad port, SAS LSI 1064E)
|
||||
+ */
|
||||
+
|
||||
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
|
||||
+ mdelay(10);
|
||||
+ }
|
||||
|
||||
if (port->endpoint)
|
||||
val = PTYPE_LEGACY_ENDPOINT << 20;
|
||||
@@ -1086,9 +1095,12 @@ static int __init apm821xx_pciex_init_po
|
||||
mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130);
|
||||
mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006);
|
||||
|
||||
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
|
||||
- mdelay(50);
|
||||
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
|
||||
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
|
||||
+ if (!(val & 0x00001000)) {
|
||||
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
|
||||
+ mdelay(50);
|
||||
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
|
||||
+ }
|
||||
|
||||
mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
|
||||
mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) |
|
||||
@@ -0,0 +1,14 @@
|
||||
--- a/arch/powerpc/platforms/4xx/pci.c
|
||||
+++ b/arch/powerpc/platforms/4xx/pci.c
|
||||
@@ -1903,9 +1903,9 @@ static void __init ppc4xx_configure_pcie
|
||||
* if it works
|
||||
*/
|
||||
out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
|
||||
- out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
|
||||
+ out_le32(mbase + PECFG_PIM0LAH, 0x00000008);
|
||||
out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
|
||||
- out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
|
||||
+ out_le32(mbase + PECFG_PIM1LAH, 0x0000000c);
|
||||
out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
|
||||
out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
From c9395ad54e2cabb87d408becc37566f3d8248933 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Lamparter <chunkeey@gmail.com>
|
||||
Date: Sun, 1 Dec 2019 02:08:23 +0100
|
||||
Subject: [PATCH] powerpc: bootwrapper: force gzip as mkimage's compression
|
||||
method
|
||||
|
||||
Due to CONFIG_KERNEL_XZ symbol, the bootwrapper code tries to
|
||||
instruct the mkimage to use the xz compression, which isn't
|
||||
supported. This patch forces the gzip compression, which is
|
||||
supported and doesn't matter because the generated uImage for
|
||||
the apm821xx target gets ignored as the OpenWrt toolchain will
|
||||
do separate U-Boot kernel images for each device individually.
|
||||
|
||||
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
---
|
||||
arch/powerpc/boot/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/powerpc/boot/Makefile
|
||||
+++ b/arch/powerpc/boot/Makefile
|
||||
@@ -272,7 +272,7 @@ compressor-$(CONFIG_KERNEL_LZO) := lzo
|
||||
|
||||
# args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd
|
||||
quiet_cmd_wrap = WRAP $@
|
||||
- cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z $(compressor-y) -c -o $@ -p $2 \
|
||||
+ cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z gzip -c -o $@ -p $2 \
|
||||
$(CROSSWRAP) $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) \
|
||||
vmlinux
|
||||
|
||||
@@ -40,12 +40,14 @@ CONFIG_PM=y
|
||||
CONFIG_PM_AUTOSLEEP=y
|
||||
CONFIG_PM_CLK=y
|
||||
CONFIG_PM_SLEEP=y
|
||||
# CONFIG_PM_USERSPACE_AUTOSLEEP is not set
|
||||
CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_PM_WAKELOCKS_GC=y
|
||||
CONFIG_PM_WAKELOCKS_LIMIT=100
|
||||
CONFIG_PPC_EARLY_DEBUG=y
|
||||
CONFIG_PPC_EARLY_DEBUG_44x=y
|
||||
# CONFIG_PPC_EARLY_DEBUG_MEMCONS is not set
|
||||
# CONFIG_PPC_EARLY_DEBUG_16550 is not set
|
||||
CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x4
|
||||
CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
|
||||
CONFIG_PPC4xx_CPM=y
|
||||
|
||||
@@ -126,11 +126,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/workingset.c | 4 ++--
|
||||
4 files changed, 24 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index e8ed225d8f7ca..f63968bd7de59 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -178,7 +178,7 @@ static inline void lru_gen_update_size(struct lruvec *lruvec, struct folio *foli
|
||||
@@ -178,7 +178,7 @@ static inline void lru_gen_update_size(s
|
||||
int zone = folio_zonenum(folio);
|
||||
int delta = folio_nr_pages(folio);
|
||||
enum lru_list lru = type * LRU_INACTIVE_FILE;
|
||||
@@ -139,7 +137,7 @@ index e8ed225d8f7ca..f63968bd7de59 100644
|
||||
|
||||
VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS);
|
||||
VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS);
|
||||
@@ -224,7 +224,7 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
|
||||
@@ -224,7 +224,7 @@ static inline bool lru_gen_add_folio(str
|
||||
int gen = folio_lru_gen(folio);
|
||||
int type = folio_is_file_lru(folio);
|
||||
int zone = folio_zonenum(folio);
|
||||
@@ -148,8 +146,6 @@ index e8ed225d8f7ca..f63968bd7de59 100644
|
||||
|
||||
VM_WARN_ON_ONCE_FOLIO(gen != -1, folio);
|
||||
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index 5f74891556f33..bd3e4689f72dc 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -404,7 +404,7 @@ enum {
|
||||
@@ -179,11 +175,9 @@ index 5f74891556f33..bd3e4689f72dc 100644
|
||||
/* to concurrently iterate lru_gen_mm_list */
|
||||
struct lru_gen_mm_state mm_state;
|
||||
#endif
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index d18296109aa7e..27142caf284c1 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3190,7 +3190,7 @@ static int get_nr_gens(struct lruvec *lruvec, int type)
|
||||
@@ -3190,7 +3190,7 @@ static int get_nr_gens(struct lruvec *lr
|
||||
|
||||
static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
|
||||
{
|
||||
@@ -201,7 +195,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
int hist = lru_hist_from_seq(lrugen->min_seq[type]);
|
||||
|
||||
pos->refaulted = lrugen->avg_refaulted[type][tier] +
|
||||
@@ -3611,7 +3611,7 @@ static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain,
|
||||
@@ -3611,7 +3611,7 @@ static void read_ctrl_pos(struct lruvec
|
||||
static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover)
|
||||
{
|
||||
int hist, tier;
|
||||
@@ -210,7 +204,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1;
|
||||
unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1;
|
||||
|
||||
@@ -3688,7 +3688,7 @@ static int folio_update_gen(struct folio *folio, int gen)
|
||||
@@ -3688,7 +3688,7 @@ static int folio_update_gen(struct folio
|
||||
static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
|
||||
{
|
||||
int type = folio_is_file_lru(folio);
|
||||
@@ -219,7 +213,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
|
||||
unsigned long new_flags, old_flags = READ_ONCE(folio->flags);
|
||||
|
||||
@@ -3733,7 +3733,7 @@ static void update_batch_size(struct lru_gen_mm_walk *walk, struct folio *folio,
|
||||
@@ -3733,7 +3733,7 @@ static void update_batch_size(struct lru
|
||||
static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk)
|
||||
{
|
||||
int gen, type, zone;
|
||||
@@ -228,7 +222,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
|
||||
walk->batched = 0;
|
||||
|
||||
@@ -4250,7 +4250,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
|
||||
@@ -4250,7 +4250,7 @@ static bool inc_min_seq(struct lruvec *l
|
||||
{
|
||||
int zone;
|
||||
int remaining = MAX_LRU_BATCH;
|
||||
@@ -237,7 +231,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
|
||||
|
||||
if (type == LRU_GEN_ANON && !can_swap)
|
||||
@@ -4286,7 +4286,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
|
||||
@@ -4286,7 +4286,7 @@ static bool try_to_inc_min_seq(struct lr
|
||||
{
|
||||
int gen, type, zone;
|
||||
bool success = false;
|
||||
@@ -246,7 +240,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
DEFINE_MIN_SEQ(lruvec);
|
||||
|
||||
VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
|
||||
@@ -4307,7 +4307,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
|
||||
@@ -4307,7 +4307,7 @@ next:
|
||||
;
|
||||
}
|
||||
|
||||
@@ -255,7 +249,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
if (can_swap) {
|
||||
min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]);
|
||||
min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]);
|
||||
@@ -4329,7 +4329,7 @@ static void inc_max_seq(struct lruvec *lruvec, bool can_swap, bool force_scan)
|
||||
@@ -4329,7 +4329,7 @@ static void inc_max_seq(struct lruvec *l
|
||||
{
|
||||
int prev, next;
|
||||
int type, zone;
|
||||
@@ -264,7 +258,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
|
||||
spin_lock_irq(&lruvec->lru_lock);
|
||||
|
||||
@@ -4387,7 +4387,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
@@ -4387,7 +4387,7 @@ static bool try_to_inc_max_seq(struct lr
|
||||
bool success;
|
||||
struct lru_gen_mm_walk *walk;
|
||||
struct mm_struct *mm = NULL;
|
||||
@@ -273,7 +267,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
|
||||
VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq));
|
||||
|
||||
@@ -4452,7 +4452,7 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
|
||||
@@ -4452,7 +4452,7 @@ static bool should_run_aging(struct lruv
|
||||
unsigned long old = 0;
|
||||
unsigned long young = 0;
|
||||
unsigned long total = 0;
|
||||
@@ -282,7 +276,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
|
||||
for (type = !can_swap; type < ANON_AND_FILE; type++) {
|
||||
@@ -4737,7 +4737,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
|
||||
@@ -4737,7 +4737,7 @@ static bool sort_folio(struct lruvec *lr
|
||||
int delta = folio_nr_pages(folio);
|
||||
int refs = folio_lru_refs(folio);
|
||||
int tier = lru_tier_from_refs(refs);
|
||||
@@ -291,7 +285,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
|
||||
VM_WARN_ON_ONCE_FOLIO(gen >= MAX_NR_GENS, folio);
|
||||
|
||||
@@ -4837,7 +4837,7 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
|
||||
@@ -4837,7 +4837,7 @@ static int scan_folios(struct lruvec *lr
|
||||
int scanned = 0;
|
||||
int isolated = 0;
|
||||
int remaining = MAX_LRU_BATCH;
|
||||
@@ -300,7 +294,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
|
||||
VM_WARN_ON_ONCE(!list_empty(list));
|
||||
@@ -5237,7 +5237,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -5237,7 +5237,7 @@ done:
|
||||
|
||||
static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
|
||||
{
|
||||
@@ -309,7 +303,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
|
||||
if (lrugen->enabled) {
|
||||
enum lru_list lru;
|
||||
@@ -5519,7 +5519,7 @@ static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec,
|
||||
@@ -5519,7 +5519,7 @@ static void lru_gen_seq_show_full(struct
|
||||
int i;
|
||||
int type, tier;
|
||||
int hist = lru_hist_from_seq(seq);
|
||||
@@ -318,7 +312,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
|
||||
for (tier = 0; tier < MAX_NR_TIERS; tier++) {
|
||||
seq_printf(m, " %10d", tier);
|
||||
@@ -5569,7 +5569,7 @@ static int lru_gen_seq_show(struct seq_file *m, void *v)
|
||||
@@ -5569,7 +5569,7 @@ static int lru_gen_seq_show(struct seq_f
|
||||
unsigned long seq;
|
||||
bool full = !debugfs_real_fops(m->file)->write;
|
||||
struct lruvec *lruvec = v;
|
||||
@@ -327,7 +321,7 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
int nid = lruvec_pgdat(lruvec)->node_id;
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
DEFINE_MAX_SEQ(lruvec);
|
||||
@@ -5823,7 +5823,7 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
@@ -5823,7 +5823,7 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
{
|
||||
int i;
|
||||
int gen, type, zone;
|
||||
@@ -336,11 +330,9 @@ index d18296109aa7e..27142caf284c1 100644
|
||||
|
||||
lrugen->max_seq = MIN_NR_GENS + 1;
|
||||
lrugen->enabled = lru_gen_enabled();
|
||||
diff --git a/mm/workingset.c b/mm/workingset.c
|
||||
index ae7e984b23c6b..688aaa73f64e8 100644
|
||||
--- a/mm/workingset.c
|
||||
+++ b/mm/workingset.c
|
||||
@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct folio *folio)
|
||||
@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct fol
|
||||
unsigned long token;
|
||||
unsigned long min_seq;
|
||||
struct lruvec *lruvec;
|
||||
@@ -349,7 +341,7 @@ index ae7e984b23c6b..688aaa73f64e8 100644
|
||||
int type = folio_is_file_lru(folio);
|
||||
int delta = folio_nr_pages(folio);
|
||||
int refs = folio_lru_refs(folio);
|
||||
@@ -252,7 +252,7 @@ static void lru_gen_refault(struct folio *folio, void *shadow)
|
||||
@@ -252,7 +252,7 @@ static void lru_gen_refault(struct folio
|
||||
unsigned long token;
|
||||
unsigned long min_seq;
|
||||
struct lruvec *lruvec;
|
||||
@@ -358,6 +350,3 @@ index ae7e984b23c6b..688aaa73f64e8 100644
|
||||
struct mem_cgroup *memcg;
|
||||
struct pglist_data *pgdat;
|
||||
int type = folio_is_file_lru(folio);
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 20 ++++++++++----------
|
||||
4 files changed, 20 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index d7062c6a89464..d8f721f98868a 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -89,15 +89,15 @@ variables are monotonically increasing.
|
||||
@@ -51,7 +49,7 @@ index d7062c6a89464..d8f721f98868a 100644
|
||||
contrast to moving across generations, which requires the LRU lock,
|
||||
moving across tiers only involves atomic operations on
|
||||
``folio->flags`` and therefore has a negligible cost. A feedback loop
|
||||
@@ -127,7 +127,7 @@ page mapped by this PTE to ``(max_seq%MAX_NR_GENS)+1``.
|
||||
@@ -127,7 +127,7 @@ page mapped by this PTE to ``(max_seq%MA
|
||||
Eviction
|
||||
--------
|
||||
The eviction consumes old generations. Given an ``lruvec``, it
|
||||
@@ -60,11 +58,9 @@ index d7062c6a89464..d8f721f98868a 100644
|
||||
``min_seq%MAX_NR_GENS`` becomes empty. To select a type and a tier to
|
||||
evict from, it first compares ``min_seq[]`` to select the older type.
|
||||
If both types are equally old, it selects the one whose first tier has
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index f63968bd7de59..da38e3d962e2f 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -256,9 +256,9 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
|
||||
@@ -256,9 +256,9 @@ static inline bool lru_gen_add_folio(str
|
||||
lru_gen_update_size(lruvec, folio, -1, gen);
|
||||
/* for folio_rotate_reclaimable() */
|
||||
if (reclaiming)
|
||||
@@ -76,8 +72,6 @@ index f63968bd7de59..da38e3d962e2f 100644
|
||||
|
||||
return true;
|
||||
}
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index bd3e4689f72dc..02e4323744715 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -312,7 +312,7 @@ enum lruvec_flags {
|
||||
@@ -109,11 +103,9 @@ index bd3e4689f72dc..02e4323744715 100644
|
||||
/* the multi-gen LRU sizes, eventually consistent */
|
||||
long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
|
||||
/* the exponential moving average of refaulted */
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 27142caf284c1..b02fed912f742 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4258,7 +4258,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
|
||||
@@ -4258,7 +4258,7 @@ static bool inc_min_seq(struct lruvec *l
|
||||
|
||||
/* prevent cold/hot inversion if force_scan is true */
|
||||
for (zone = 0; zone < MAX_NR_ZONES; zone++) {
|
||||
@@ -122,7 +114,7 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
|
||||
while (!list_empty(head)) {
|
||||
struct folio *folio = lru_to_folio(head);
|
||||
@@ -4269,7 +4269,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
|
||||
@@ -4269,7 +4269,7 @@ static bool inc_min_seq(struct lruvec *l
|
||||
VM_WARN_ON_ONCE_FOLIO(folio_zonenum(folio) != zone, folio);
|
||||
|
||||
new_gen = folio_inc_gen(lruvec, folio, false);
|
||||
@@ -131,7 +123,7 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
|
||||
if (!--remaining)
|
||||
return false;
|
||||
@@ -4297,7 +4297,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
|
||||
@@ -4297,7 +4297,7 @@ static bool try_to_inc_min_seq(struct lr
|
||||
gen = lru_gen_from_seq(min_seq[type]);
|
||||
|
||||
for (zone = 0; zone < MAX_NR_ZONES; zone++) {
|
||||
@@ -140,7 +132,7 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
goto next;
|
||||
}
|
||||
|
||||
@@ -4762,7 +4762,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
|
||||
@@ -4762,7 +4762,7 @@ static bool sort_folio(struct lruvec *lr
|
||||
|
||||
/* promoted */
|
||||
if (gen != lru_gen_from_seq(lrugen->min_seq[type])) {
|
||||
@@ -149,7 +141,7 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4771,7 +4771,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
|
||||
@@ -4771,7 +4771,7 @@ static bool sort_folio(struct lruvec *lr
|
||||
int hist = lru_hist_from_seq(lrugen->min_seq[type]);
|
||||
|
||||
gen = folio_inc_gen(lruvec, folio, false);
|
||||
@@ -158,7 +150,7 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
|
||||
WRITE_ONCE(lrugen->protected[hist][type][tier - 1],
|
||||
lrugen->protected[hist][type][tier - 1] + delta);
|
||||
@@ -4783,7 +4783,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
|
||||
@@ -4783,7 +4783,7 @@ static bool sort_folio(struct lruvec *lr
|
||||
if (folio_test_locked(folio) || folio_test_writeback(folio) ||
|
||||
(type == LRU_GEN_FILE && folio_test_dirty(folio))) {
|
||||
gen = folio_inc_gen(lruvec, folio, true);
|
||||
@@ -167,7 +159,7 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4850,7 +4850,7 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
|
||||
@@ -4850,7 +4850,7 @@ static int scan_folios(struct lruvec *lr
|
||||
for (zone = sc->reclaim_idx; zone >= 0; zone--) {
|
||||
LIST_HEAD(moved);
|
||||
int skipped = 0;
|
||||
@@ -176,7 +168,7 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
|
||||
while (!list_empty(head)) {
|
||||
struct folio *folio = lru_to_folio(head);
|
||||
@@ -5250,7 +5250,7 @@ static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
|
||||
@@ -5250,7 +5250,7 @@ static bool __maybe_unused state_is_vali
|
||||
int gen, type, zone;
|
||||
|
||||
for_each_gen_type_zone(gen, type, zone) {
|
||||
@@ -185,7 +177,7 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -5295,7 +5295,7 @@ static bool drain_evictable(struct lruvec *lruvec)
|
||||
@@ -5295,7 +5295,7 @@ static bool drain_evictable(struct lruve
|
||||
int remaining = MAX_LRU_BATCH;
|
||||
|
||||
for_each_gen_type_zone(gen, type, zone) {
|
||||
@@ -194,7 +186,7 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
|
||||
while (!list_empty(head)) {
|
||||
bool success;
|
||||
@@ -5832,7 +5832,7 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
@@ -5832,7 +5832,7 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
lrugen->timestamps[i] = jiffies;
|
||||
|
||||
for_each_gen_type_zone(gen, type, zone)
|
||||
@@ -203,6 +195,3 @@ index 27142caf284c1..b02fed912f742 100644
|
||||
|
||||
lruvec->mm_state.seq = MIN_NR_GENS;
|
||||
init_waitqueue_head(&lruvec->mm_state.wait);
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -40,11 +40,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 81 +++++++++++++++--------------------------------------
|
||||
1 file changed, 23 insertions(+), 58 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index b02fed912f742..991961180b320 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -448,6 +448,11 @@ static bool cgroup_reclaim(struct scan_control *sc)
|
||||
@@ -448,6 +448,11 @@ static bool cgroup_reclaim(struct scan_c
|
||||
return sc->target_mem_cgroup;
|
||||
}
|
||||
|
||||
@@ -56,7 +54,7 @@ index b02fed912f742..991961180b320 100644
|
||||
/**
|
||||
* writeback_throttling_sane - is the usual dirty throttling mechanism available?
|
||||
* @sc: scan_control in question
|
||||
@@ -498,6 +503,11 @@ static bool cgroup_reclaim(struct scan_control *sc)
|
||||
@@ -498,6 +503,11 @@ static bool cgroup_reclaim(struct scan_c
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -68,7 +66,7 @@ index b02fed912f742..991961180b320 100644
|
||||
static bool writeback_throttling_sane(struct scan_control *sc)
|
||||
{
|
||||
return true;
|
||||
@@ -4993,8 +5003,7 @@ static int isolate_folios(struct lruvec *lruvec, struct scan_control *sc, int sw
|
||||
@@ -4993,8 +5003,7 @@ static int isolate_folios(struct lruvec
|
||||
return scanned;
|
||||
}
|
||||
|
||||
@@ -78,7 +76,7 @@ index b02fed912f742..991961180b320 100644
|
||||
{
|
||||
int type;
|
||||
int scanned;
|
||||
@@ -5083,9 +5092,6 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
|
||||
@@ -5083,9 +5092,6 @@ retry:
|
||||
goto retry;
|
||||
}
|
||||
|
||||
@@ -88,7 +86,7 @@ index b02fed912f742..991961180b320 100644
|
||||
return scanned;
|
||||
}
|
||||
|
||||
@@ -5124,67 +5130,26 @@ static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *
|
||||
@@ -5124,67 +5130,26 @@ done:
|
||||
return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
|
||||
}
|
||||
|
||||
@@ -165,7 +163,7 @@ index b02fed912f742..991961180b320 100644
|
||||
|
||||
lru_add_drain();
|
||||
|
||||
@@ -5208,7 +5173,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -5208,7 +5173,7 @@ static void lru_gen_shrink_lruvec(struct
|
||||
if (!nr_to_scan)
|
||||
goto done;
|
||||
|
||||
@@ -174,7 +172,7 @@ index b02fed912f742..991961180b320 100644
|
||||
if (!delta)
|
||||
goto done;
|
||||
|
||||
@@ -5216,7 +5181,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -5216,7 +5181,7 @@ static void lru_gen_shrink_lruvec(struct
|
||||
if (scanned >= nr_to_scan)
|
||||
break;
|
||||
|
||||
@@ -183,7 +181,7 @@ index b02fed912f742..991961180b320 100644
|
||||
break;
|
||||
|
||||
cond_resched();
|
||||
@@ -5666,7 +5631,7 @@ static int run_eviction(struct lruvec *lruvec, unsigned long seq, struct scan_co
|
||||
@@ -5666,7 +5631,7 @@ static int run_eviction(struct lruvec *l
|
||||
if (sc->nr_reclaimed >= nr_to_reclaim)
|
||||
return 0;
|
||||
|
||||
@@ -192,6 +190,3 @@ index b02fed912f742..991961180b320 100644
|
||||
return 0;
|
||||
|
||||
cond_resched();
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -42,8 +42,6 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 126 ++++++++++++++++++++++++----------------------------
|
||||
1 file changed, 59 insertions(+), 67 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 991961180b320..5a2e83e673232 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -136,7 +136,6 @@ struct scan_control {
|
||||
@@ -54,7 +52,7 @@ index 991961180b320..5a2e83e673232 100644
|
||||
unsigned long last_reclaimed;
|
||||
#endif
|
||||
|
||||
@@ -4455,7 +4454,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
@@ -4455,7 +4454,7 @@ done:
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -63,7 +61,7 @@ index 991961180b320..5a2e83e673232 100644
|
||||
struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
|
||||
{
|
||||
int gen, type, zone;
|
||||
@@ -4464,6 +4463,13 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
|
||||
@@ -4464,6 +4463,13 @@ static bool should_run_aging(struct lruv
|
||||
unsigned long total = 0;
|
||||
struct lru_gen_folio *lrugen = &lruvec->lrugen;
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
@@ -77,7 +75,7 @@ index 991961180b320..5a2e83e673232 100644
|
||||
|
||||
for (type = !can_swap; type < ANON_AND_FILE; type++) {
|
||||
unsigned long seq;
|
||||
@@ -4492,8 +4498,6 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
|
||||
@@ -4492,8 +4498,6 @@ static bool should_run_aging(struct lruv
|
||||
* stalls when the number of generations reaches MIN_NR_GENS. Hence, the
|
||||
* ideal number of generations is MIN_NR_GENS+1.
|
||||
*/
|
||||
@@ -86,7 +84,7 @@ index 991961180b320..5a2e83e673232 100644
|
||||
if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
|
||||
return false;
|
||||
|
||||
@@ -4512,40 +4516,54 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
|
||||
@@ -4512,40 +4516,54 @@ static bool should_run_aging(struct lruv
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -162,7 +160,7 @@ index 991961180b320..5a2e83e673232 100644
|
||||
}
|
||||
|
||||
/* to protect the working set of the last N jiffies */
|
||||
@@ -4554,46 +4572,32 @@ static unsigned long lru_gen_min_ttl __read_mostly;
|
||||
@@ -4554,46 +4572,32 @@ static unsigned long lru_gen_min_ttl __r
|
||||
static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
{
|
||||
struct mem_cgroup *memcg;
|
||||
@@ -216,7 +214,7 @@ index 991961180b320..5a2e83e673232 100644
|
||||
*/
|
||||
if (mutex_trylock(&oom_lock)) {
|
||||
struct oom_control oc = {
|
||||
@@ -5101,33 +5105,27 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
|
||||
@@ -5101,33 +5105,27 @@ retry:
|
||||
* reclaim.
|
||||
*/
|
||||
static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
|
||||
@@ -256,7 +254,7 @@ index 991961180b320..5a2e83e673232 100644
|
||||
}
|
||||
|
||||
static unsigned long get_nr_to_reclaim(struct scan_control *sc)
|
||||
@@ -5146,9 +5144,7 @@ static unsigned long get_nr_to_reclaim(struct scan_control *sc)
|
||||
@@ -5146,9 +5144,7 @@ static unsigned long get_nr_to_reclaim(s
|
||||
static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
{
|
||||
struct blk_plug plug;
|
||||
@@ -266,7 +264,7 @@ index 991961180b320..5a2e83e673232 100644
|
||||
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
|
||||
|
||||
lru_add_drain();
|
||||
@@ -5169,13 +5165,13 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -5169,13 +5165,13 @@ static void lru_gen_shrink_lruvec(struct
|
||||
else
|
||||
swappiness = 0;
|
||||
|
||||
@@ -283,7 +281,7 @@ index 991961180b320..5a2e83e673232 100644
|
||||
|
||||
scanned += delta;
|
||||
if (scanned >= nr_to_scan)
|
||||
@@ -5187,10 +5183,6 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -5187,10 +5183,6 @@ static void lru_gen_shrink_lruvec(struct
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
@@ -294,6 +292,3 @@ index 991961180b320..5a2e83e673232 100644
|
||||
clear_mm_walk();
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -24,11 +24,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 124 ++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 62 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 5a2e83e673232..0c47952714b26 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4454,68 +4454,6 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
@@ -4454,68 +4454,6 @@ done:
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -97,7 +95,7 @@ index 5a2e83e673232..0c47952714b26 100644
|
||||
static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
|
||||
{
|
||||
int gen, type, zone;
|
||||
@@ -5099,6 +5037,68 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
|
||||
@@ -5099,6 +5037,68 @@ retry:
|
||||
return scanned;
|
||||
}
|
||||
|
||||
@@ -166,6 +164,3 @@ index 5a2e83e673232..0c47952714b26 100644
|
||||
/*
|
||||
* For future optimizations:
|
||||
* 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -74,11 +74,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 374 +++++++++++++++++++++++++++++++++----
|
||||
6 files changed, 500 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
|
||||
index e039763029563..82d28b052a9e5 100644
|
||||
--- a/include/linux/memcontrol.h
|
||||
+++ b/include/linux/memcontrol.h
|
||||
@@ -790,6 +790,11 @@ static inline void obj_cgroup_put(struct obj_cgroup *objcg)
|
||||
@@ -790,6 +790,11 @@ static inline void obj_cgroup_put(struct
|
||||
percpu_ref_put(&objcg->refcnt);
|
||||
}
|
||||
|
||||
@@ -90,7 +88,7 @@ index e039763029563..82d28b052a9e5 100644
|
||||
static inline void mem_cgroup_put(struct mem_cgroup *memcg)
|
||||
{
|
||||
if (memcg)
|
||||
@@ -1290,6 +1295,11 @@ static inline void obj_cgroup_put(struct obj_cgroup *objcg)
|
||||
@@ -1290,6 +1295,11 @@ static inline void obj_cgroup_put(struct
|
||||
{
|
||||
}
|
||||
|
||||
@@ -102,11 +100,9 @@ index e039763029563..82d28b052a9e5 100644
|
||||
static inline void mem_cgroup_put(struct mem_cgroup *memcg)
|
||||
{
|
||||
}
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index da38e3d962e2f..c1fd3922dc5dd 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -122,6 +122,18 @@ static inline bool lru_gen_in_fault(void)
|
||||
@@ -122,6 +122,18 @@ static inline bool lru_gen_in_fault(void
|
||||
return current->in_lru_fault;
|
||||
}
|
||||
|
||||
@@ -125,7 +121,7 @@ index da38e3d962e2f..c1fd3922dc5dd 100644
|
||||
static inline int lru_gen_from_seq(unsigned long seq)
|
||||
{
|
||||
return seq % MAX_NR_GENS;
|
||||
@@ -297,6 +309,11 @@ static inline bool lru_gen_in_fault(void)
|
||||
@@ -297,6 +309,11 @@ static inline bool lru_gen_in_fault(void
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -137,8 +133,6 @@ index da38e3d962e2f..c1fd3922dc5dd 100644
|
||||
static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
|
||||
{
|
||||
return false;
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index 02e4323744715..66e067a635682 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -7,6 +7,7 @@
|
||||
@@ -180,7 +174,7 @@ index 02e4323744715..66e067a635682 100644
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -479,12 +497,87 @@ void lru_gen_init_lruvec(struct lruvec *lruvec);
|
||||
@@ -479,12 +497,87 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
||||
@@ -269,7 +263,7 @@ index 02e4323744715..66e067a635682 100644
|
||||
static inline void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
{
|
||||
}
|
||||
@@ -494,6 +587,7 @@ static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
@@ -494,6 +587,7 @@ static inline void lru_gen_look_around(s
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
||||
@@ -277,7 +271,7 @@ index 02e4323744715..66e067a635682 100644
|
||||
static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
|
||||
{
|
||||
}
|
||||
@@ -501,7 +595,24 @@ static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
|
||||
@@ -501,7 +595,24 @@ static inline void lru_gen_init_memcg(st
|
||||
static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
{
|
||||
}
|
||||
@@ -312,11 +306,9 @@ index 02e4323744715..66e067a635682 100644
|
||||
#endif
|
||||
|
||||
CACHELINE_PADDING(_pad2_);
|
||||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
|
||||
index 3e8f1ad0fe9db..7815d556e38cc 100644
|
||||
--- a/mm/memcontrol.c
|
||||
+++ b/mm/memcontrol.c
|
||||
@@ -477,6 +477,16 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, int nid)
|
||||
@@ -477,6 +477,16 @@ static void mem_cgroup_update_tree(struc
|
||||
struct mem_cgroup_per_node *mz;
|
||||
struct mem_cgroup_tree_per_node *mctz;
|
||||
|
||||
@@ -333,7 +325,7 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
|
||||
mctz = soft_limit_tree.rb_tree_per_node[nid];
|
||||
if (!mctz)
|
||||
return;
|
||||
@@ -3522,6 +3532,9 @@ unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order,
|
||||
@@ -3522,6 +3532,9 @@ unsigned long mem_cgroup_soft_limit_recl
|
||||
struct mem_cgroup_tree_per_node *mctz;
|
||||
unsigned long excess;
|
||||
|
||||
@@ -343,7 +335,7 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
|
||||
if (order > 0)
|
||||
return 0;
|
||||
|
||||
@@ -5382,6 +5395,7 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css)
|
||||
@@ -5382,6 +5395,7 @@ static int mem_cgroup_css_online(struct
|
||||
if (unlikely(mem_cgroup_is_root(memcg)))
|
||||
queue_delayed_work(system_unbound_wq, &stats_flush_dwork,
|
||||
2UL*HZ);
|
||||
@@ -351,7 +343,7 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
|
||||
return 0;
|
||||
offline_kmem:
|
||||
memcg_offline_kmem(memcg);
|
||||
@@ -5413,6 +5427,7 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
|
||||
@@ -5413,6 +5427,7 @@ static void mem_cgroup_css_offline(struc
|
||||
memcg_offline_kmem(memcg);
|
||||
reparent_shrinker_deferred(memcg);
|
||||
wb_memcg_offline(memcg);
|
||||
@@ -359,7 +351,7 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
|
||||
|
||||
drain_all_stock(memcg);
|
||||
|
||||
@@ -5424,6 +5439,7 @@ static void mem_cgroup_css_released(struct cgroup_subsys_state *css)
|
||||
@@ -5424,6 +5439,7 @@ static void mem_cgroup_css_released(stru
|
||||
struct mem_cgroup *memcg = mem_cgroup_from_css(css);
|
||||
|
||||
invalidate_reclaim_iterators(memcg);
|
||||
@@ -367,11 +359,9 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
|
||||
}
|
||||
|
||||
static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
|
||||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
|
||||
index 69668817fed37..473057b81a9df 100644
|
||||
--- a/mm/page_alloc.c
|
||||
+++ b/mm/page_alloc.c
|
||||
@@ -7957,6 +7957,7 @@ static void __init free_area_init_node(int nid)
|
||||
@@ -7957,6 +7957,7 @@ static void __init free_area_init_node(i
|
||||
pgdat_set_deferred_range(pgdat);
|
||||
|
||||
free_area_init_core(pgdat);
|
||||
@@ -379,8 +369,6 @@ index 69668817fed37..473057b81a9df 100644
|
||||
}
|
||||
|
||||
static void __init free_area_init_memoryless_node(int nid)
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 0c47952714b26..65eb28448f216 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -54,6 +54,8 @@
|
||||
@@ -404,7 +392,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
/* Allocation order */
|
||||
s8 order;
|
||||
|
||||
@@ -3160,6 +3157,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_caps, NR_LRU_GEN_CAPS);
|
||||
@@ -3160,6 +3157,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_ca
|
||||
for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \
|
||||
for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++)
|
||||
|
||||
@@ -414,7 +402,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
|
||||
{
|
||||
struct pglist_data *pgdat = NODE_DATA(nid);
|
||||
@@ -4440,8 +4440,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
@@ -4440,8 +4440,7 @@ done:
|
||||
if (sc->priority <= DEF_PRIORITY - 2)
|
||||
wait_event_killable(lruvec->mm_state.wait,
|
||||
max_seq < READ_ONCE(lrugen->max_seq));
|
||||
@@ -424,7 +412,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
}
|
||||
|
||||
VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
|
||||
@@ -4514,8 +4513,6 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
@@ -4514,8 +4513,6 @@ static void lru_gen_age_node(struct pgli
|
||||
|
||||
VM_WARN_ON_ONCE(!current_is_kswapd());
|
||||
|
||||
@@ -433,7 +421,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
/* check the order to exclude compaction-induced reclaim */
|
||||
if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY)
|
||||
return;
|
||||
@@ -5104,8 +5101,7 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
|
||||
@@ -5104,8 +5101,7 @@ static bool should_run_aging(struct lruv
|
||||
* 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
|
||||
* reclaim.
|
||||
*/
|
||||
@@ -443,7 +431,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
{
|
||||
unsigned long nr_to_scan;
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
@@ -5122,10 +5118,8 @@ static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *
|
||||
@@ -5122,10 +5118,8 @@ static unsigned long get_nr_to_scan(stru
|
||||
if (sc->priority == DEF_PRIORITY)
|
||||
return nr_to_scan;
|
||||
|
||||
@@ -455,7 +443,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
}
|
||||
|
||||
static unsigned long get_nr_to_reclaim(struct scan_control *sc)
|
||||
@@ -5134,29 +5128,18 @@ static unsigned long get_nr_to_reclaim(struct scan_control *sc)
|
||||
@@ -5134,29 +5128,18 @@ static unsigned long get_nr_to_reclaim(s
|
||||
if (!global_reclaim(sc))
|
||||
return -1;
|
||||
|
||||
@@ -487,7 +475,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
|
||||
if (sc->may_swap)
|
||||
swappiness = get_swappiness(lruvec, sc);
|
||||
@@ -5166,7 +5149,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -5166,7 +5149,7 @@ static void lru_gen_shrink_lruvec(struct
|
||||
swappiness = 0;
|
||||
|
||||
nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
|
||||
@@ -496,7 +484,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
break;
|
||||
|
||||
delta = evict_folios(lruvec, sc, swappiness);
|
||||
@@ -5183,11 +5166,252 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -5183,10 +5166,251 @@ static void lru_gen_shrink_lruvec(struct
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
@@ -621,11 +609,11 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
+ if (try_to_shrink_lruvec(lruvec, sc))
|
||||
+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
|
||||
+
|
||||
clear_mm_walk();
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
}
|
||||
|
||||
+ clear_mm_walk();
|
||||
+
|
||||
+ blk_finish_plug(&plug);
|
||||
+}
|
||||
+
|
||||
+#else /* !CONFIG_MEMCG */
|
||||
+
|
||||
+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
@@ -691,9 +679,9 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
+ if (current_is_kswapd())
|
||||
+ sc->nr_reclaimed += reclaimed;
|
||||
+
|
||||
+ clear_mm_walk();
|
||||
+
|
||||
+ blk_finish_plug(&plug);
|
||||
clear_mm_walk();
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
+
|
||||
+ /* kswapd should never fail */
|
||||
+ pgdat->kswapd_failures = 0;
|
||||
@@ -743,13 +731,12 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
|
||||
+
|
||||
+ spin_unlock(&pgdat->memcg_lru.lock);
|
||||
+}
|
||||
}
|
||||
+#endif
|
||||
+
|
||||
|
||||
/******************************************************************************
|
||||
* state change
|
||||
******************************************************************************/
|
||||
@@ -5644,11 +5868,11 @@ static int run_cmd(char cmd, int memcg_id, int nid, unsigned long seq,
|
||||
@@ -5644,11 +5868,11 @@ static int run_cmd(char cmd, int memcg_i
|
||||
|
||||
if (!mem_cgroup_disabled()) {
|
||||
rcu_read_lock();
|
||||
@@ -764,7 +751,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!memcg)
|
||||
@@ -5796,6 +6020,19 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
@@ -5796,6 +6020,19 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
||||
@@ -784,7 +771,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
void lru_gen_init_memcg(struct mem_cgroup *memcg)
|
||||
{
|
||||
INIT_LIST_HEAD(&memcg->mm_list.fifo);
|
||||
@@ -5819,7 +6056,69 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
@@ -5819,7 +6056,69 @@ void lru_gen_exit_memcg(struct mem_cgrou
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -855,7 +842,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
|
||||
static int __init init_lru_gen(void)
|
||||
{
|
||||
@@ -5846,6 +6145,10 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -5846,6 +6145,10 @@ static void lru_gen_shrink_lruvec(struct
|
||||
{
|
||||
}
|
||||
|
||||
@@ -866,7 +853,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
#endif /* CONFIG_LRU_GEN */
|
||||
|
||||
static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
@@ -5859,7 +6162,7 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
@@ -5859,7 +6162,7 @@ static void shrink_lruvec(struct lruvec
|
||||
bool proportional_reclaim;
|
||||
struct blk_plug plug;
|
||||
|
||||
@@ -875,7 +862,7 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
lru_gen_shrink_lruvec(lruvec, sc);
|
||||
return;
|
||||
}
|
||||
@@ -6102,6 +6405,11 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
|
||||
@@ -6102,6 +6405,11 @@ static void shrink_node(pg_data_t *pgdat
|
||||
struct lruvec *target_lruvec;
|
||||
bool reclaimable = false;
|
||||
|
||||
@@ -887,6 +874,3 @@ index 0c47952714b26..65eb28448f216 100644
|
||||
target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
|
||||
|
||||
again:
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -39,11 +39,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 55 +++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 28 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 65eb28448f216..0a0e1250ffc87 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc)
|
||||
@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
|
||||
|
||||
@@ -53,7 +51,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
if (!can_demote(pgdat->node_id, sc) &&
|
||||
mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH)
|
||||
return 0;
|
||||
@@ -4223,7 +4226,7 @@ static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_
|
||||
@@ -4223,7 +4226,7 @@ static void walk_mm(struct lruvec *lruve
|
||||
} while (err == -EAGAIN);
|
||||
}
|
||||
|
||||
@@ -62,7 +60,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
{
|
||||
struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk;
|
||||
|
||||
@@ -4231,7 +4234,7 @@ static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat)
|
||||
@@ -4231,7 +4234,7 @@ static struct lru_gen_mm_walk *set_mm_wa
|
||||
VM_WARN_ON_ONCE(walk);
|
||||
|
||||
walk = &pgdat->mm_walk;
|
||||
@@ -71,7 +69,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
VM_WARN_ON_ONCE(current_is_kswapd());
|
||||
|
||||
walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
|
||||
@@ -4417,7 +4420,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
@@ -4417,7 +4420,7 @@ static bool try_to_inc_max_seq(struct lr
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -80,7 +78,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
if (!walk) {
|
||||
success = iterate_mm_list_nowalk(lruvec, max_seq);
|
||||
goto done;
|
||||
@@ -4486,8 +4489,6 @@ static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -4486,8 +4489,6 @@ static bool lruvec_is_reclaimable(struct
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
DEFINE_MIN_SEQ(lruvec);
|
||||
|
||||
@@ -89,7 +87,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
/* see the comment on lru_gen_folio */
|
||||
gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
|
||||
birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
|
||||
@@ -4743,12 +4744,8 @@ static bool isolate_folio(struct lruvec *lruvec, struct folio *folio, struct sca
|
||||
@@ -4743,12 +4744,8 @@ static bool isolate_folio(struct lruvec
|
||||
{
|
||||
bool success;
|
||||
|
||||
@@ -103,7 +101,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
(folio_test_dirty(folio) ||
|
||||
(folio_test_anon(folio) && !folio_test_swapcache(folio))))
|
||||
return false;
|
||||
@@ -4845,9 +4842,8 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
|
||||
@@ -4845,9 +4842,8 @@ static int scan_folios(struct lruvec *lr
|
||||
__count_vm_events(PGSCAN_ANON + type, isolated);
|
||||
|
||||
/*
|
||||
@@ -115,7 +113,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
*/
|
||||
return isolated || !remaining ? scanned : 0;
|
||||
}
|
||||
@@ -5107,8 +5103,7 @@ static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool
|
||||
@@ -5107,8 +5103,7 @@ static long get_nr_to_scan(struct lruvec
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
DEFINE_MAX_SEQ(lruvec);
|
||||
|
||||
@@ -125,7 +123,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
return 0;
|
||||
|
||||
if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
|
||||
@@ -5136,17 +5131,14 @@ static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
@@ -5136,17 +5131,14 @@ static bool try_to_shrink_lruvec(struct
|
||||
long nr_to_scan;
|
||||
unsigned long scanned = 0;
|
||||
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
|
||||
@@ -148,7 +146,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
|
||||
nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
|
||||
if (nr_to_scan <= 0)
|
||||
@@ -5277,12 +5269,13 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
@@ -5277,12 +5269,13 @@ static void lru_gen_shrink_lruvec(struct
|
||||
struct blk_plug plug;
|
||||
|
||||
VM_WARN_ON_ONCE(global_reclaim(sc));
|
||||
@@ -163,7 +161,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
|
||||
if (try_to_shrink_lruvec(lruvec, sc))
|
||||
lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
|
||||
@@ -5338,11 +5331,19 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
|
||||
@@ -5338,11 +5331,19 @@ static void lru_gen_shrink_node(struct p
|
||||
|
||||
VM_WARN_ON_ONCE(!global_reclaim(sc));
|
||||
|
||||
@@ -184,7 +182,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
|
||||
set_initial_priority(pgdat, sc);
|
||||
|
||||
@@ -5360,7 +5361,7 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
|
||||
@@ -5360,7 +5361,7 @@ static void lru_gen_shrink_node(struct p
|
||||
clear_mm_walk();
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
@@ -193,7 +191,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
/* kswapd should never fail */
|
||||
pgdat->kswapd_failures = 0;
|
||||
}
|
||||
@@ -5932,7 +5933,7 @@ static ssize_t lru_gen_seq_write(struct file *file, const char __user *src,
|
||||
@@ -5932,7 +5933,7 @@ static ssize_t lru_gen_seq_write(struct
|
||||
set_task_reclaim_state(current, &sc.reclaim_state);
|
||||
flags = memalloc_noreclaim_save();
|
||||
blk_start_plug(&plug);
|
||||
@@ -202,6 +200,3 @@ index 65eb28448f216..0a0e1250ffc87 100644
|
||||
err = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -25,11 +25,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 0a0e1250ffc87..aa9746f2bc80b 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4415,7 +4415,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
@@ -4415,7 +4415,7 @@ static bool try_to_inc_max_seq(struct lr
|
||||
* handful of PTEs. Spreading the work out over a period of time usually
|
||||
* is less efficient, but it avoids bursty page faults.
|
||||
*/
|
||||
@@ -38,6 +36,3 @@ index 0a0e1250ffc87..aa9746f2bc80b 100644
|
||||
success = iterate_mm_list_nowalk(lruvec, max_seq);
|
||||
goto done;
|
||||
}
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -27,11 +27,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 25 +++++++++++++++----------
|
||||
1 file changed, 15 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index aa9746f2bc80b..49da02f841c81 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -5206,18 +5206,20 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)
|
||||
@@ -5206,18 +5206,20 @@ static int shrink_one(struct lruvec *lru
|
||||
|
||||
static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
{
|
||||
@@ -54,7 +52,7 @@ index aa9746f2bc80b..49da02f841c81 100644
|
||||
gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -5241,14 +5243,22 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
@@ -5241,14 +5243,22 @@ restart:
|
||||
|
||||
op = shrink_one(lruvec, sc);
|
||||
|
||||
@@ -80,7 +78,7 @@ index aa9746f2bc80b..49da02f841c81 100644
|
||||
/* restart if raced with lru_gen_rotate_memcg() */
|
||||
if (gen != get_nulls_value(pos))
|
||||
goto restart;
|
||||
@@ -5257,11 +5267,6 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
@@ -5257,11 +5267,6 @@ restart:
|
||||
bin = get_memcg_bin(bin + 1);
|
||||
if (bin != first_bin)
|
||||
goto restart;
|
||||
@@ -92,6 +90,3 @@ index aa9746f2bc80b..49da02f841c81 100644
|
||||
}
|
||||
|
||||
static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -60,11 +60,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 5 ++++-
|
||||
4 files changed, 33 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index c1fd3922dc5dd..7bb2e5f94734c 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -595,4 +595,12 @@ pte_install_uffd_wp_if_needed(struct vm_area_struct *vma, unsigned long addr,
|
||||
@@ -595,4 +595,12 @@ pte_install_uffd_wp_if_needed(struct vm_
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -77,11 +75,9 @@ index c1fd3922dc5dd..7bb2e5f94734c 100644
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
diff --git a/mm/memory.c b/mm/memory.c
|
||||
index 747b7ea30f890..c2f48f8003c2e 100644
|
||||
--- a/mm/memory.c
|
||||
+++ b/mm/memory.c
|
||||
@@ -1435,8 +1435,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
|
||||
@@ -1435,8 +1435,7 @@ again:
|
||||
force_flush = 1;
|
||||
set_page_dirty(page);
|
||||
}
|
||||
@@ -91,7 +87,7 @@ index 747b7ea30f890..c2f48f8003c2e 100644
|
||||
mark_page_accessed(page);
|
||||
}
|
||||
rss[mm_counter(page)]--;
|
||||
@@ -5170,8 +5169,8 @@ static inline void mm_account_fault(struct pt_regs *regs,
|
||||
@@ -5170,8 +5169,8 @@ static inline void mm_account_fault(stru
|
||||
#ifdef CONFIG_LRU_GEN
|
||||
static void lru_gen_enter_fault(struct vm_area_struct *vma)
|
||||
{
|
||||
@@ -102,11 +98,9 @@ index 747b7ea30f890..c2f48f8003c2e 100644
|
||||
}
|
||||
|
||||
static void lru_gen_exit_fault(void)
|
||||
diff --git a/mm/rmap.c b/mm/rmap.c
|
||||
index 7da2d8d097d9b..825dac3caa1e5 100644
|
||||
--- a/mm/rmap.c
|
||||
+++ b/mm/rmap.c
|
||||
@@ -823,25 +823,14 @@ static bool folio_referenced_one(struct folio *folio,
|
||||
@@ -823,25 +823,14 @@ static bool folio_referenced_one(struct
|
||||
}
|
||||
|
||||
if (pvmw.pte) {
|
||||
@@ -135,7 +129,7 @@ index 7da2d8d097d9b..825dac3caa1e5 100644
|
||||
} else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
|
||||
if (pmdp_clear_flush_young_notify(vma, address,
|
||||
pvmw.pmd))
|
||||
@@ -875,7 +864,20 @@ static bool invalid_folio_referenced_vma(struct vm_area_struct *vma, void *arg)
|
||||
@@ -875,7 +864,20 @@ static bool invalid_folio_referenced_vma
|
||||
struct folio_referenced_arg *pra = arg;
|
||||
struct mem_cgroup *memcg = pra->memcg;
|
||||
|
||||
@@ -157,7 +151,7 @@ index 7da2d8d097d9b..825dac3caa1e5 100644
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -906,6 +908,7 @@ int folio_referenced(struct folio *folio, int is_locked,
|
||||
@@ -906,6 +908,7 @@ int folio_referenced(struct folio *folio
|
||||
.arg = (void *)&pra,
|
||||
.anon_lock = folio_lock_anon_vma_read,
|
||||
.try_lock = true,
|
||||
@@ -165,7 +159,7 @@ index 7da2d8d097d9b..825dac3caa1e5 100644
|
||||
};
|
||||
|
||||
*vm_flags = 0;
|
||||
@@ -921,15 +924,6 @@ int folio_referenced(struct folio *folio, int is_locked,
|
||||
@@ -921,15 +924,6 @@ int folio_referenced(struct folio *folio
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -181,11 +175,9 @@ index 7da2d8d097d9b..825dac3caa1e5 100644
|
||||
rmap_walk(folio, &rwc);
|
||||
*vm_flags = pra.vm_flags;
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 49da02f841c81..596fed6ae0439 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3778,7 +3778,10 @@ static int should_skip_vma(unsigned long start, unsigned long end, struct mm_wal
|
||||
@@ -3778,7 +3778,10 @@ static int should_skip_vma(unsigned long
|
||||
if (is_vm_hugetlb_page(vma))
|
||||
return true;
|
||||
|
||||
@@ -197,6 +189,3 @@ index 49da02f841c81..596fed6ae0439 100644
|
||||
return true;
|
||||
|
||||
if (vma == get_gate_vma(vma->vm_mm))
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -83,11 +83,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/fadvise.c | 5 ++++-
|
||||
3 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/linux/fs.h b/include/linux/fs.h
|
||||
index f14ecbeab2a9d..97f9c41c1a43a 100644
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -166,6 +166,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
|
||||
@@ -166,6 +166,8 @@ typedef int (dio_iodone_t)(struct kiocb
|
||||
/* File supports DIRECT IO */
|
||||
#define FMODE_CAN_ODIRECT ((__force fmode_t)0x400000)
|
||||
|
||||
@@ -96,11 +94,9 @@ index f14ecbeab2a9d..97f9c41c1a43a 100644
|
||||
/* File was opened by fanotify and shouldn't generate fanotify events */
|
||||
#define FMODE_NONOTIFY ((__force fmode_t)0x4000000)
|
||||
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index 7bb2e5f94734c..9a8e2049333c0 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -600,6 +600,9 @@ static inline bool vma_has_recency(struct vm_area_struct *vma)
|
||||
@@ -600,6 +600,9 @@ static inline bool vma_has_recency(struc
|
||||
if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))
|
||||
return false;
|
||||
|
||||
@@ -110,11 +106,9 @@ index 7bb2e5f94734c..9a8e2049333c0 100644
|
||||
return true;
|
||||
}
|
||||
|
||||
diff --git a/mm/fadvise.c b/mm/fadvise.c
|
||||
index c76ee665355a4..2ba24d865bf5f 100644
|
||||
--- a/mm/fadvise.c
|
||||
+++ b/mm/fadvise.c
|
||||
@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
|
||||
@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, l
|
||||
case POSIX_FADV_NORMAL:
|
||||
file->f_ra.ra_pages = bdi->ra_pages;
|
||||
spin_lock(&file->f_lock);
|
||||
@@ -123,7 +117,7 @@ index c76ee665355a4..2ba24d865bf5f 100644
|
||||
spin_unlock(&file->f_lock);
|
||||
break;
|
||||
case POSIX_FADV_RANDOM:
|
||||
@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
|
||||
@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, l
|
||||
force_page_cache_readahead(mapping, file, start_index, nrpages);
|
||||
break;
|
||||
case POSIX_FADV_NOREUSE:
|
||||
@@ -133,6 +127,3 @@ index c76ee665355a4..2ba24d865bf5f 100644
|
||||
break;
|
||||
case POSIX_FADV_DONTNEED:
|
||||
__filemap_fdatawrite_range(mapping, offset, endbyte,
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -28,11 +28,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 4 ++++
|
||||
2 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index d8f721f98868a..6e1483e70fdca 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -141,6 +141,21 @@ loop has detected outlying refaults from the tier this page is in. To
|
||||
@@ -141,6 +141,21 @@ loop has detected outlying refaults from
|
||||
this end, the feedback loop uses the first tier as the baseline, for
|
||||
the reason stated earlier.
|
||||
|
||||
@@ -54,11 +52,9 @@ index d8f721f98868a..6e1483e70fdca 100644
|
||||
Summary
|
||||
-------
|
||||
The multi-gen LRU can be disassembled into the following parts:
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 596fed6ae0439..ab0b8d3b9d88f 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4459,6 +4459,10 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
@@ -4459,6 +4459,10 @@ done:
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -69,6 +65,3 @@ index 596fed6ae0439..ab0b8d3b9d88f 100644
|
||||
static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
|
||||
{
|
||||
int gen, type, zone;
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -19,11 +19,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 4 ++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index 6e1483e70fdca..bd988a142bc2f 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -156,6 +156,20 @@ This time-based approach has the following advantages:
|
||||
@@ -156,6 +156,20 @@ This time-based approach has the followi
|
||||
and memory sizes.
|
||||
2. It is more reliable because it is directly wired to the OOM killer.
|
||||
|
||||
@@ -44,11 +42,9 @@ index 6e1483e70fdca..bd988a142bc2f 100644
|
||||
Summary
|
||||
-------
|
||||
The multi-gen LRU can be disassembled into the following parts:
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index ab0b8d3b9d88f..8fa82630240d6 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4553,6 +4553,10 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
@@ -4553,6 +4553,10 @@ static void lru_gen_age_node(struct pgli
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +55,3 @@ index ab0b8d3b9d88f..8fa82630240d6 100644
|
||||
/*
|
||||
* This function exploits spatial locality when shrink_folio_list() walks the
|
||||
* rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -20,11 +20,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 180 +++++++++++++++---------------
|
||||
2 files changed, 108 insertions(+), 88 deletions(-)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index bd988a142bc2f..770b5d539856c 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -170,6 +170,22 @@ promotes hot pages. If the scan was done cacheline efficiently, it
|
||||
@@ -170,6 +170,22 @@ promotes hot pages. If the scan was done
|
||||
adds the PMD entry pointing to the PTE table to the Bloom filter. This
|
||||
forms a feedback loop between the eviction and the aging.
|
||||
|
||||
@@ -47,15 +45,12 @@ index bd988a142bc2f..770b5d539856c 100644
|
||||
Summary
|
||||
-------
|
||||
The multi-gen LRU can be disassembled into the following parts:
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 8fa82630240d6..74b4f9d660b56 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3208,6 +3208,98 @@ static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
|
||||
get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS;
|
||||
@@ -3209,6 +3209,98 @@ static bool __maybe_unused seq_is_valid(
|
||||
}
|
||||
|
||||
+/******************************************************************************
|
||||
/******************************************************************************
|
||||
+ * Bloom filters
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
@@ -147,10 +142,11 @@ index 8fa82630240d6..74b4f9d660b56 100644
|
||||
+ WRITE_ONCE(lruvec->mm_state.filters[gen], filter);
|
||||
+}
|
||||
+
|
||||
/******************************************************************************
|
||||
+/******************************************************************************
|
||||
* mm_struct list
|
||||
******************************************************************************/
|
||||
@@ -3333,94 +3425,6 @@ void lru_gen_migrate_mm(struct mm_struct *mm)
|
||||
|
||||
@@ -3333,94 +3425,6 @@ void lru_gen_migrate_mm(struct mm_struct
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -245,6 +241,3 @@ index 8fa82630240d6..74b4f9d660b56 100644
|
||||
static void reset_mm_stats(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, bool last)
|
||||
{
|
||||
int i;
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -22,11 +22,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 250 +++++++++++++++++-------------
|
||||
5 files changed, 178 insertions(+), 143 deletions(-)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index 770b5d539856c..5f1f6ecbb79b9 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -186,9 +186,40 @@ is false positive, the cost is an additional scan of a range of PTEs,
|
||||
@@ -186,9 +186,40 @@ is false positive, the cost is an additi
|
||||
which may yield hot pages anyway. Parameters of the filter itself can
|
||||
control the false positive rate in the limit.
|
||||
|
||||
@@ -68,11 +66,9 @@ index 770b5d539856c..5f1f6ecbb79b9 100644
|
||||
|
||||
* Generations
|
||||
* Rmap walks
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index 9a8e2049333c0..5567f4850243b 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -122,18 +122,6 @@ static inline bool lru_gen_in_fault(void)
|
||||
@@ -122,18 +122,6 @@ static inline bool lru_gen_in_fault(void
|
||||
return current->in_lru_fault;
|
||||
}
|
||||
|
||||
@@ -91,7 +87,7 @@ index 9a8e2049333c0..5567f4850243b 100644
|
||||
static inline int lru_gen_from_seq(unsigned long seq)
|
||||
{
|
||||
return seq % MAX_NR_GENS;
|
||||
@@ -309,11 +297,6 @@ static inline bool lru_gen_in_fault(void)
|
||||
@@ -309,11 +297,6 @@ static inline bool lru_gen_in_fault(void
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -103,8 +99,6 @@ index 9a8e2049333c0..5567f4850243b 100644
|
||||
static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
|
||||
{
|
||||
return false;
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index 66e067a635682..403c7461e7a70 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -368,15 +368,6 @@ struct page_vma_mapped_walk;
|
||||
@@ -123,7 +117,7 @@ index 66e067a635682..403c7461e7a70 100644
|
||||
#ifdef CONFIG_LRU_GEN
|
||||
|
||||
enum {
|
||||
@@ -557,7 +548,7 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg);
|
||||
@@ -557,7 +548,7 @@ void lru_gen_exit_memcg(struct mem_cgrou
|
||||
void lru_gen_online_memcg(struct mem_cgroup *memcg);
|
||||
void lru_gen_offline_memcg(struct mem_cgroup *memcg);
|
||||
void lru_gen_release_memcg(struct mem_cgroup *memcg);
|
||||
@@ -132,7 +126,7 @@ index 66e067a635682..403c7461e7a70 100644
|
||||
|
||||
#else /* !CONFIG_MEMCG */
|
||||
|
||||
@@ -608,7 +599,7 @@ static inline void lru_gen_release_memcg(struct mem_cgroup *memcg)
|
||||
@@ -608,7 +599,7 @@ static inline void lru_gen_release_memcg
|
||||
{
|
||||
}
|
||||
|
||||
@@ -141,11 +135,9 @@ index 66e067a635682..403c7461e7a70 100644
|
||||
{
|
||||
}
|
||||
|
||||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
|
||||
index 7815d556e38cc..5397aeb43986d 100644
|
||||
--- a/mm/memcontrol.c
|
||||
+++ b/mm/memcontrol.c
|
||||
@@ -478,12 +478,8 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, int nid)
|
||||
@@ -478,12 +478,8 @@ static void mem_cgroup_update_tree(struc
|
||||
struct mem_cgroup_tree_per_node *mctz;
|
||||
|
||||
if (lru_gen_enabled()) {
|
||||
@@ -160,15 +152,12 @@ index 7815d556e38cc..5397aeb43986d 100644
|
||||
return;
|
||||
}
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 74b4f9d660b56..ccde215c084ca 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4689,6 +4689,148 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
mem_cgroup_unlock_pages();
|
||||
@@ -4690,6 +4690,148 @@ void lru_gen_look_around(struct page_vma
|
||||
}
|
||||
|
||||
+/******************************************************************************
|
||||
/******************************************************************************
|
||||
+ * memcg LRU
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
@@ -310,10 +299,11 @@ index 74b4f9d660b56..ccde215c084ca 100644
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
/******************************************************************************
|
||||
+/******************************************************************************
|
||||
* the eviction
|
||||
******************************************************************************/
|
||||
@@ -5386,53 +5528,6 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
|
||||
|
||||
@@ -5386,53 +5528,6 @@ done:
|
||||
pgdat->kswapd_failures = 0;
|
||||
}
|
||||
|
||||
@@ -367,7 +357,7 @@ index 74b4f9d660b56..ccde215c084ca 100644
|
||||
/******************************************************************************
|
||||
* state change
|
||||
******************************************************************************/
|
||||
@@ -6078,67 +6173,6 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
@@ -6078,67 +6173,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,6 +425,3 @@ index 74b4f9d660b56..ccde215c084ca 100644
|
||||
#endif /* CONFIG_MEMCG */
|
||||
|
||||
static int __init init_lru_gen(void)
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index ccde215c084ca..d5d6f8d94f58a 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -6160,12 +6160,17 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
@@ -6160,12 +6160,17 @@ void lru_gen_exit_memcg(struct mem_cgrou
|
||||
int i;
|
||||
int nid;
|
||||
|
||||
@@ -40,6 +38,3 @@ index ccde215c084ca..d5d6f8d94f58a 100644
|
||||
for (i = 0; i < NR_BLOOM_FILTERS; i++) {
|
||||
bitmap_free(lruvec->mm_state.filters[i]);
|
||||
lruvec->mm_state.filters[i] = NULL;
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -17,11 +17,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 40 ++++++++++++++++++++--------------------
|
||||
1 file changed, 20 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index d5d6f8d94f58a..8f496c2e670a9 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3980,8 +3980,8 @@ static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end,
|
||||
@@ -3980,8 +3980,8 @@ restart:
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
|
||||
@@ -32,7 +30,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
|
||||
{
|
||||
int i;
|
||||
pmd_t *pmd;
|
||||
@@ -3994,18 +3994,19 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area
|
||||
@@ -3994,18 +3994,19 @@ static void walk_pmd_range_locked(pud_t
|
||||
VM_WARN_ON_ONCE(pud_leaf(*pud));
|
||||
|
||||
/* try to batch at most 1+MIN_LRU_BATCH+1 entries */
|
||||
@@ -56,7 +54,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
|
||||
|
||||
ptl = pmd_lockptr(args->mm, pmd);
|
||||
if (!spin_trylock(ptl))
|
||||
@@ -4016,15 +4017,16 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area
|
||||
@@ -4016,15 +4017,16 @@ static void walk_pmd_range_locked(pud_t
|
||||
do {
|
||||
unsigned long pfn;
|
||||
struct folio *folio;
|
||||
@@ -76,7 +74,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
|
||||
pmdp_test_and_clear_young(vma, addr, pmd + i);
|
||||
goto next;
|
||||
}
|
||||
@@ -4053,12 +4055,11 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area
|
||||
@@ -4053,12 +4055,11 @@ next:
|
||||
arch_leave_lazy_mmu_mode();
|
||||
spin_unlock(ptl);
|
||||
done:
|
||||
@@ -92,7 +90,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -4071,9 +4072,9 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
|
||||
@@ -4071,9 +4072,9 @@ static void walk_pmd_range(pud_t *pud, u
|
||||
unsigned long next;
|
||||
unsigned long addr;
|
||||
struct vm_area_struct *vma;
|
||||
@@ -104,7 +102,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
|
||||
|
||||
VM_WARN_ON_ONCE(pud_leaf(*pud));
|
||||
|
||||
@@ -4115,18 +4116,17 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
|
||||
@@ -4115,18 +4116,17 @@ restart:
|
||||
if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
|
||||
continue;
|
||||
|
||||
@@ -126,7 +124,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
|
||||
}
|
||||
|
||||
if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i))
|
||||
@@ -4143,7 +4143,7 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
|
||||
@@ -4143,7 +4143,7 @@ restart:
|
||||
update_bloom_filter(walk->lruvec, walk->max_seq + 1, pmd + i);
|
||||
}
|
||||
|
||||
@@ -135,6 +133,3 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
|
||||
|
||||
if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end))
|
||||
goto restart;
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -24,11 +24,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
mm/vmscan.c | 73 +++++++++++++++++------------------------------------
|
||||
1 file changed, 23 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 8f496c2e670a9..f6ce7a1fd78a3 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4571,13 +4571,12 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
@@ -4571,13 +4571,12 @@ static void lru_gen_age_node(struct pgli
|
||||
void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
{
|
||||
int i;
|
||||
@@ -44,7 +42,7 @@ index 8f496c2e670a9..f6ce7a1fd78a3 100644
|
||||
struct folio *folio = pfn_folio(pvmw->pfn);
|
||||
struct mem_cgroup *memcg = folio_memcg(folio);
|
||||
struct pglist_data *pgdat = folio_pgdat(folio);
|
||||
@@ -4594,25 +4593,28 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
@@ -4594,25 +4593,28 @@ void lru_gen_look_around(struct page_vma
|
||||
/* avoid taking the LRU lock under the PTL when possible */
|
||||
walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL;
|
||||
|
||||
@@ -81,7 +79,7 @@ index 8f496c2e670a9..f6ce7a1fd78a3 100644
|
||||
for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) {
|
||||
unsigned long pfn;
|
||||
|
||||
@@ -4637,56 +4639,27 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
@@ -4637,56 +4639,27 @@ void lru_gen_look_around(struct page_vma
|
||||
!folio_test_swapcache(folio)))
|
||||
folio_mark_dirty(folio);
|
||||
|
||||
@@ -148,6 +146,3 @@ index 8f496c2e670a9..f6ce7a1fd78a3 100644
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -46,8 +46,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
mm/vmscan.c | 112 +++++++++++++++--------------------------
|
||||
2 files changed, 42 insertions(+), 78 deletions(-)
|
||||
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index 403c7461e7a70..d62a5accf1be4 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -453,18 +453,14 @@ enum {
|
||||
@@ -71,11 +69,9 @@ index 403c7461e7a70..d62a5accf1be4 100644
|
||||
};
|
||||
|
||||
struct lru_gen_mm_walk {
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3371,18 +3371,13 @@ void lru_gen_del_mm(struct mm_struct *mm)
|
||||
@@ -3371,18 +3371,13 @@ void lru_gen_del_mm(struct mm_struct *mm
|
||||
if (!lruvec)
|
||||
continue;
|
||||
|
||||
@@ -99,7 +95,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
}
|
||||
|
||||
list_del_init(&mm->lru_gen.list);
|
||||
@@ -3478,68 +3473,54 @@ static bool iterate_mm_list(struct lruvec *lruvec, struct lru_gen_mm_walk *walk,
|
||||
@@ -3478,68 +3473,54 @@ static bool iterate_mm_list(struct lruve
|
||||
struct mm_struct **iter)
|
||||
{
|
||||
bool first = false;
|
||||
@@ -191,7 +187,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
if (*iter || last)
|
||||
reset_mm_stats(lruvec, walk, last);
|
||||
|
||||
@@ -3567,9 +3548,9 @@ static bool iterate_mm_list_nowalk(struct lruvec *lruvec, unsigned long max_seq)
|
||||
@@ -3567,9 +3548,9 @@ static bool iterate_mm_list_nowalk(struc
|
||||
|
||||
VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq);
|
||||
|
||||
@@ -204,7 +200,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
|
||||
reset_mm_stats(lruvec, NULL, true);
|
||||
success = true;
|
||||
@@ -4172,10 +4153,6 @@ static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end,
|
||||
@@ -4172,10 +4153,6 @@ restart:
|
||||
|
||||
walk_pmd_range(&val, addr, next, args);
|
||||
|
||||
@@ -215,7 +211,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
if (need_resched() || walk->batched >= MAX_LRU_BATCH) {
|
||||
end = (addr | ~PUD_MASK) + 1;
|
||||
goto done;
|
||||
@@ -4208,8 +4185,14 @@ static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_
|
||||
@@ -4208,8 +4185,14 @@ static void walk_mm(struct lruvec *lruve
|
||||
walk->next_addr = FIRST_USER_ADDRESS;
|
||||
|
||||
do {
|
||||
@@ -230,7 +226,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
/* folio_update_gen() requires stable folio_memcg() */
|
||||
if (!mem_cgroup_trylock_pages(memcg))
|
||||
break;
|
||||
@@ -4442,25 +4425,12 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
@@ -4442,25 +4425,12 @@ static bool try_to_inc_max_seq(struct lr
|
||||
success = iterate_mm_list(lruvec, walk, &mm);
|
||||
if (mm)
|
||||
walk_mm(lruvec, mm, walk);
|
||||
@@ -259,7 +255,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -6105,7 +6075,6 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
@@ -6105,7 +6075,6 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]);
|
||||
|
||||
lruvec->mm_state.seq = MIN_NR_GENS;
|
||||
@@ -267,7 +263,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
||||
@@ -6138,7 +6107,6 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
@@ -6138,7 +6107,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
|
||||
for_each_node(nid) {
|
||||
struct lruvec *lruvec = get_lruvec(memcg, nid);
|
||||
|
||||
@@ -275,6 +271,3 @@ index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0,
|
||||
sizeof(lruvec->lrugen.nr_pages)));
|
||||
|
||||
--
|
||||
2.40.1
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From c3552d3f85f06cf4b4818bd84c4fcc09d8d45165 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:17:19 +0100
|
||||
Subject: [PATCH 01/13] net: dsa: mt7530: make some noise if register read
|
||||
fails
|
||||
|
||||
Simply returning the negative error value instead of the read value
|
||||
doesn't seem like a good idea. Return 0 instead and add WARN_ON_ONCE(1)
|
||||
so this kind of error will not go unnoticed.
|
||||
|
||||
Suggested-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -224,9 +224,10 @@ mt7530_mii_read(struct mt7530_priv *priv
|
||||
/* MT7530 uses 31 as the pseudo port */
|
||||
ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
if (ret < 0) {
|
||||
+ WARN_ON_ONCE(1);
|
||||
dev_err(&bus->dev,
|
||||
"failed to read mt7530 register\n");
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
lo = bus->read(bus, 0x1f, r);
|
||||
@@ -0,0 +1,111 @@
|
||||
From b896355fc4988216d4f38582d07add9252a795ae Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:17:30 +0100
|
||||
Subject: [PATCH 02/13] net: dsa: mt7530: refactor SGMII PCS creation
|
||||
|
||||
Instead of macro templates use a dedidated function and allocated
|
||||
regmap_config when creating the regmaps for the pcs-mtk-lynxi
|
||||
instances.
|
||||
This is in preparation to switching to use unlocked regmap accessors
|
||||
and have regmap's locking API handle locking for us.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 74 +++++++++++++++++++++++++++-------------
|
||||
1 file changed, 50 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2950,26 +2950,56 @@ static const struct regmap_bus mt7531_re
|
||||
.reg_update_bits = mt7530_regmap_update_bits,
|
||||
};
|
||||
|
||||
-#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
|
||||
- { \
|
||||
- .name = _name, \
|
||||
- .reg_bits = 16, \
|
||||
- .val_bits = 32, \
|
||||
- .reg_stride = 4, \
|
||||
- .reg_base = _reg_base, \
|
||||
- .max_register = 0x17c, \
|
||||
+static int
|
||||
+mt7531_create_sgmii(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ struct regmap_config *mt7531_pcs_config[2];
|
||||
+ struct phylink_pcs *pcs;
|
||||
+ struct regmap *regmap;
|
||||
+ int i, ret = 0;
|
||||
+
|
||||
+ for (i = 0; i < 2; i++) {
|
||||
+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||||
+ sizeof(struct regmap_config),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!mt7531_pcs_config[i]) {
|
||||
+ ret = -ENOMEM;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
|
||||
+ mt7531_pcs_config[i]->reg_bits = 16;
|
||||
+ mt7531_pcs_config[i]->val_bits = 32;
|
||||
+ mt7531_pcs_config[i]->reg_stride = 4;
|
||||
+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
|
||||
+ mt7531_pcs_config[i]->max_register = 0x17c;
|
||||
+
|
||||
+ regmap = devm_regmap_init(priv->dev,
|
||||
+ &mt7531_regmap_bus, priv,
|
||||
+ mt7531_pcs_config[i]);
|
||||
+ if (IS_ERR(regmap)) {
|
||||
+ ret = PTR_ERR(regmap);
|
||||
+ break;
|
||||
+ }
|
||||
+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
|
||||
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
|
||||
+ if (!pcs) {
|
||||
+ ret = -ENXIO;
|
||||
+ break;
|
||||
+ }
|
||||
+ priv->ports[5 + i].sgmii_pcs = pcs;
|
||||
}
|
||||
|
||||
-static const struct regmap_config mt7531_pcs_config[] = {
|
||||
- MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
|
||||
- MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
|
||||
-};
|
||||
+ if (ret && i)
|
||||
+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
static int
|
||||
mt753x_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- struct regmap *regmap;
|
||||
int i, ret;
|
||||
|
||||
/* Initialise the PCS devices */
|
||||
@@ -2991,15 +3021,11 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
- if (priv->id == ID_MT7531)
|
||||
- for (i = 0; i < 2; i++) {
|
||||
- regmap = devm_regmap_init(ds->dev,
|
||||
- &mt7531_regmap_bus, priv,
|
||||
- &mt7531_pcs_config[i]);
|
||||
- priv->ports[5 + i].sgmii_pcs =
|
||||
- mtk_pcs_lynxi_create(ds->dev, regmap,
|
||||
- MT7531_PHYA_CTRL_SIGNAL3, 0);
|
||||
- }
|
||||
+ if (priv->id == ID_MT7531) {
|
||||
+ ret = mt7531_create_sgmii(priv);
|
||||
+ if (ret && priv->irq)
|
||||
+ mt7530_free_irq_common(priv);
|
||||
+ }
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
From 33396408776385f3d2f6069646169a6b5b28e3b3 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:17:40 +0100
|
||||
Subject: [PATCH 03/13] net: dsa: mt7530: use unlocked regmap accessors
|
||||
|
||||
Instead of wrapping the locked register accessor functions, use the
|
||||
unlocked variants and add locking wrapper functions to let regmap
|
||||
handle the locking.
|
||||
|
||||
This is a preparation towards being able to always use regmap to
|
||||
access switch registers instead of open-coded accessor functions.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 23 ++++++++++++++---------
|
||||
1 file changed, 14 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2923,7 +2923,7 @@ static int mt7530_regmap_read(void *cont
|
||||
{
|
||||
struct mt7530_priv *priv = context;
|
||||
|
||||
- *val = mt7530_read(priv, reg);
|
||||
+ *val = mt7530_mii_read(priv, reg);
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -2931,23 +2931,25 @@ static int mt7530_regmap_write(void *con
|
||||
{
|
||||
struct mt7530_priv *priv = context;
|
||||
|
||||
- mt7530_write(priv, reg, val);
|
||||
+ mt7530_mii_write(priv, reg, val);
|
||||
return 0;
|
||||
};
|
||||
|
||||
-static int mt7530_regmap_update_bits(void *context, unsigned int reg,
|
||||
- unsigned int mask, unsigned int val)
|
||||
+static void
|
||||
+mt7530_mdio_regmap_lock(void *mdio_lock)
|
||||
{
|
||||
- struct mt7530_priv *priv = context;
|
||||
+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+}
|
||||
|
||||
- mt7530_rmw(priv, reg, mask, val);
|
||||
- return 0;
|
||||
-};
|
||||
+static void
|
||||
+mt7530_mdio_regmap_unlock(void *mdio_lock)
|
||||
+{
|
||||
+ mutex_unlock(mdio_lock);
|
||||
+}
|
||||
|
||||
static const struct regmap_bus mt7531_regmap_bus = {
|
||||
.reg_write = mt7530_regmap_write,
|
||||
.reg_read = mt7530_regmap_read,
|
||||
- .reg_update_bits = mt7530_regmap_update_bits,
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -2973,6 +2975,9 @@ mt7531_create_sgmii(struct mt7530_priv *
|
||||
mt7531_pcs_config[i]->reg_stride = 4;
|
||||
mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
|
||||
mt7531_pcs_config[i]->max_register = 0x17c;
|
||||
+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
|
||||
+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
|
||||
+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
|
||||
regmap = devm_regmap_init(priv->dev,
|
||||
&mt7531_regmap_bus, priv,
|
||||
@@ -0,0 +1,224 @@
|
||||
From 743cba4345cb366248f9d375c6a9e50243dc0677 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:17:52 +0100
|
||||
Subject: [PATCH 04/13] net: dsa: mt7530: use regmap to access switch register
|
||||
space
|
||||
|
||||
Use regmap API to access the switch register space.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++++----------------
|
||||
drivers/net/dsa/mt7530.h | 2 +
|
||||
2 files changed, 62 insertions(+), 39 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -183,9 +183,9 @@ core_clear(struct mt7530_priv *priv, u32
|
||||
}
|
||||
|
||||
static int
|
||||
-mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
+ struct mii_bus *bus = context;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
@@ -197,24 +197,34 @@ mt7530_mii_write(struct mt7530_priv *pri
|
||||
/* MT7530 uses 31 as the pseudo port */
|
||||
ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
if (ret < 0)
|
||||
- goto err;
|
||||
+ return ret;
|
||||
|
||||
ret = bus->write(bus, 0x1f, r, lo);
|
||||
if (ret < 0)
|
||||
- goto err;
|
||||
+ return ret;
|
||||
|
||||
ret = bus->write(bus, 0x1f, 0x10, hi);
|
||||
-err:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_write(priv->regmap, reg, val);
|
||||
+
|
||||
if (ret < 0)
|
||||
- dev_err(&bus->dev,
|
||||
+ dev_err(priv->dev,
|
||||
"failed to write mt7530 register\n");
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static u32
|
||||
-mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
|
||||
+static int
|
||||
+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
+ struct mii_bus *bus = context;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
@@ -223,17 +233,32 @@ mt7530_mii_read(struct mt7530_priv *priv
|
||||
|
||||
/* MT7530 uses 31 as the pseudo port */
|
||||
ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
- if (ret < 0) {
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ lo = bus->read(bus, 0x1f, r);
|
||||
+ hi = bus->read(bus, 0x1f, 0x10);
|
||||
+
|
||||
+ *val = (hi << 16) | (lo & 0xffff);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static u32
|
||||
+mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u32 val;
|
||||
+
|
||||
+ ret = regmap_read(priv->regmap, reg, &val);
|
||||
+ if (ret) {
|
||||
WARN_ON_ONCE(1);
|
||||
- dev_err(&bus->dev,
|
||||
+ dev_err(priv->dev,
|
||||
"failed to read mt7530 register\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
- lo = bus->read(bus, 0x1f, r);
|
||||
- hi = bus->read(bus, 0x1f, 0x10);
|
||||
-
|
||||
- return (hi << 16) | (lo & 0xffff);
|
||||
+ return val;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -283,14 +308,10 @@ mt7530_rmw(struct mt7530_priv *priv, u32
|
||||
u32 mask, u32 set)
|
||||
{
|
||||
struct mii_bus *bus = priv->bus;
|
||||
- u32 val;
|
||||
|
||||
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
|
||||
- val = mt7530_mii_read(priv, reg);
|
||||
- val &= ~mask;
|
||||
- val |= set;
|
||||
- mt7530_mii_write(priv, reg, val);
|
||||
+ regmap_update_bits(priv->regmap, reg, mask, set);
|
||||
|
||||
mutex_unlock(&bus->mdio_lock);
|
||||
}
|
||||
@@ -298,7 +319,7 @@ mt7530_rmw(struct mt7530_priv *priv, u32
|
||||
static void
|
||||
mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
- mt7530_rmw(priv, reg, 0, val);
|
||||
+ mt7530_rmw(priv, reg, val, val);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2919,22 +2940,6 @@ static const struct phylink_pcs_ops mt75
|
||||
.pcs_an_restart = mt7530_pcs_an_restart,
|
||||
};
|
||||
|
||||
-static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
-{
|
||||
- struct mt7530_priv *priv = context;
|
||||
-
|
||||
- *val = mt7530_mii_read(priv, reg);
|
||||
- return 0;
|
||||
-};
|
||||
-
|
||||
-static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
-{
|
||||
- struct mt7530_priv *priv = context;
|
||||
-
|
||||
- mt7530_mii_write(priv, reg, val);
|
||||
- return 0;
|
||||
-};
|
||||
-
|
||||
static void
|
||||
mt7530_mdio_regmap_lock(void *mdio_lock)
|
||||
{
|
||||
@@ -2947,7 +2952,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc
|
||||
mutex_unlock(mdio_lock);
|
||||
}
|
||||
|
||||
-static const struct regmap_bus mt7531_regmap_bus = {
|
||||
+static const struct regmap_bus mt7530_regmap_bus = {
|
||||
.reg_write = mt7530_regmap_write,
|
||||
.reg_read = mt7530_regmap_read,
|
||||
};
|
||||
@@ -2980,7 +2985,7 @@ mt7531_create_sgmii(struct mt7530_priv *
|
||||
mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
|
||||
regmap = devm_regmap_init(priv->dev,
|
||||
- &mt7531_regmap_bus, priv,
|
||||
+ &mt7530_regmap_bus, priv->bus,
|
||||
mt7531_pcs_config[i]);
|
||||
if (IS_ERR(regmap)) {
|
||||
ret = PTR_ERR(regmap);
|
||||
@@ -3145,6 +3150,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match)
|
||||
static int
|
||||
mt7530_probe(struct mdio_device *mdiodev)
|
||||
{
|
||||
+ static struct regmap_config *regmap_config;
|
||||
struct mt7530_priv *priv;
|
||||
struct device_node *dn;
|
||||
|
||||
@@ -3224,6 +3230,21 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
mutex_init(&priv->reg_mutex);
|
||||
dev_set_drvdata(&mdiodev->dev, priv);
|
||||
|
||||
+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!regmap_config)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ regmap_config->reg_bits = 16;
|
||||
+ regmap_config->val_bits = 32;
|
||||
+ regmap_config->reg_stride = 4;
|
||||
+ regmap_config->max_register = MT7530_CREV;
|
||||
+ regmap_config->disable_locking = true;
|
||||
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
|
||||
+ priv->bus, regmap_config);
|
||||
+ if (IS_ERR(priv->regmap))
|
||||
+ return PTR_ERR(priv->regmap);
|
||||
+
|
||||
return dsa_register_switch(priv->ds);
|
||||
}
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -747,6 +747,7 @@ struct mt753x_info {
|
||||
* @dev: The device pointer
|
||||
* @ds: The pointer to the dsa core structure
|
||||
* @bus: The bus used for the device and built-in PHY
|
||||
+ * @regmap: The regmap instance representing all switch registers
|
||||
* @rstc: The pointer to reset control used by MCM
|
||||
* @core_pwr: The power supplied into the core
|
||||
* @io_pwr: The power supplied into the I/O
|
||||
@@ -767,6 +768,7 @@ struct mt7530_priv {
|
||||
struct device *dev;
|
||||
struct dsa_switch *ds;
|
||||
struct mii_bus *bus;
|
||||
+ struct regmap *regmap;
|
||||
struct reset_control *rstc;
|
||||
struct regulator *core_pwr;
|
||||
struct regulator *io_pwr;
|
||||
@@ -0,0 +1,54 @@
|
||||
From f3cf1d06e2aef644b426c23b4bb570780b1f8d47 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:04 +0100
|
||||
Subject: [PATCH 05/13] net: dsa: mt7530: move SGMII PCS creation to
|
||||
mt7530_probe function
|
||||
|
||||
Move creating the SGMII PCS from mt753x_setup() to the more appropriate
|
||||
mt7530_probe() function.
|
||||
This is done also in preparation of moving all functions related to
|
||||
MDIO-connected MT753x switches to a separate module.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 13 +++++++------
|
||||
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3031,12 +3031,6 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
- if (priv->id == ID_MT7531) {
|
||||
- ret = mt7531_create_sgmii(priv);
|
||||
- if (ret && priv->irq)
|
||||
- mt7530_free_irq_common(priv);
|
||||
- }
|
||||
-
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3153,6 +3147,7 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
static struct regmap_config *regmap_config;
|
||||
struct mt7530_priv *priv;
|
||||
struct device_node *dn;
|
||||
+ int ret;
|
||||
|
||||
dn = mdiodev->dev.of_node;
|
||||
|
||||
@@ -3245,6 +3240,12 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
+ if (priv->id == ID_MT7531) {
|
||||
+ ret = mt7531_create_sgmii(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
return dsa_register_switch(priv->ds);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
From e4729ae7c095c0c87794bff47ea43e35d69de986 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:16 +0100
|
||||
Subject: [PATCH 06/13] net: dsa: mt7530: introduce mutex helpers
|
||||
|
||||
As the MDIO bus lock only needs to be involved if actually operating
|
||||
on an MDIO-connected switch we will need to skip locking for built-in
|
||||
switches which are accessed via MMIO.
|
||||
Create helper functions which simplify that upcoming change.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 73 ++++++++++++++++++++--------------------
|
||||
1 file changed, 36 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -143,31 +143,40 @@ err:
|
||||
}
|
||||
|
||||
static void
|
||||
-core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
+mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+}
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+static void
|
||||
+mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ mutex_unlock(&priv->bus->mdio_lock);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
+{
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static void
|
||||
core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
u32 val;
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
|
||||
val &= ~mask;
|
||||
val |= set;
|
||||
core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -264,13 +273,11 @@ mt7530_mii_read(struct mt7530_priv *priv
|
||||
static void
|
||||
mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
-
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
mt7530_mii_write(priv, reg, val);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static u32
|
||||
@@ -282,14 +289,13 @@ _mt7530_unlocked_read(struct mt7530_dumm
|
||||
static u32
|
||||
_mt7530_read(struct mt7530_dummy_poll *p)
|
||||
{
|
||||
- struct mii_bus *bus = p->priv->bus;
|
||||
u32 val;
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(p->priv);
|
||||
|
||||
val = mt7530_mii_read(p->priv, p->reg);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(p->priv);
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -307,13 +313,11 @@ static void
|
||||
mt7530_rmw(struct mt7530_priv *priv, u32 reg,
|
||||
u32 mask, u32 set)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
-
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
regmap_update_bits(priv->regmap, reg, mask, set);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -645,14 +649,13 @@ static int
|
||||
mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
|
||||
int regnum)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
struct mt7530_dummy_poll p;
|
||||
u32 reg, val;
|
||||
int ret;
|
||||
|
||||
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -685,7 +688,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr
|
||||
|
||||
ret = val & MT7531_MDIO_RW_DATA_MASK;
|
||||
out:
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -694,14 +697,13 @@ static int
|
||||
mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
|
||||
int regnum, u32 data)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
struct mt7530_dummy_poll p;
|
||||
u32 val, reg;
|
||||
int ret;
|
||||
|
||||
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -733,7 +735,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p
|
||||
}
|
||||
|
||||
out:
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -741,14 +743,13 @@ out:
|
||||
static int
|
||||
mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
struct mt7530_dummy_poll p;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -771,7 +772,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr
|
||||
|
||||
ret = val & MT7531_MDIO_RW_DATA_MASK;
|
||||
out:
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -780,14 +781,13 @@ static int
|
||||
mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
|
||||
u16 data)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
struct mt7530_dummy_poll p;
|
||||
int ret;
|
||||
u32 reg;
|
||||
|
||||
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
|
||||
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -809,7 +809,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p
|
||||
}
|
||||
|
||||
out:
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1109,7 +1109,6 @@ static int
|
||||
mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
int length;
|
||||
u32 val;
|
||||
|
||||
@@ -1120,7 +1119,7 @@ mt7530_port_change_mtu(struct dsa_switch
|
||||
if (!dsa_is_cpu_port(ds, port))
|
||||
return 0;
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
val = mt7530_mii_read(priv, MT7530_GMACCR);
|
||||
val &= ~MAX_RX_PKT_LEN_MASK;
|
||||
@@ -1141,7 +1140,7 @@ mt7530_port_change_mtu(struct dsa_switch
|
||||
|
||||
mt7530_mii_write(priv, MT7530_GMACCR, val);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1942,10 +1941,10 @@ mt7530_irq_thread_fn(int irq, void *dev_
|
||||
u32 val;
|
||||
int p;
|
||||
|
||||
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
val = mt7530_mii_read(priv, MT7530_SYS_INT_STS);
|
||||
mt7530_mii_write(priv, MT7530_SYS_INT_STS, val);
|
||||
- mutex_unlock(&priv->bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
for (p = 0; p < MT7530_NUM_PHYS; p++) {
|
||||
if (BIT(p) & val) {
|
||||
@@ -1981,7 +1980,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
|
||||
{
|
||||
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
|
||||
|
||||
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1990,7 +1989,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da
|
||||
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
|
||||
|
||||
mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
|
||||
- mutex_unlock(&priv->bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static struct irq_chip mt7530_irq_chip = {
|
||||
@@ -0,0 +1,75 @@
|
||||
From 0d7ae94a0c581f86939bebec0b6ccd66e640d1d8 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:28 +0100
|
||||
Subject: [PATCH 07/13] net: dsa: mt7530: move p5_intf_modes() function to
|
||||
mt7530.c
|
||||
|
||||
In preparation of splitting mt7530.c into a driver for MDIO-connected
|
||||
as well as MDIO-accessed built-in switches on one hand and MMIO-accessed
|
||||
built-in switches move the p5_inft_modes() function from mt7530.h to
|
||||
mt7530.c. The function is only needed there and will trigger a compiler
|
||||
warning about a defined but unused function otherwise when including
|
||||
mt7530.h in the to-be-introduced bus-specific drivers.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 18 ++++++++++++++++++
|
||||
drivers/net/dsa/mt7530.h | 18 ------------------
|
||||
2 files changed, 18 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -950,6 +950,24 @@ mt7530_set_ageing_time(struct dsa_switch
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const char *p5_intf_modes(unsigned int p5_interface)
|
||||
+{
|
||||
+ switch (p5_interface) {
|
||||
+ case P5_DISABLED:
|
||||
+ return "DISABLED";
|
||||
+ case P5_INTF_SEL_PHY_P0:
|
||||
+ return "PHY P0";
|
||||
+ case P5_INTF_SEL_PHY_P4:
|
||||
+ return "PHY P4";
|
||||
+ case P5_INTF_SEL_GMAC5:
|
||||
+ return "GMAC5";
|
||||
+ case P5_INTF_SEL_GMAC5_SGMII:
|
||||
+ return "GMAC5_SGMII";
|
||||
+ default:
|
||||
+ return "unknown";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -682,24 +682,6 @@ enum p5_interface_select {
|
||||
P5_INTF_SEL_GMAC5_SGMII,
|
||||
};
|
||||
|
||||
-static const char *p5_intf_modes(unsigned int p5_interface)
|
||||
-{
|
||||
- switch (p5_interface) {
|
||||
- case P5_DISABLED:
|
||||
- return "DISABLED";
|
||||
- case P5_INTF_SEL_PHY_P0:
|
||||
- return "PHY P0";
|
||||
- case P5_INTF_SEL_PHY_P4:
|
||||
- return "PHY P4";
|
||||
- case P5_INTF_SEL_GMAC5:
|
||||
- return "GMAC5";
|
||||
- case P5_INTF_SEL_GMAC5_SGMII:
|
||||
- return "GMAC5_SGMII";
|
||||
- default:
|
||||
- return "unknown";
|
||||
- }
|
||||
-}
|
||||
-
|
||||
struct mt7530_priv;
|
||||
|
||||
struct mt753x_pcs {
|
||||
@@ -0,0 +1,155 @@
|
||||
From 4d632005c90e253c000d0db73b7cdb9d8dc2e2dd Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:39 +0100
|
||||
Subject: [PATCH 08/13] net: dsa: mt7530: introduce mt7530_probe_common helper
|
||||
function
|
||||
|
||||
Move commonly used parts from mt7530_probe into new mt7530_probe_common
|
||||
helper function which will be used by both, mt7530_probe and the
|
||||
to-be-introduced mt7988_probe.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 98 ++++++++++++++++++++++------------------
|
||||
1 file changed, 54 insertions(+), 44 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3159,44 +3159,21 @@ static const struct of_device_id mt7530_
|
||||
MODULE_DEVICE_TABLE(of, mt7530_of_match);
|
||||
|
||||
static int
|
||||
-mt7530_probe(struct mdio_device *mdiodev)
|
||||
+mt7530_probe_common(struct mt7530_priv *priv)
|
||||
{
|
||||
- static struct regmap_config *regmap_config;
|
||||
- struct mt7530_priv *priv;
|
||||
- struct device_node *dn;
|
||||
- int ret;
|
||||
+ struct device *dev = priv->dev;
|
||||
|
||||
- dn = mdiodev->dev.of_node;
|
||||
-
|
||||
- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
|
||||
+ priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
|
||||
if (!priv->ds)
|
||||
return -ENOMEM;
|
||||
|
||||
- priv->ds->dev = &mdiodev->dev;
|
||||
+ priv->ds->dev = dev;
|
||||
priv->ds->num_ports = MT7530_NUM_PORTS;
|
||||
|
||||
- /* Use medatek,mcm property to distinguish hardware type that would
|
||||
- * casues a little bit differences on power-on sequence.
|
||||
- */
|
||||
- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
|
||||
- if (priv->mcm) {
|
||||
- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
|
||||
-
|
||||
- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
|
||||
- if (IS_ERR(priv->rstc)) {
|
||||
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
- return PTR_ERR(priv->rstc);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* Get the hardware identifier from the devicetree node.
|
||||
* We will need it for some of the clock and regulator setup.
|
||||
*/
|
||||
- priv->info = of_device_get_match_data(&mdiodev->dev);
|
||||
+ priv->info = of_device_get_match_data(dev);
|
||||
if (!priv->info)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -3210,23 +3187,53 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
return -EINVAL;
|
||||
|
||||
priv->id = priv->info->id;
|
||||
+ priv->dev = dev;
|
||||
+ priv->ds->priv = priv;
|
||||
+ priv->ds->ops = &mt7530_switch_ops;
|
||||
+ mutex_init(&priv->reg_mutex);
|
||||
+ dev_set_drvdata(dev, priv);
|
||||
|
||||
- if (priv->id == ID_MT7530) {
|
||||
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
|
||||
- if (IS_ERR(priv->core_pwr))
|
||||
- return PTR_ERR(priv->core_pwr);
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
|
||||
- if (IS_ERR(priv->io_pwr))
|
||||
- return PTR_ERR(priv->io_pwr);
|
||||
- }
|
||||
+static int
|
||||
+mt7530_probe(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+ static struct regmap_config *regmap_config;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ struct device_node *dn;
|
||||
+ int ret;
|
||||
+
|
||||
+ dn = mdiodev->dev.of_node;
|
||||
+
|
||||
+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
|
||||
- /* Not MCM that indicates switch works as the remote standalone
|
||||
+ priv->bus = mdiodev->bus;
|
||||
+ priv->dev = &mdiodev->dev;
|
||||
+
|
||||
+ ret = mt7530_probe_common(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Use medatek,mcm property to distinguish hardware type that would
|
||||
+ * cause a little bit differences on power-on sequence.
|
||||
+ * Not MCM that indicates switch works as the remote standalone
|
||||
* integrated circuit so the GPIO pin would be used to complete
|
||||
* the reset, otherwise memory-mapped register accessing used
|
||||
* through syscon provides in the case of MCM.
|
||||
*/
|
||||
- if (!priv->mcm) {
|
||||
+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
|
||||
+ if (priv->mcm) {
|
||||
+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
|
||||
+
|
||||
+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
|
||||
+ if (IS_ERR(priv->rstc)) {
|
||||
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
+ return PTR_ERR(priv->rstc);
|
||||
+ }
|
||||
+ } else {
|
||||
priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(priv->reset)) {
|
||||
@@ -3235,12 +3242,15 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
}
|
||||
}
|
||||
|
||||
- priv->bus = mdiodev->bus;
|
||||
- priv->dev = &mdiodev->dev;
|
||||
- priv->ds->priv = priv;
|
||||
- priv->ds->ops = &mt7530_switch_ops;
|
||||
- mutex_init(&priv->reg_mutex);
|
||||
- dev_set_drvdata(&mdiodev->dev, priv);
|
||||
+ if (priv->id == ID_MT7530) {
|
||||
+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
|
||||
+ if (IS_ERR(priv->core_pwr))
|
||||
+ return PTR_ERR(priv->core_pwr);
|
||||
+
|
||||
+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
|
||||
+ if (IS_ERR(priv->io_pwr))
|
||||
+ return PTR_ERR(priv->io_pwr);
|
||||
+ }
|
||||
|
||||
regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
|
||||
GFP_KERNEL);
|
||||
@@ -0,0 +1,54 @@
|
||||
From 69b838d2629e6b82bcd9e0ab3c1c03f46e5e01d3 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:50 +0100
|
||||
Subject: [PATCH 09/13] net: dsa: mt7530: introduce mt7530_remove_common helper
|
||||
function
|
||||
|
||||
Move commonly used parts from mt7530_remove into new
|
||||
mt7530_remove_common helper function which will be used by both,
|
||||
mt7530_remove and the to-be-introduced mt7988_remove.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3277,6 +3277,17 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
}
|
||||
|
||||
static void
|
||||
+mt7530_remove_common(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ if (priv->irq)
|
||||
+ mt7530_free_irq(priv);
|
||||
+
|
||||
+ dsa_unregister_switch(priv->ds);
|
||||
+
|
||||
+ mutex_destroy(&priv->reg_mutex);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
mt7530_remove(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
@@ -3295,15 +3306,10 @@ mt7530_remove(struct mdio_device *mdiode
|
||||
dev_err(priv->dev, "Failed to disable io pwr: %d\n",
|
||||
ret);
|
||||
|
||||
- if (priv->irq)
|
||||
- mt7530_free_irq(priv);
|
||||
-
|
||||
- dsa_unregister_switch(priv->ds);
|
||||
+ mt7530_remove_common(priv);
|
||||
|
||||
for (i = 0; i < 2; ++i)
|
||||
mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
|
||||
-
|
||||
- mutex_destroy(&priv->reg_mutex);
|
||||
}
|
||||
|
||||
static void mt7530_shutdown(struct mdio_device *mdiodev)
|
||||
@@ -0,0 +1,691 @@
|
||||
From 8eceed6dbd74067dbf4d8e39f14734f4d2f35176 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:19:13 +0100
|
||||
Subject: [PATCH 10/13] net: dsa: mt7530: introduce separate MDIO driver
|
||||
|
||||
Split MT7530 switch driver into a common part and a part specific
|
||||
for MDIO connected switches and multi-chip modules.
|
||||
Move MDIO-specific functions to newly introduced mt7530-mdio.c while
|
||||
keeping the common parts in mt7530.c.
|
||||
Introduce new Kconfig symbol CONFIG_NET_DSA_MT7530_MDIO which is
|
||||
implied by CONFIG_NET_DSA_MT7530.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/net/dsa/Kconfig | 16 +-
|
||||
drivers/net/dsa/Makefile | 1 +
|
||||
drivers/net/dsa/mt7530-mdio.c | 271 ++++++++++++++++++++++++++++++++++
|
||||
drivers/net/dsa/mt7530.c | 264 +--------------------------------
|
||||
drivers/net/dsa/mt7530.h | 6 +
|
||||
6 files changed, 301 insertions(+), 258 deletions(-)
|
||||
create mode 100644 drivers/net/dsa/mt7530-mdio.c
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -13060,6 +13060,7 @@ M: Landen Chao <Landen.Chao@mediatek.com
|
||||
M: DENG Qingfang <dqfext@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
+F: drivers/net/dsa/mt7530-mdio.c
|
||||
F: drivers/net/dsa/mt7530.*
|
||||
F: net/dsa/tag_mtk.c
|
||||
|
||||
--- a/drivers/net/dsa/Kconfig
|
||||
+++ b/drivers/net/dsa/Kconfig
|
||||
@@ -37,10 +37,22 @@ config NET_DSA_MT7530
|
||||
tristate "MediaTek MT753x and MT7621 Ethernet switch support"
|
||||
select NET_DSA_TAG_MTK
|
||||
select MEDIATEK_GE_PHY
|
||||
+ imply NET_DSA_MT7530_MDIO
|
||||
+ help
|
||||
+ This enables support for the MediaTek MT7530 and MT7531 Ethernet
|
||||
+ switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
|
||||
+ MT7621ST and MT7623AI SoCs, and built-in switch in MT7988 SoC are
|
||||
+ supported as well.
|
||||
+
|
||||
+config NET_DSA_MT7530_MDIO
|
||||
+ tristate "MediaTek MT7530 MDIO interface driver"
|
||||
+ depends on NET_DSA_MT7530
|
||||
select PCS_MTK_LYNXI
|
||||
help
|
||||
- This enables support for the MediaTek MT7530, MT7531, and MT7621
|
||||
- Ethernet switch chips.
|
||||
+ This enables support for the MediaTek MT7530 and MT7531 switch
|
||||
+ chips which are connected via MDIO, as well as multi-chip
|
||||
+ module MT7530 which can be found in the MT7621AT, MT7621DAT,
|
||||
+ MT7621ST and MT7623AI SoCs.
|
||||
|
||||
config NET_DSA_MV88E6060
|
||||
tristate "Marvell 88E6060 ethernet switch chip support"
|
||||
--- a/drivers/net/dsa/Makefile
|
||||
+++ b/drivers/net/dsa/Makefile
|
||||
@@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi
|
||||
endif
|
||||
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
|
||||
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
|
||||
+obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
|
||||
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
|
||||
obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
|
||||
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mt7530-mdio.c
|
||||
@@ -0,0 +1,271 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+
|
||||
+#include <linux/gpio/consumer.h>
|
||||
+#include <linux/mdio.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/pcs/pcs-mtk-lynxi.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_mdio.h>
|
||||
+#include <linux/of_net.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+#include <net/dsa.h>
|
||||
+
|
||||
+#include "mt7530.h"
|
||||
+
|
||||
+static int
|
||||
+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
+{
|
||||
+ struct mii_bus *bus = context;
|
||||
+ u16 page, r, lo, hi;
|
||||
+ int ret;
|
||||
+
|
||||
+ page = (reg >> 6) & 0x3ff;
|
||||
+ r = (reg >> 2) & 0xf;
|
||||
+ lo = val & 0xffff;
|
||||
+ hi = val >> 16;
|
||||
+
|
||||
+ /* MT7530 uses 31 as the pseudo port */
|
||||
+ ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bus->write(bus, 0x1f, r, lo);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bus->write(bus, 0x1f, 0x10, hi);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
+{
|
||||
+ struct mii_bus *bus = context;
|
||||
+ u16 page, r, lo, hi;
|
||||
+ int ret;
|
||||
+
|
||||
+ page = (reg >> 6) & 0x3ff;
|
||||
+ r = (reg >> 2) & 0xf;
|
||||
+
|
||||
+ /* MT7530 uses 31 as the pseudo port */
|
||||
+ ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ lo = bus->read(bus, 0x1f, r);
|
||||
+ hi = bus->read(bus, 0x1f, 0x10);
|
||||
+
|
||||
+ *val = (hi << 16) | (lo & 0xffff);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7530_mdio_regmap_lock(void *mdio_lock)
|
||||
+{
|
||||
+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7530_mdio_regmap_unlock(void *mdio_lock)
|
||||
+{
|
||||
+ mutex_unlock(mdio_lock);
|
||||
+}
|
||||
+
|
||||
+static const struct regmap_bus mt7530_regmap_bus = {
|
||||
+ .reg_write = mt7530_regmap_write,
|
||||
+ .reg_read = mt7530_regmap_read,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mt7531_create_sgmii(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ struct regmap_config *mt7531_pcs_config[2];
|
||||
+ struct phylink_pcs *pcs;
|
||||
+ struct regmap *regmap;
|
||||
+ int i, ret = 0;
|
||||
+
|
||||
+ for (i = 0; i < 2; i++) {
|
||||
+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||||
+ sizeof(struct regmap_config),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!mt7531_pcs_config[i]) {
|
||||
+ ret = -ENOMEM;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
|
||||
+ mt7531_pcs_config[i]->reg_bits = 16;
|
||||
+ mt7531_pcs_config[i]->val_bits = 32;
|
||||
+ mt7531_pcs_config[i]->reg_stride = 4;
|
||||
+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
|
||||
+ mt7531_pcs_config[i]->max_register = 0x17c;
|
||||
+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
|
||||
+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
|
||||
+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
+
|
||||
+ regmap = devm_regmap_init(priv->dev,
|
||||
+ &mt7530_regmap_bus, priv->bus,
|
||||
+ mt7531_pcs_config[i]);
|
||||
+ if (IS_ERR(regmap)) {
|
||||
+ ret = PTR_ERR(regmap);
|
||||
+ break;
|
||||
+ }
|
||||
+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
|
||||
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
|
||||
+ if (!pcs) {
|
||||
+ ret = -ENXIO;
|
||||
+ break;
|
||||
+ }
|
||||
+ priv->ports[5 + i].sgmii_pcs = pcs;
|
||||
+ }
|
||||
+
|
||||
+ if (ret && i)
|
||||
+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mt7530_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
|
||||
+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
|
||||
+ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt7530_of_match);
|
||||
+
|
||||
+static int
|
||||
+mt7530_probe(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+ static struct regmap_config *regmap_config;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ struct device_node *dn;
|
||||
+ int ret;
|
||||
+
|
||||
+ dn = mdiodev->dev.of_node;
|
||||
+
|
||||
+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv->bus = mdiodev->bus;
|
||||
+ priv->dev = &mdiodev->dev;
|
||||
+
|
||||
+ ret = mt7530_probe_common(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Use medatek,mcm property to distinguish hardware type that would
|
||||
+ * cause a little bit differences on power-on sequence.
|
||||
+ * Not MCM that indicates switch works as the remote standalone
|
||||
+ * integrated circuit so the GPIO pin would be used to complete
|
||||
+ * the reset, otherwise memory-mapped register accessing used
|
||||
+ * through syscon provides in the case of MCM.
|
||||
+ */
|
||||
+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
|
||||
+ if (priv->mcm) {
|
||||
+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
|
||||
+
|
||||
+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
|
||||
+ if (IS_ERR(priv->rstc)) {
|
||||
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
+ return PTR_ERR(priv->rstc);
|
||||
+ }
|
||||
+ } else {
|
||||
+ priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
|
||||
+ GPIOD_OUT_LOW);
|
||||
+ if (IS_ERR(priv->reset)) {
|
||||
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
+ return PTR_ERR(priv->reset);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (priv->id == ID_MT7530) {
|
||||
+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
|
||||
+ if (IS_ERR(priv->core_pwr))
|
||||
+ return PTR_ERR(priv->core_pwr);
|
||||
+
|
||||
+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
|
||||
+ if (IS_ERR(priv->io_pwr))
|
||||
+ return PTR_ERR(priv->io_pwr);
|
||||
+ }
|
||||
+
|
||||
+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!regmap_config)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ regmap_config->reg_bits = 16;
|
||||
+ regmap_config->val_bits = 32;
|
||||
+ regmap_config->reg_stride = 4;
|
||||
+ regmap_config->max_register = MT7530_CREV;
|
||||
+ regmap_config->disable_locking = true;
|
||||
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
|
||||
+ priv->bus, regmap_config);
|
||||
+ if (IS_ERR(priv->regmap))
|
||||
+ return PTR_ERR(priv->regmap);
|
||||
+
|
||||
+ if (priv->id == ID_MT7531) {
|
||||
+ ret = mt7531_create_sgmii(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return dsa_register_switch(priv->ds);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7530_remove(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
+ int ret = 0, i;
|
||||
+
|
||||
+ if (!priv)
|
||||
+ return;
|
||||
+
|
||||
+ ret = regulator_disable(priv->core_pwr);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(priv->dev,
|
||||
+ "Failed to disable core power: %d\n", ret);
|
||||
+
|
||||
+ ret = regulator_disable(priv->io_pwr);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(priv->dev, "Failed to disable io pwr: %d\n",
|
||||
+ ret);
|
||||
+
|
||||
+ mt7530_remove_common(priv);
|
||||
+
|
||||
+ for (i = 0; i < 2; ++i)
|
||||
+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
|
||||
+}
|
||||
+
|
||||
+static void mt7530_shutdown(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
+
|
||||
+ if (!priv)
|
||||
+ return;
|
||||
+
|
||||
+ dsa_switch_shutdown(priv->ds);
|
||||
+
|
||||
+ dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
+}
|
||||
+
|
||||
+static struct mdio_driver mt7530_mdio_driver = {
|
||||
+ .probe = mt7530_probe,
|
||||
+ .remove = mt7530_remove,
|
||||
+ .shutdown = mt7530_shutdown,
|
||||
+ .mdiodrv.driver = {
|
||||
+ .name = "mt7530-mdio",
|
||||
+ .of_match_table = mt7530_of_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+mdio_module_driver(mt7530_mdio_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
|
||||
+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/of_platform.h>
|
||||
-#include <linux/pcs/pcs-mtk-lynxi.h>
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
@@ -192,31 +191,6 @@ core_clear(struct mt7530_priv *priv, u32
|
||||
}
|
||||
|
||||
static int
|
||||
-mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
-{
|
||||
- struct mii_bus *bus = context;
|
||||
- u16 page, r, lo, hi;
|
||||
- int ret;
|
||||
-
|
||||
- page = (reg >> 6) & 0x3ff;
|
||||
- r = (reg >> 2) & 0xf;
|
||||
- lo = val & 0xffff;
|
||||
- hi = val >> 16;
|
||||
-
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- ret = bus->write(bus, 0x1f, r, lo);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- ret = bus->write(bus, 0x1f, 0x10, hi);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
int ret;
|
||||
@@ -230,29 +204,6 @@ mt7530_mii_write(struct mt7530_priv *pri
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int
|
||||
-mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
-{
|
||||
- struct mii_bus *bus = context;
|
||||
- u16 page, r, lo, hi;
|
||||
- int ret;
|
||||
-
|
||||
- page = (reg >> 6) & 0x3ff;
|
||||
- r = (reg >> 2) & 0xf;
|
||||
-
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- lo = bus->read(bus, 0x1f, r);
|
||||
- hi = bus->read(bus, 0x1f, 0x10);
|
||||
-
|
||||
- *val = (hi << 16) | (lo & 0xffff);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static u32
|
||||
mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
|
||||
{
|
||||
@@ -2957,72 +2908,6 @@ static const struct phylink_pcs_ops mt75
|
||||
.pcs_an_restart = mt7530_pcs_an_restart,
|
||||
};
|
||||
|
||||
-static void
|
||||
-mt7530_mdio_regmap_lock(void *mdio_lock)
|
||||
-{
|
||||
- mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mt7530_mdio_regmap_unlock(void *mdio_lock)
|
||||
-{
|
||||
- mutex_unlock(mdio_lock);
|
||||
-}
|
||||
-
|
||||
-static const struct regmap_bus mt7530_regmap_bus = {
|
||||
- .reg_write = mt7530_regmap_write,
|
||||
- .reg_read = mt7530_regmap_read,
|
||||
-};
|
||||
-
|
||||
-static int
|
||||
-mt7531_create_sgmii(struct mt7530_priv *priv)
|
||||
-{
|
||||
- struct regmap_config *mt7531_pcs_config[2];
|
||||
- struct phylink_pcs *pcs;
|
||||
- struct regmap *regmap;
|
||||
- int i, ret = 0;
|
||||
-
|
||||
- for (i = 0; i < 2; i++) {
|
||||
- mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||||
- sizeof(struct regmap_config),
|
||||
- GFP_KERNEL);
|
||||
- if (!mt7531_pcs_config[i]) {
|
||||
- ret = -ENOMEM;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- mt7531_pcs_config[i]->name = i ? "port6" : "port5";
|
||||
- mt7531_pcs_config[i]->reg_bits = 16;
|
||||
- mt7531_pcs_config[i]->val_bits = 32;
|
||||
- mt7531_pcs_config[i]->reg_stride = 4;
|
||||
- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
|
||||
- mt7531_pcs_config[i]->max_register = 0x17c;
|
||||
- mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
|
||||
- mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
|
||||
- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
-
|
||||
- regmap = devm_regmap_init(priv->dev,
|
||||
- &mt7530_regmap_bus, priv->bus,
|
||||
- mt7531_pcs_config[i]);
|
||||
- if (IS_ERR(regmap)) {
|
||||
- ret = PTR_ERR(regmap);
|
||||
- break;
|
||||
- }
|
||||
- pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
|
||||
- MT7531_PHYA_CTRL_SIGNAL3, 0);
|
||||
- if (!pcs) {
|
||||
- ret = -ENXIO;
|
||||
- break;
|
||||
- }
|
||||
- priv->ports[5 + i].sgmii_pcs = pcs;
|
||||
- }
|
||||
-
|
||||
- if (ret && i)
|
||||
- mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
mt753x_setup(struct dsa_switch *ds)
|
||||
{
|
||||
@@ -3081,7 +2966,7 @@ static int mt753x_set_mac_eee(struct dsa
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct dsa_switch_ops mt7530_switch_ops = {
|
||||
+const struct dsa_switch_ops mt7530_switch_ops = {
|
||||
.get_tag_protocol = mtk_get_tag_protocol,
|
||||
.setup = mt753x_setup,
|
||||
.get_strings = mt7530_get_strings,
|
||||
@@ -3115,8 +3000,9 @@ static const struct dsa_switch_ops mt753
|
||||
.get_mac_eee = mt753x_get_mac_eee,
|
||||
.set_mac_eee = mt753x_set_mac_eee,
|
||||
};
|
||||
+EXPORT_SYMBOL_GPL(mt7530_switch_ops);
|
||||
|
||||
-static const struct mt753x_info mt753x_table[] = {
|
||||
+const struct mt753x_info mt753x_table[] = {
|
||||
[ID_MT7621] = {
|
||||
.id = ID_MT7621,
|
||||
.pcs_ops = &mt7530_pcs_ops,
|
||||
@@ -3149,16 +3035,9 @@ static const struct mt753x_info mt753x_t
|
||||
.mac_port_config = mt7531_mac_config,
|
||||
},
|
||||
};
|
||||
+EXPORT_SYMBOL_GPL(mt753x_table);
|
||||
|
||||
-static const struct of_device_id mt7530_of_match[] = {
|
||||
- { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
|
||||
- { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
|
||||
- { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
|
||||
- { /* sentinel */ },
|
||||
-};
|
||||
-MODULE_DEVICE_TABLE(of, mt7530_of_match);
|
||||
-
|
||||
-static int
|
||||
+int
|
||||
mt7530_probe_common(struct mt7530_priv *priv)
|
||||
{
|
||||
struct device *dev = priv->dev;
|
||||
@@ -3195,88 +3074,9 @@ mt7530_probe_common(struct mt7530_priv *
|
||||
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(mt7530_probe_common);
|
||||
|
||||
-static int
|
||||
-mt7530_probe(struct mdio_device *mdiodev)
|
||||
-{
|
||||
- static struct regmap_config *regmap_config;
|
||||
- struct mt7530_priv *priv;
|
||||
- struct device_node *dn;
|
||||
- int ret;
|
||||
-
|
||||
- dn = mdiodev->dev.of_node;
|
||||
-
|
||||
- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- priv->bus = mdiodev->bus;
|
||||
- priv->dev = &mdiodev->dev;
|
||||
-
|
||||
- ret = mt7530_probe_common(priv);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- /* Use medatek,mcm property to distinguish hardware type that would
|
||||
- * cause a little bit differences on power-on sequence.
|
||||
- * Not MCM that indicates switch works as the remote standalone
|
||||
- * integrated circuit so the GPIO pin would be used to complete
|
||||
- * the reset, otherwise memory-mapped register accessing used
|
||||
- * through syscon provides in the case of MCM.
|
||||
- */
|
||||
- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
|
||||
- if (priv->mcm) {
|
||||
- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
|
||||
-
|
||||
- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
|
||||
- if (IS_ERR(priv->rstc)) {
|
||||
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
- return PTR_ERR(priv->rstc);
|
||||
- }
|
||||
- } else {
|
||||
- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
|
||||
- GPIOD_OUT_LOW);
|
||||
- if (IS_ERR(priv->reset)) {
|
||||
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
- return PTR_ERR(priv->reset);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (priv->id == ID_MT7530) {
|
||||
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
|
||||
- if (IS_ERR(priv->core_pwr))
|
||||
- return PTR_ERR(priv->core_pwr);
|
||||
-
|
||||
- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
|
||||
- if (IS_ERR(priv->io_pwr))
|
||||
- return PTR_ERR(priv->io_pwr);
|
||||
- }
|
||||
-
|
||||
- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
|
||||
- GFP_KERNEL);
|
||||
- if (!regmap_config)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- regmap_config->reg_bits = 16;
|
||||
- regmap_config->val_bits = 32;
|
||||
- regmap_config->reg_stride = 4;
|
||||
- regmap_config->max_register = MT7530_CREV;
|
||||
- regmap_config->disable_locking = true;
|
||||
- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
|
||||
- priv->bus, regmap_config);
|
||||
- if (IS_ERR(priv->regmap))
|
||||
- return PTR_ERR(priv->regmap);
|
||||
-
|
||||
- if (priv->id == ID_MT7531) {
|
||||
- ret = mt7531_create_sgmii(priv);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- return dsa_register_switch(priv->ds);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
+void
|
||||
mt7530_remove_common(struct mt7530_priv *priv)
|
||||
{
|
||||
if (priv->irq)
|
||||
@@ -3286,55 +3086,7 @@ mt7530_remove_common(struct mt7530_priv
|
||||
|
||||
mutex_destroy(&priv->reg_mutex);
|
||||
}
|
||||
-
|
||||
-static void
|
||||
-mt7530_remove(struct mdio_device *mdiodev)
|
||||
-{
|
||||
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
- int ret = 0, i;
|
||||
-
|
||||
- if (!priv)
|
||||
- return;
|
||||
-
|
||||
- ret = regulator_disable(priv->core_pwr);
|
||||
- if (ret < 0)
|
||||
- dev_err(priv->dev,
|
||||
- "Failed to disable core power: %d\n", ret);
|
||||
-
|
||||
- ret = regulator_disable(priv->io_pwr);
|
||||
- if (ret < 0)
|
||||
- dev_err(priv->dev, "Failed to disable io pwr: %d\n",
|
||||
- ret);
|
||||
-
|
||||
- mt7530_remove_common(priv);
|
||||
-
|
||||
- for (i = 0; i < 2; ++i)
|
||||
- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
|
||||
-}
|
||||
-
|
||||
-static void mt7530_shutdown(struct mdio_device *mdiodev)
|
||||
-{
|
||||
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
-
|
||||
- if (!priv)
|
||||
- return;
|
||||
-
|
||||
- dsa_switch_shutdown(priv->ds);
|
||||
-
|
||||
- dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
-}
|
||||
-
|
||||
-static struct mdio_driver mt7530_mdio_driver = {
|
||||
- .probe = mt7530_probe,
|
||||
- .remove = mt7530_remove,
|
||||
- .shutdown = mt7530_shutdown,
|
||||
- .mdiodrv.driver = {
|
||||
- .name = "mt7530",
|
||||
- .of_match_table = mt7530_of_match,
|
||||
- },
|
||||
-};
|
||||
-
|
||||
-mdio_module_driver(mt7530_mdio_driver);
|
||||
+EXPORT_SYMBOL_GPL(mt7530_remove_common);
|
||||
|
||||
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
|
||||
MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -807,4 +807,10 @@ static inline void INIT_MT7530_DUMMY_POL
|
||||
p->reg = reg;
|
||||
}
|
||||
|
||||
+int mt7530_probe_common(struct mt7530_priv *priv);
|
||||
+void mt7530_remove_common(struct mt7530_priv *priv);
|
||||
+
|
||||
+extern const struct dsa_switch_ops mt7530_switch_ops;
|
||||
+extern const struct mt753x_info mt753x_table[];
|
||||
+
|
||||
#endif /* __MT7530_H */
|
||||
@@ -0,0 +1,47 @@
|
||||
From a52cadbf76593f8fcb2f4f62cb006e3f2a22ad06 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:19:28 +0100
|
||||
Subject: [PATCH 11/13] net: dsa: mt7530: skip locking if MDIO bus isn't
|
||||
present
|
||||
|
||||
As MT7530 and MT7531 internally use 32-bit wide registers, each access
|
||||
to any register of the switch requires several operations on the MDIO
|
||||
bus. Hence if there is congruent access, e.g. due to PCS or PHY
|
||||
polling, this can mess up and interfere with another ongoing register
|
||||
access sequence.
|
||||
|
||||
However, the MDIO bus mutex is only relevant for MDIO-connected
|
||||
switches. Prepare switches which have there registers directly mapped
|
||||
into the SoCs register space via MMIO which do not require such
|
||||
locking. There we can simply use regmap's default locking mechanism.
|
||||
|
||||
Hence guard mutex operations to only be performed in case of MDIO
|
||||
connected switches.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -144,13 +144,15 @@ err:
|
||||
static void
|
||||
mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
{
|
||||
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ if (priv->bus)
|
||||
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
{
|
||||
- mutex_unlock(&priv->bus->mdio_lock);
|
||||
+ if (priv->bus)
|
||||
+ mutex_unlock(&priv->bus->mdio_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -0,0 +1,421 @@
|
||||
From b361015763fedea439f13b336b15ef7bdf1f7d4f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:19:40 +0100
|
||||
Subject: [PATCH 12/13] net: dsa: mt7530: introduce driver for MT7988 built-in
|
||||
switch
|
||||
|
||||
Add driver for the built-in Gigabit Ethernet switch which can be found
|
||||
in the MediaTek MT7988 SoC.
|
||||
|
||||
The switch shares most of its design with MT7530 and MT7531, but has
|
||||
it's registers mapped into the SoCs register space rather than being
|
||||
connected externally or internally via MDIO.
|
||||
|
||||
Introduce a new platform driver to support that.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
MAINTAINERS | 2 +
|
||||
drivers/net/dsa/Kconfig | 12 +++
|
||||
drivers/net/dsa/Makefile | 1 +
|
||||
drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++
|
||||
drivers/net/dsa/mt7530.c | 137 +++++++++++++++++++++++++++++++++-
|
||||
drivers/net/dsa/mt7530.h | 12 +--
|
||||
6 files changed, 255 insertions(+), 10 deletions(-)
|
||||
create mode 100644 drivers/net/dsa/mt7530-mmio.c
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -13058,9 +13058,11 @@ MEDIATEK SWITCH DRIVER
|
||||
M: Sean Wang <sean.wang@mediatek.com>
|
||||
M: Landen Chao <Landen.Chao@mediatek.com>
|
||||
M: DENG Qingfang <dqfext@gmail.com>
|
||||
+M: Daniel Golle <daniel@makrotopia.org>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/dsa/mt7530-mdio.c
|
||||
+F: drivers/net/dsa/mt7530-mmio.c
|
||||
F: drivers/net/dsa/mt7530.*
|
||||
F: net/dsa/tag_mtk.c
|
||||
|
||||
--- a/drivers/net/dsa/Kconfig
|
||||
+++ b/drivers/net/dsa/Kconfig
|
||||
@@ -38,6 +38,7 @@ config NET_DSA_MT7530
|
||||
select NET_DSA_TAG_MTK
|
||||
select MEDIATEK_GE_PHY
|
||||
imply NET_DSA_MT7530_MDIO
|
||||
+ imply NET_DSA_MT7530_MMIO
|
||||
help
|
||||
This enables support for the MediaTek MT7530 and MT7531 Ethernet
|
||||
switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
|
||||
@@ -54,6 +55,17 @@ config NET_DSA_MT7530_MDIO
|
||||
module MT7530 which can be found in the MT7621AT, MT7621DAT,
|
||||
MT7621ST and MT7623AI SoCs.
|
||||
|
||||
+config NET_DSA_MT7530_MMIO
|
||||
+ tristate "MediaTek MT7530 MMIO interface driver"
|
||||
+ depends on NET_DSA_MT7530
|
||||
+ depends on HAS_IOMEM
|
||||
+ help
|
||||
+ This enables support for the built-in Ethernet switch found
|
||||
+ in the MediaTek MT7988 SoC.
|
||||
+ The switch is a similar design as MT7531, but the switch registers
|
||||
+ are directly mapped into the SoCs register space rather than being
|
||||
+ accessible via MDIO.
|
||||
+
|
||||
config NET_DSA_MV88E6060
|
||||
tristate "Marvell 88E6060 ethernet switch chip support"
|
||||
select NET_DSA_TAG_TRAILER
|
||||
--- a/drivers/net/dsa/Makefile
|
||||
+++ b/drivers/net/dsa/Makefile
|
||||
@@ -8,6 +8,7 @@ endif
|
||||
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
|
||||
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
|
||||
obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
|
||||
+obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o
|
||||
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
|
||||
obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
|
||||
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mt7530-mmio.c
|
||||
@@ -0,0 +1,101 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <net/dsa.h>
|
||||
+
|
||||
+#include "mt7530.h"
|
||||
+
|
||||
+static const struct of_device_id mt7988_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt7988_of_match);
|
||||
+
|
||||
+static int
|
||||
+mt7988_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ static struct regmap_config *sw_regmap_config;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ void __iomem *base_addr;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv->bus = NULL;
|
||||
+ priv->dev = &pdev->dev;
|
||||
+
|
||||
+ ret = mt7530_probe_common(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(priv->rstc)) {
|
||||
+ dev_err(&pdev->dev, "Couldn't get our reset line\n");
|
||||
+ return PTR_ERR(priv->rstc);
|
||||
+ }
|
||||
+
|
||||
+ base_addr = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(base_addr)) {
|
||||
+ dev_err(&pdev->dev, "cannot request I/O memory space\n");
|
||||
+ return -ENXIO;
|
||||
+ }
|
||||
+
|
||||
+ sw_regmap_config = devm_kzalloc(&pdev->dev, sizeof(*sw_regmap_config), GFP_KERNEL);
|
||||
+ if (!sw_regmap_config)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ sw_regmap_config->name = "switch";
|
||||
+ sw_regmap_config->reg_bits = 16;
|
||||
+ sw_regmap_config->val_bits = 32;
|
||||
+ sw_regmap_config->reg_stride = 4;
|
||||
+ sw_regmap_config->max_register = MT7530_CREV;
|
||||
+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base_addr, sw_regmap_config);
|
||||
+ if (IS_ERR(priv->regmap))
|
||||
+ return PTR_ERR(priv->regmap);
|
||||
+
|
||||
+ return dsa_register_switch(priv->ds);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mt7988_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (priv)
|
||||
+ mt7530_remove_common(priv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mt7988_shutdown(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (!priv)
|
||||
+ return;
|
||||
+
|
||||
+ dsa_switch_shutdown(priv->ds);
|
||||
+
|
||||
+ dev_set_drvdata(&pdev->dev, NULL);
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver mt7988_platform_driver = {
|
||||
+ .probe = mt7988_probe,
|
||||
+ .remove = mt7988_remove,
|
||||
+ .shutdown = mt7988_shutdown,
|
||||
+ .driver = {
|
||||
+ .name = "mt7530-mmio",
|
||||
+ .of_match_table = mt7988_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(mt7988_platform_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
|
||||
+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MMIO)");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1989,6 +1989,47 @@ static const struct irq_domain_ops mt753
|
||||
};
|
||||
|
||||
static void
|
||||
+mt7988_irq_mask(struct irq_data *d)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
|
||||
+
|
||||
+ priv->irq_enable &= ~BIT(d->hwirq);
|
||||
+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7988_irq_unmask(struct irq_data *d)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
|
||||
+
|
||||
+ priv->irq_enable |= BIT(d->hwirq);
|
||||
+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip mt7988_irq_chip = {
|
||||
+ .name = KBUILD_MODNAME,
|
||||
+ .irq_mask = mt7988_irq_mask,
|
||||
+ .irq_unmask = mt7988_irq_unmask,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mt7988_irq_map(struct irq_domain *domain, unsigned int irq,
|
||||
+ irq_hw_number_t hwirq)
|
||||
+{
|
||||
+ irq_set_chip_data(irq, domain->host_data);
|
||||
+ irq_set_chip_and_handler(irq, &mt7988_irq_chip, handle_simple_irq);
|
||||
+ irq_set_nested_thread(irq, true);
|
||||
+ irq_set_noprobe(irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct irq_domain_ops mt7988_irq_domain_ops = {
|
||||
+ .map = mt7988_irq_map,
|
||||
+ .xlate = irq_domain_xlate_onecell,
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
mt7530_setup_mdio_irq(struct mt7530_priv *priv)
|
||||
{
|
||||
struct dsa_switch *ds = priv->ds;
|
||||
@@ -2022,8 +2063,15 @@ mt7530_setup_irq(struct mt7530_priv *pri
|
||||
return priv->irq ? : -EINVAL;
|
||||
}
|
||||
|
||||
- priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
|
||||
- &mt7530_irq_domain_ops, priv);
|
||||
+ if (priv->id == ID_MT7988)
|
||||
+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
|
||||
+ &mt7988_irq_domain_ops,
|
||||
+ priv);
|
||||
+ else
|
||||
+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
|
||||
+ &mt7530_irq_domain_ops,
|
||||
+ priv);
|
||||
+
|
||||
if (!priv->irq_domain) {
|
||||
dev_err(dev, "failed to create IRQ domain\n");
|
||||
return -ENOMEM;
|
||||
@@ -2520,6 +2568,25 @@ static void mt7531_mac_port_get_caps(str
|
||||
}
|
||||
}
|
||||
|
||||
+static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
|
||||
+ struct phylink_config *config)
|
||||
+{
|
||||
+ phy_interface_zero(config->supported_interfaces);
|
||||
+
|
||||
+ switch (port) {
|
||||
+ case 0 ... 4: /* Internal phy */
|
||||
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
+ config->supported_interfaces);
|
||||
+ break;
|
||||
+
|
||||
+ case 6:
|
||||
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
+ config->supported_interfaces);
|
||||
+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
+ MAC_10000FD;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int
|
||||
mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
|
||||
{
|
||||
@@ -2596,6 +2663,17 @@ static bool mt753x_is_mac_port(u32 port)
|
||||
}
|
||||
|
||||
static int
|
||||
+mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ if (dsa_is_cpu_port(ds, port) &&
|
||||
+ interface == PHY_INTERFACE_MODE_INTERNAL)
|
||||
+ return 0;
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
@@ -2665,7 +2743,8 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
|
||||
switch (port) {
|
||||
case 0 ... 4: /* Internal phy */
|
||||
- if (state->interface != PHY_INTERFACE_MODE_GMII)
|
||||
+ if (state->interface != PHY_INTERFACE_MODE_GMII &&
|
||||
+ state->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
goto unsupported;
|
||||
break;
|
||||
case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
|
||||
@@ -2743,7 +2822,8 @@ static void mt753x_phylink_mac_link_up(s
|
||||
/* MT753x MAC works in 1G full duplex mode for all up-clocked
|
||||
* variants.
|
||||
*/
|
||||
- if (interface == PHY_INTERFACE_MODE_TRGMII ||
|
||||
+ if (interface == PHY_INTERFACE_MODE_INTERNAL ||
|
||||
+ interface == PHY_INTERFACE_MODE_TRGMII ||
|
||||
(phy_interface_mode_is_8023z(interface))) {
|
||||
speed = SPEED_1000;
|
||||
duplex = DUPLEX_FULL;
|
||||
@@ -2823,6 +2903,21 @@ mt7531_cpu_port_config(struct dsa_switch
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+mt7988_cpu_port_config(struct dsa_switch *ds, int port)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
+
|
||||
+ mt7530_write(priv, MT7530_PMCR_P(port),
|
||||
+ PMCR_CPU_PORT_SETTING(priv->id));
|
||||
+
|
||||
+ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
|
||||
+ PHY_INTERFACE_MODE_INTERNAL, NULL,
|
||||
+ SPEED_10000, DUPLEX_FULL, true, true);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
@@ -2968,6 +3063,27 @@ static int mt753x_set_mac_eee(struct dsa
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mt7988_setup(struct dsa_switch *ds)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
+
|
||||
+ /* Reset the switch */
|
||||
+ reset_control_assert(priv->rstc);
|
||||
+ usleep_range(20, 50);
|
||||
+ reset_control_deassert(priv->rstc);
|
||||
+ usleep_range(20, 50);
|
||||
+
|
||||
+ /* Reset the switch PHYs */
|
||||
+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
|
||||
+
|
||||
+ return mt7531_setup_common(ds);
|
||||
+}
|
||||
+
|
||||
const struct dsa_switch_ops mt7530_switch_ops = {
|
||||
.get_tag_protocol = mtk_get_tag_protocol,
|
||||
.setup = mt753x_setup,
|
||||
@@ -3036,6 +3152,17 @@ const struct mt753x_info mt753x_table[]
|
||||
.mac_port_get_caps = mt7531_mac_port_get_caps,
|
||||
.mac_port_config = mt7531_mac_config,
|
||||
},
|
||||
+ [ID_MT7988] = {
|
||||
+ .id = ID_MT7988,
|
||||
+ .pcs_ops = &mt7530_pcs_ops,
|
||||
+ .sw_setup = mt7988_setup,
|
||||
+ .phy_read = mt7531_ind_phy_read,
|
||||
+ .phy_write = mt7531_ind_phy_write,
|
||||
+ .pad_setup = mt7988_pad_setup,
|
||||
+ .cpu_port_config = mt7988_cpu_port_config,
|
||||
+ .mac_port_get_caps = mt7988_mac_port_get_caps,
|
||||
+ .mac_port_config = mt7988_mac_config,
|
||||
+ },
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mt753x_table);
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -18,6 +18,7 @@ enum mt753x_id {
|
||||
ID_MT7530 = 0,
|
||||
ID_MT7621 = 1,
|
||||
ID_MT7531 = 2,
|
||||
+ ID_MT7988 = 3,
|
||||
};
|
||||
|
||||
#define NUM_TRGMII_CTRL 5
|
||||
@@ -54,11 +55,11 @@ enum mt753x_id {
|
||||
#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
|
||||
#define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
|
||||
|
||||
-#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \
|
||||
+#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
MT7531_CFC : MT7530_MFC)
|
||||
-#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \
|
||||
+#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
MT7531_MIRROR_EN : MIRROR_EN)
|
||||
-#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \
|
||||
+#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
MT7531_MIRROR_MASK : MIRROR_MASK)
|
||||
|
||||
/* Registers for BPDU and PAE frame control*/
|
||||
@@ -295,9 +296,8 @@ enum mt7530_vlan_port_acc_frm {
|
||||
MT7531_FORCE_DPX | \
|
||||
MT7531_FORCE_RX_FC | \
|
||||
MT7531_FORCE_TX_FC)
|
||||
-#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \
|
||||
- MT7531_FORCE_MODE : \
|
||||
- PMCR_FORCE_MODE)
|
||||
+#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
+ MT7531_FORCE_MODE : PMCR_FORCE_MODE)
|
||||
#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
|
||||
PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
|
||||
PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
|
||||
@@ -0,0 +1,118 @@
|
||||
From eb1dd407b4be7ca38166a38c56c8edf52c6a399f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sun, 16 Apr 2023 13:08:14 +0100
|
||||
Subject: [PATCH 13/13] net: dsa: mt7530: fix support for MT7531BE
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There are two variants of the MT7531 switch IC which got different
|
||||
features (and pins) regarding port 5:
|
||||
* MT7531AE: SGMII/1000Base-X/2500Base-X SerDes PCS
|
||||
* MT7531BE: RGMII
|
||||
|
||||
Moving the creation of the SerDes PCS from mt753x_setup to mt7530_probe
|
||||
with commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation
|
||||
to mt7530_probe function") works fine for MT7531AE which got two
|
||||
instances of mtk-pcs-lynxi, however, MT7531BE requires mt7531_pll_setup
|
||||
to setup clocks before the single PCS on port 6 (usually used as CPU
|
||||
port) starts to work and hence the PCS creation failed on MT7531BE.
|
||||
|
||||
Fix this by introducing a pointer to mt7531_create_sgmii function in
|
||||
struct mt7530_priv and call it again at the end of mt753x_setup like it
|
||||
was before commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS
|
||||
creation to mt7530_probe function").
|
||||
|
||||
Fixes: 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation to mt7530_probe function")
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/ZDvlLhhqheobUvOK@makrotopia.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530-mdio.c | 16 ++++++++--------
|
||||
drivers/net/dsa/mt7530.c | 6 ++++++
|
||||
drivers/net/dsa/mt7530.h | 4 ++--
|
||||
3 files changed, 16 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530-mdio.c
|
||||
+++ b/drivers/net/dsa/mt7530-mdio.c
|
||||
@@ -81,14 +81,17 @@ static const struct regmap_bus mt7530_re
|
||||
};
|
||||
|
||||
static int
|
||||
-mt7531_create_sgmii(struct mt7530_priv *priv)
|
||||
+mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii)
|
||||
{
|
||||
- struct regmap_config *mt7531_pcs_config[2];
|
||||
+ struct regmap_config *mt7531_pcs_config[2] = {};
|
||||
struct phylink_pcs *pcs;
|
||||
struct regmap *regmap;
|
||||
int i, ret = 0;
|
||||
|
||||
- for (i = 0; i < 2; i++) {
|
||||
+ /* MT7531AE has two SGMII units for port 5 and port 6
|
||||
+ * MT7531BE has only one SGMII unit for port 6
|
||||
+ */
|
||||
+ for (i = dual_sgmii ? 0 : 1; i < 2; i++) {
|
||||
mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||||
sizeof(struct regmap_config),
|
||||
GFP_KERNEL);
|
||||
@@ -208,11 +211,8 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
- if (priv->id == ID_MT7531) {
|
||||
- ret = mt7531_create_sgmii(priv);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
+ if (priv->id == ID_MT7531)
|
||||
+ priv->create_sgmii = mt7531_create_sgmii;
|
||||
|
||||
return dsa_register_switch(priv->ds);
|
||||
}
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3030,6 +3030,12 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
+ if (priv->create_sgmii) {
|
||||
+ ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv));
|
||||
+ if (ret && priv->irq)
|
||||
+ mt7530_free_irq(priv);
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -741,10 +741,10 @@ struct mt753x_info {
|
||||
* registers
|
||||
* @p6_interface Holding the current port 6 interface
|
||||
* @p5_intf_sel: Holding the current port 5 interface select
|
||||
- *
|
||||
* @irq: IRQ number of the switch
|
||||
* @irq_domain: IRQ domain of the switch irq_chip
|
||||
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN
|
||||
+ * @create_sgmii: Pointer to function creating SGMII PCS instance(s)
|
||||
*/
|
||||
struct mt7530_priv {
|
||||
struct device *dev;
|
||||
@@ -763,7 +763,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*/
|
||||
@@ -771,6 +770,7 @@ struct mt7530_priv {
|
||||
int irq;
|
||||
struct irq_domain *irq_domain;
|
||||
u32 irq_enable;
|
||||
+ int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
|
||||
};
|
||||
|
||||
struct mt7530_hw_vlan_entry {
|
||||
@@ -21,7 +21,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -13959,6 +13959,7 @@ F: include/uapi/linux/meye.h
|
||||
@@ -13962,6 +13962,7 @@ F: include/uapi/linux/meye.h
|
||||
|
||||
MOTORCOMM PHY DRIVER
|
||||
M: Peter Geis <pgwipeout@gmail.com>
|
||||
|
||||
@@ -5246,6 +5246,8 @@ CONFIG_RXKAD=y
|
||||
# CONFIG_SATA_AHCI is not set
|
||||
# CONFIG_SATA_AHCI_PLATFORM is not set
|
||||
# CONFIG_SATA_DWC is not set
|
||||
# CONFIG_SATA_DWC_DEBUG is not set
|
||||
# CONFIG_SATA_DWC_OLD_DMA is not set
|
||||
# CONFIG_SATA_FSL is not set
|
||||
# CONFIG_SATA_HIGHBANK is not set
|
||||
# CONFIG_SATA_HOST is not set
|
||||
|
||||
@@ -150,6 +150,7 @@ CONFIG_AF_UNIX_OOB=y
|
||||
# CONFIG_AHCI_BRCM is not set
|
||||
# CONFIG_AHCI_CEVA is not set
|
||||
# CONFIG_AHCI_DWC is not set
|
||||
# CONFIG_SATA_DWC_OLD_DMA is not set
|
||||
# CONFIG_AHCI_IMX is not set
|
||||
# CONFIG_AHCI_MVEBU is not set
|
||||
# CONFIG_AHCI_QORIQ is not set
|
||||
@@ -1712,6 +1713,7 @@ CONFIG_DQL=y
|
||||
# CONFIG_DRM_RCAR_LVDS is not set
|
||||
# CONFIG_DRM_RCAR_USE_LVDS is not set
|
||||
# CONFIG_DRM_RCAR_USE_MIPI_DSI is not set
|
||||
# CONFIG_DRM_ROCKCHIP is not set
|
||||
# CONFIG_DRM_SII902X is not set
|
||||
# CONFIG_DRM_SII9234 is not set
|
||||
# CONFIG_DRM_SIL_SII8620 is not set
|
||||
@@ -2188,7 +2190,6 @@ CONFIG_FSNOTIFY=y
|
||||
# CONFIG_FTRACE_STARTUP_TEST is not set
|
||||
# CONFIG_FTR_FIXUP_SELFTEST is not set
|
||||
# CONFIG_FTWDT010_WATCHDOG is not set
|
||||
# CONFIG_FUNCTION_ERROR_INJECTION is not set
|
||||
# CONFIG_FUJITSU_ERRATUM_010001 is not set
|
||||
# CONFIG_FUJITSU_ES is not set
|
||||
# CONFIG_FUJITSU_LAPTOP is not set
|
||||
@@ -6312,6 +6313,8 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
|
||||
# CONFIG_SND_SOC_PCM512x_SPI is not set
|
||||
# CONFIG_SND_SOC_QCOM is not set
|
||||
# CONFIG_SND_SOC_RK3328 is not set
|
||||
# CONFIG_SND_SOC_RK817 is not set
|
||||
# CONFIG_SND_SOC_ROCKCHIP is not set
|
||||
# CONFIG_SND_SOC_RT5616 is not set
|
||||
# CONFIG_SND_SOC_RT5631 is not set
|
||||
# CONFIG_SND_SOC_RT5640 is not set
|
||||
@@ -6990,6 +6993,7 @@ CONFIG_TTY=y
|
||||
# CONFIG_TWL6040_CORE is not set
|
||||
# CONFIG_TXGBE is not set
|
||||
# CONFIG_TYPEC is not set
|
||||
# CONFIG_TYPEC_DP_ALTMODE is not set
|
||||
# CONFIG_TYPEC_TCPM is not set
|
||||
# CONFIG_TYPEC_UCSI is not set
|
||||
# CONFIG_TYPHOON is not set
|
||||
|
||||
@@ -1054,6 +1054,9 @@ static struct genl_family switch_fam = {
|
||||
.module = THIS_MODULE,
|
||||
.ops = swconfig_ops,
|
||||
.n_ops = ARRAY_SIZE(swconfig_ops),
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(6,0,0)
|
||||
.resv_start_op = SWITCH_CMD_SET_VLAN + 1,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
@@ -15,7 +15,7 @@ Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2196,6 +2196,10 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
@@ -2236,6 +2236,10 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
From 663fa1b7e0cb2c929008482014a70c6625caad75 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:55:13 +0000
|
||||
Subject: [PATCH 1/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V1 capability
|
||||
bit
|
||||
|
||||
Introduce MTK_NETSYS_V1 bit in the device capabilities for
|
||||
MT7621/MT7622/MT7623/MT7628/MT7629 SoCs.
|
||||
Use !MTK_NETSYS_V1 instead of MTK_NETSYS_V2 in the driver codebase.
|
||||
This is a preliminary patch to introduce support for MT7988 SoC.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++-------
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 45 ++++++++++++---------
|
||||
2 files changed, 41 insertions(+), 34 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -640,7 +640,7 @@ static void mtk_set_queue_speed(struct m
|
||||
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
|
||||
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
|
||||
|
||||
if (IS_ENABLED(CONFIG_SOC_MT7621)) {
|
||||
@@ -1018,7 +1018,7 @@ static bool mtk_rx_get_desc(struct mtk_e
|
||||
rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
|
||||
rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
|
||||
rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
|
||||
rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
|
||||
}
|
||||
@@ -1076,7 +1076,7 @@ static int mtk_init_fq_dma(struct mtk_et
|
||||
|
||||
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
|
||||
txd->txd4 = 0;
|
||||
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
|
||||
txd->txd5 = 0;
|
||||
txd->txd6 = 0;
|
||||
txd->txd7 = 0;
|
||||
@@ -1267,7 +1267,7 @@ static void mtk_tx_set_dma_desc(struct n
|
||||
struct mtk_mac *mac = netdev_priv(dev);
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
mtk_tx_set_dma_desc_v2(dev, txd, info);
|
||||
else
|
||||
mtk_tx_set_dma_desc_v1(dev, txd, info);
|
||||
@@ -1950,7 +1950,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
break;
|
||||
|
||||
/* find out which mac the packet come from. values start at 1 */
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
|
||||
else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
|
||||
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
|
||||
@@ -2046,7 +2046,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
skb->dev = netdev;
|
||||
bytes += skb->len;
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
|
||||
hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
|
||||
if (hash != MTK_RXD5_FOE_ENTRY)
|
||||
@@ -2071,7 +2071,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
/* When using VLAN untagging in combination with DSA, the
|
||||
* hardware treats the MTK special tag as a VLAN and untags it.
|
||||
*/
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1) &&
|
||||
(trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
|
||||
unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
|
||||
|
||||
@@ -2382,7 +2382,7 @@ static int mtk_tx_alloc(struct mtk_eth *
|
||||
txd->txd2 = next_ptr;
|
||||
txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
|
||||
txd->txd4 = 0;
|
||||
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
|
||||
txd->txd5 = 0;
|
||||
txd->txd6 = 0;
|
||||
txd->txd7 = 0;
|
||||
@@ -2435,7 +2435,7 @@ static int mtk_tx_alloc(struct mtk_eth *
|
||||
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
|
||||
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
|
||||
mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
|
||||
ofs += MTK_QTX_OFFSET;
|
||||
@@ -2571,7 +2571,7 @@ static int mtk_rx_alloc(struct mtk_eth *
|
||||
|
||||
rxd->rxd3 = 0;
|
||||
rxd->rxd4 = 0;
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
rxd->rxd5 = 0;
|
||||
rxd->rxd6 = 0;
|
||||
rxd->rxd7 = 0;
|
||||
@@ -3119,7 +3119,7 @@ static int mtk_start_dma(struct mtk_eth
|
||||
MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
|
||||
MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
|
||||
MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
|
||||
MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
|
||||
@@ -3529,7 +3529,7 @@ static void mtk_hw_reset(struct mtk_eth
|
||||
{
|
||||
u32 val;
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
|
||||
val = RSTCTRL_PPE0_V2;
|
||||
} else {
|
||||
@@ -3541,7 +3541,7 @@ static void mtk_hw_reset(struct mtk_eth
|
||||
|
||||
ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
|
||||
0x3ffffff);
|
||||
}
|
||||
@@ -3737,7 +3737,7 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
else
|
||||
mtk_hw_reset(eth);
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
/* Set FE to PDMAv2 if necessary */
|
||||
val = mtk_r32(eth, MTK_FE_GLO_MISC);
|
||||
mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
|
||||
@@ -3774,7 +3774,7 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
*/
|
||||
val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
|
||||
mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
|
||||
mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -819,6 +819,7 @@ enum mkt_eth_capabilities {
|
||||
MTK_SHARED_INT_BIT,
|
||||
MTK_TRGMII_MT7621_CLK_BIT,
|
||||
MTK_QDMA_BIT,
|
||||
+ MTK_NETSYS_V1_BIT,
|
||||
MTK_NETSYS_V2_BIT,
|
||||
MTK_SOC_MT7628_BIT,
|
||||
MTK_RSTCTRL_PPE1_BIT,
|
||||
@@ -854,6 +855,7 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
|
||||
#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
|
||||
#define MTK_QDMA BIT(MTK_QDMA_BIT)
|
||||
+#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
|
||||
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
|
||||
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
|
||||
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
|
||||
@@ -916,25 +918,30 @@ enum mkt_eth_capabilities {
|
||||
|
||||
#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x))
|
||||
|
||||
-#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
|
||||
- MTK_GMAC2_RGMII | MTK_SHARED_INT | \
|
||||
- MTK_TRGMII_MT7621_CLK | MTK_QDMA)
|
||||
-
|
||||
-#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | MTK_GMAC2_RGMII | \
|
||||
- MTK_GMAC2_SGMII | MTK_GDM1_ESW | \
|
||||
- MTK_MUX_GDM1_TO_GMAC1_ESW | \
|
||||
- MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_QDMA)
|
||||
-
|
||||
-#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | MTK_GMAC2_RGMII | \
|
||||
- MTK_QDMA)
|
||||
-
|
||||
-#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628)
|
||||
-
|
||||
-#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
|
||||
- MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW | \
|
||||
- MTK_MUX_GMAC2_GMAC0_TO_GEPHY | \
|
||||
- MTK_MUX_U3_GMAC2_TO_QPHY | \
|
||||
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
|
||||
+#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
|
||||
+ MTK_GMAC2_RGMII | MTK_SHARED_INT | \
|
||||
+ MTK_TRGMII_MT7621_CLK | MTK_QDMA | \
|
||||
+ MTK_NETSYS_V1)
|
||||
+
|
||||
+#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | \
|
||||
+ MTK_GMAC2_RGMII | MTK_GMAC2_SGMII | \
|
||||
+ MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW |\
|
||||
+ MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | \
|
||||
+ MTK_QDMA | MTK_NETSYS_V1)
|
||||
+
|
||||
+#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
|
||||
+ MTK_GMAC2_RGMII | MTK_QDMA | \
|
||||
+ MTK_NETSYS_V1)
|
||||
+
|
||||
+#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628 | \
|
||||
+ MTK_NETSYS_V1)
|
||||
+
|
||||
+#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
|
||||
+ MTK_GMAC2_GEPHY | MTK_GDM1_ESW | \
|
||||
+ MTK_MUX_GMAC2_GMAC0_TO_GEPHY | MTK_QDMA | \
|
||||
+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_NETSYS_V1 |\
|
||||
+ MTK_MUX_GDM1_TO_GMAC1_ESW | \
|
||||
+ MTK_MUX_GMAC12_TO_GEPHY_SGMII)
|
||||
|
||||
#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
|
||||
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
|
||||
@@ -0,0 +1,181 @@
|
||||
From 5af2b2dc4d6ba0ff7696e79f18e5b2bf862194eb Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:55:24 +0000
|
||||
Subject: [PATCH 2/7] net: ethernet: mtk_eth_soc: move MAX_DEVS in mtk_soc_data
|
||||
|
||||
This is a preliminary patch to add MT7988 SoC support since it runs 3
|
||||
macs instead of 2.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +++++++++++++++++++--
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 +++----
|
||||
2 files changed, 36 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -4043,7 +4043,10 @@ static void mtk_sgmii_destroy(struct mtk
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAX_DEVS; i++)
|
||||
+ if (!eth->sgmii_pcs)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++)
|
||||
mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
|
||||
}
|
||||
|
||||
@@ -4486,7 +4489,12 @@ static int mtk_sgmii_init(struct mtk_eth
|
||||
u32 flags;
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||
+ eth->sgmii_pcs = devm_kzalloc(eth->dev,
|
||||
+ sizeof(*eth->sgmii_pcs) *
|
||||
+ eth->soc->num_devs,
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
|
||||
if (!np)
|
||||
break;
|
||||
@@ -4531,6 +4539,18 @@ static int mtk_probe(struct platform_dev
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
|
||||
eth->ip_align = NET_IP_ALIGN;
|
||||
|
||||
+ eth->netdev = devm_kzalloc(eth->dev,
|
||||
+ sizeof(*eth->netdev) * eth->soc->num_devs,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!eth->netdev)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ eth->mac = devm_kzalloc(eth->dev,
|
||||
+ sizeof(*eth->mac) * eth->soc->num_devs,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!eth->mac)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
spin_lock_init(ð->page_lock);
|
||||
spin_lock_init(ð->tx_irq_lock);
|
||||
spin_lock_init(ð->rx_irq_lock);
|
||||
@@ -4716,7 +4736,7 @@ static int mtk_probe(struct platform_dev
|
||||
goto err_deinit_ppe;
|
||||
}
|
||||
|
||||
- for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
|
||||
@@ -4792,6 +4812,7 @@ static const struct mtk_soc_data mt2701_
|
||||
.hw_features = MTK_HW_FEATURES,
|
||||
.required_clks = MT7623_CLKS_BITMAP,
|
||||
.required_pctl = true,
|
||||
+ .num_devs = 2,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
.rxd_size = sizeof(struct mtk_rx_dma),
|
||||
@@ -4810,6 +4831,7 @@ static const struct mtk_soc_data mt7621_
|
||||
.required_pctl = false,
|
||||
.offload_version = 1,
|
||||
.hash_offset = 2,
|
||||
+ .num_devs = 2,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
@@ -4831,6 +4853,7 @@ static const struct mtk_soc_data mt7622_
|
||||
.offload_version = 2,
|
||||
.hash_offset = 2,
|
||||
.has_accounting = true,
|
||||
+ .num_devs = 2,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
@@ -4850,6 +4873,7 @@ static const struct mtk_soc_data mt7623_
|
||||
.required_pctl = true,
|
||||
.offload_version = 1,
|
||||
.hash_offset = 2,
|
||||
+ .num_devs = 2,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
@@ -4869,6 +4893,7 @@ static const struct mtk_soc_data mt7629_
|
||||
.required_clks = MT7629_CLKS_BITMAP,
|
||||
.required_pctl = false,
|
||||
.has_accounting = true,
|
||||
+ .num_devs = 2,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
.rxd_size = sizeof(struct mtk_rx_dma),
|
||||
@@ -4890,6 +4915,7 @@ static const struct mtk_soc_data mt7981_
|
||||
.hash_offset = 4,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry),
|
||||
.has_accounting = true,
|
||||
+ .num_devs = 2,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma_v2),
|
||||
.rxd_size = sizeof(struct mtk_rx_dma_v2),
|
||||
@@ -4908,6 +4934,7 @@ static const struct mtk_soc_data mt7986_
|
||||
.required_clks = MT7986_CLKS_BITMAP,
|
||||
.required_pctl = false,
|
||||
.hash_offset = 4,
|
||||
+ .num_devs = 2,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry),
|
||||
.has_accounting = true,
|
||||
.txrx = {
|
||||
@@ -4926,6 +4953,7 @@ static const struct mtk_soc_data rt5350_
|
||||
.hw_features = MTK_HW_FEATURES_MT7628,
|
||||
.required_clks = MT7628_CLKS_BITMAP,
|
||||
.required_pctl = false,
|
||||
+ .num_devs = 2,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
.rxd_size = sizeof(struct mtk_rx_dma),
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1021,6 +1021,7 @@ struct mtk_reg_map {
|
||||
* @required_pctl A bool value to show whether the SoC requires
|
||||
* the extra setup for those pins used by GMAC.
|
||||
* @hash_offset Flow table hash offset.
|
||||
+ * @num_devs SoC number of macs.
|
||||
* @foe_entry_size Foe table entry size.
|
||||
* @has_accounting Bool indicating support for accounting of
|
||||
* offloaded flows.
|
||||
@@ -1039,6 +1040,7 @@ struct mtk_soc_data {
|
||||
bool required_pctl;
|
||||
u8 offload_version;
|
||||
u8 hash_offset;
|
||||
+ u8 num_devs;
|
||||
u16 foe_entry_size;
|
||||
netdev_features_t hw_features;
|
||||
bool has_accounting;
|
||||
@@ -1054,9 +1056,6 @@ struct mtk_soc_data {
|
||||
|
||||
#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
|
||||
|
||||
-/* currently no SoC has more than 2 macs */
|
||||
-#define MTK_MAX_DEVS 2
|
||||
-
|
||||
/* struct mtk_eth - This is the main datasructure for holding the state
|
||||
* of the driver
|
||||
* @dev: The device pointer
|
||||
@@ -1111,14 +1110,14 @@ struct mtk_eth {
|
||||
spinlock_t tx_irq_lock;
|
||||
spinlock_t rx_irq_lock;
|
||||
struct net_device dummy_dev;
|
||||
- struct net_device *netdev[MTK_MAX_DEVS];
|
||||
- struct mtk_mac *mac[MTK_MAX_DEVS];
|
||||
+ struct net_device **netdev;
|
||||
+ struct mtk_mac **mac;
|
||||
int irq[3];
|
||||
u32 msg_enable;
|
||||
unsigned long sysclk;
|
||||
struct regmap *ethsys;
|
||||
struct regmap *infra;
|
||||
- struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
|
||||
+ struct phylink_pcs **sgmii_pcs;
|
||||
struct regmap *pctl;
|
||||
bool hwlro;
|
||||
refcount_t dma_refcnt;
|
||||
@@ -0,0 +1,153 @@
|
||||
From 4e35e80750b33727e606be9e7ce447bde2e0deb7 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:55:35 +0000
|
||||
Subject: [PATCH 3/7] net: ethernet: mtk_eth_soc: rely on num_devs and remove
|
||||
MTK_MAC_COUNT
|
||||
|
||||
Get rid of MTK_MAC_COUNT since it is a duplicated of eth->soc->num_devs.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 ++++++++++-----------
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
|
||||
2 files changed, 15 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -944,7 +944,7 @@ static void mtk_stats_update(struct mtk_
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->mac[i] || !eth->mac[i]->hw_stats)
|
||||
continue;
|
||||
if (spin_trylock(ð->mac[i]->hw_stats->stats_lock)) {
|
||||
@@ -1449,7 +1449,7 @@ static int mtk_queue_stopped(struct mtk_
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
if (netif_queue_stopped(eth->netdev[i]))
|
||||
@@ -1463,7 +1463,7 @@ static void mtk_wake_queue(struct mtk_et
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
netif_tx_wake_all_queues(eth->netdev[i]);
|
||||
@@ -1956,7 +1956,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
|
||||
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
|
||||
|
||||
- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
|
||||
+ if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
|
||||
!eth->netdev[mac]))
|
||||
goto release_desc;
|
||||
|
||||
@@ -2993,7 +2993,7 @@ static void mtk_dma_free(struct mtk_eth
|
||||
const struct mtk_soc_data *soc = eth->soc;
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++)
|
||||
+ for (i = 0; i < soc->num_devs; i++)
|
||||
if (eth->netdev[i])
|
||||
netdev_reset_queue(eth->netdev[i]);
|
||||
if (eth->scratch_ring) {
|
||||
@@ -3147,7 +3147,7 @@ static void mtk_gdm_config(struct mtk_et
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
|
||||
return;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
|
||||
|
||||
/* default setup the forward port to send frame to PDMA */
|
||||
@@ -3758,7 +3758,7 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
* up with the more appropriate value when mtk_mac_config call is being
|
||||
* invoked.
|
||||
*/
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
struct net_device *dev = eth->netdev[i];
|
||||
|
||||
mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
|
||||
@@ -3963,7 +3963,7 @@ static void mtk_pending_work(struct work
|
||||
mtk_prepare_for_reset(eth);
|
||||
|
||||
/* stop all devices to make sure that dma is properly shut down */
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
|
||||
continue;
|
||||
|
||||
@@ -3979,7 +3979,7 @@ static void mtk_pending_work(struct work
|
||||
mtk_hw_init(eth, true);
|
||||
|
||||
/* restart DMA and enable IRQs */
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!test_bit(i, &restart))
|
||||
continue;
|
||||
|
||||
@@ -4007,7 +4007,7 @@ static int mtk_free_dev(struct mtk_eth *
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
free_netdev(eth->netdev[i]);
|
||||
@@ -4026,7 +4026,7 @@ static int mtk_unreg_dev(struct mtk_eth
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
struct mtk_mac *mac;
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
@@ -4331,7 +4331,7 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
}
|
||||
|
||||
id = be32_to_cpup(_id);
|
||||
- if (id >= MTK_MAC_COUNT) {
|
||||
+ if (id >= eth->soc->num_devs) {
|
||||
dev_err(eth->dev, "%d is not a valid mac id\n", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -4461,7 +4461,7 @@ void mtk_eth_set_dma_device(struct mtk_e
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
dev = eth->netdev[i];
|
||||
|
||||
if (!dev || !(dev->flags & IFF_UP))
|
||||
@@ -4787,7 +4787,7 @@ static int mtk_remove(struct platform_de
|
||||
int i;
|
||||
|
||||
/* stop all devices to make sure that dma is properly shut down */
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
mtk_stop(eth->netdev[i]);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -33,7 +33,6 @@
|
||||
#define MTK_TX_DMA_BUF_LEN_V2 0xffff
|
||||
#define MTK_QDMA_RING_SIZE 2048
|
||||
#define MTK_DMA_SIZE 512
|
||||
-#define MTK_MAC_COUNT 2
|
||||
#define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN)
|
||||
#define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
|
||||
#define MTK_DMA_DUMMY_DESC 0xffffffff
|
||||
@@ -0,0 +1,292 @@
|
||||
From ab817f559d505329d8a413c7d29250f6d87d77a0 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:55:47 +0000
|
||||
Subject: [PATCH 4/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability
|
||||
bit
|
||||
|
||||
Introduce MTK_NETSYS_V3 bit in the device capabilities.
|
||||
This is a preliminary patch to introduce support for MT7988 SoC.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++----
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 44 +++++++-
|
||||
2 files changed, 134 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -924,17 +924,32 @@ void mtk_stats_update_mac(struct mtk_mac
|
||||
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
|
||||
hw_stats->rx_flow_control_packets +=
|
||||
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
|
||||
- hw_stats->tx_skip +=
|
||||
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
|
||||
- hw_stats->tx_collisions +=
|
||||
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
|
||||
- hw_stats->tx_bytes +=
|
||||
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
|
||||
- stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
|
||||
- if (stats)
|
||||
- hw_stats->tx_bytes += (stats << 32);
|
||||
- hw_stats->tx_packets +=
|
||||
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
|
||||
+
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
|
||||
+ hw_stats->tx_skip +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
|
||||
+ hw_stats->tx_collisions +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
|
||||
+ hw_stats->tx_bytes +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
|
||||
+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
|
||||
+ if (stats)
|
||||
+ hw_stats->tx_bytes += (stats << 32);
|
||||
+ hw_stats->tx_packets +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
|
||||
+ } else {
|
||||
+ hw_stats->tx_skip +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
|
||||
+ hw_stats->tx_collisions +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
|
||||
+ hw_stats->tx_bytes +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
|
||||
+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
|
||||
+ if (stats)
|
||||
+ hw_stats->tx_bytes += (stats << 32);
|
||||
+ hw_stats->tx_packets +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
|
||||
+ }
|
||||
}
|
||||
|
||||
u64_stats_update_end(&hw_stats->syncp);
|
||||
@@ -1238,7 +1253,10 @@ static void mtk_tx_set_dma_desc_v2(struc
|
||||
data |= TX_DMA_LS0;
|
||||
WRITE_ONCE(desc->txd3, data);
|
||||
|
||||
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
|
||||
+ if (mac->id == MTK_GMAC3_ID)
|
||||
+ data = PSE_GDM3_PORT;
|
||||
+ else
|
||||
+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
|
||||
data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
|
||||
WRITE_ONCE(desc->txd4, data);
|
||||
|
||||
@@ -1249,6 +1267,9 @@ static void mtk_tx_set_dma_desc_v2(struc
|
||||
/* tx checksum offload */
|
||||
if (info->csum)
|
||||
data |= TX_DMA_CHKSUM_V2;
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
|
||||
+ netdev_uses_dsa(dev))
|
||||
+ data |= TX_DMA_SPTAG_V3;
|
||||
}
|
||||
WRITE_ONCE(desc->txd5, data);
|
||||
|
||||
@@ -1314,8 +1335,13 @@ static int mtk_tx_map(struct sk_buff *sk
|
||||
mtk_tx_set_dma_desc(dev, itxd, &txd_info);
|
||||
|
||||
itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
|
||||
- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
|
||||
- MTK_TX_FLAGS_FPORT1;
|
||||
+ if (mac->id == MTK_GMAC1_ID)
|
||||
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
|
||||
+ else if (mac->id == MTK_GMAC2_ID)
|
||||
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
|
||||
+ else
|
||||
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT2;
|
||||
+
|
||||
setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
|
||||
k++);
|
||||
|
||||
@@ -1363,8 +1389,13 @@ static int mtk_tx_map(struct sk_buff *sk
|
||||
memset(tx_buf, 0, sizeof(*tx_buf));
|
||||
tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
|
||||
tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
|
||||
- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
|
||||
- MTK_TX_FLAGS_FPORT1;
|
||||
+
|
||||
+ if (mac->id == MTK_GMAC1_ID)
|
||||
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT0;
|
||||
+ else if (mac->id == MTK_GMAC2_ID)
|
||||
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT1;
|
||||
+ else
|
||||
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT2;
|
||||
|
||||
setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
|
||||
txd_info.size, k++);
|
||||
@@ -1950,11 +1981,24 @@ static int mtk_poll_rx(struct napi_struc
|
||||
break;
|
||||
|
||||
/* find out which mac the packet come from. values start at 1 */
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
|
||||
- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
|
||||
- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
+ u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
|
||||
+
|
||||
+ switch (val) {
|
||||
+ case PSE_GDM1_PORT:
|
||||
+ case PSE_GDM2_PORT:
|
||||
+ mac = val - 1;
|
||||
+ break;
|
||||
+ case PSE_GDM3_PORT:
|
||||
+ mac = MTK_GMAC3_ID;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
|
||||
+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
|
||||
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
|
||||
+ }
|
||||
|
||||
if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
|
||||
!eth->netdev[mac]))
|
||||
@@ -2185,7 +2229,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
|
||||
tx_buf = mtk_desc_to_tx_buf(ring, desc,
|
||||
eth->soc->txrx.txd_size);
|
||||
if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
|
||||
- mac = 1;
|
||||
+ mac = MTK_GMAC2_ID;
|
||||
+ else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
|
||||
+ mac = MTK_GMAC3_ID;
|
||||
|
||||
if (!tx_buf->data)
|
||||
break;
|
||||
@@ -3796,7 +3842,26 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
|
||||
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
|
||||
+ /* PSE should not drop port1, port8 and port9 packets */
|
||||
+ mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
|
||||
+
|
||||
+ /* GDM and CDM Threshold */
|
||||
+ mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
|
||||
+ mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
|
||||
+
|
||||
+ /* Disable GDM1 RX CRC stripping */
|
||||
+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
|
||||
+ val &= ~MTK_GDMA_STRP_CRC;
|
||||
+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));
|
||||
+
|
||||
+ /* PSE GDM3 MIB counter has incorrect hw default values,
|
||||
+ * so the driver ought to read clear the values beforehand
|
||||
+ * in case ethtool retrieve wrong mib values.
|
||||
+ */
|
||||
+ for (i = 0; i < 0x80; i += 0x4)
|
||||
+ mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
|
||||
+ } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
/* PSE should not drop port8 and port9 packets from WDMA Tx */
|
||||
mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
|
||||
|
||||
@@ -4368,7 +4433,11 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
}
|
||||
spin_lock_init(&mac->hw_stats->stats_lock);
|
||||
u64_stats_init(&mac->hw_stats->syncp);
|
||||
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
|
||||
+
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
|
||||
+ mac->hw_stats->reg_offset = id * 0x80;
|
||||
+ else
|
||||
+ mac->hw_stats->reg_offset = id * 0x40;
|
||||
|
||||
/* phylink create */
|
||||
err = of_get_phy_mode(np, &phy_mode);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -121,6 +121,7 @@
|
||||
#define MTK_GDMA_ICS_EN BIT(22)
|
||||
#define MTK_GDMA_TCS_EN BIT(21)
|
||||
#define MTK_GDMA_UCS_EN BIT(20)
|
||||
+#define MTK_GDMA_STRP_CRC BIT(16)
|
||||
#define MTK_GDMA_TO_PDMA 0x0
|
||||
#define MTK_GDMA_DROP_ALL 0x7777
|
||||
|
||||
@@ -286,8 +287,6 @@
|
||||
/* QDMA Interrupt grouping registers */
|
||||
#define MTK_RLS_DONE_INT BIT(0)
|
||||
|
||||
-#define MTK_STAT_OFFSET 0x40
|
||||
-
|
||||
/* QDMA TX NUM */
|
||||
#define QID_BITS_V2(x) (((x) & 0x3f) << 16)
|
||||
#define MTK_QDMA_GMAC2_QID 8
|
||||
@@ -300,6 +299,8 @@
|
||||
#define TX_DMA_CHKSUM_V2 (0x7 << 28)
|
||||
#define TX_DMA_TSO_V2 BIT(31)
|
||||
|
||||
+#define TX_DMA_SPTAG_V3 BIT(27)
|
||||
+
|
||||
/* QDMA V2 descriptor txd4 */
|
||||
#define TX_DMA_FPORT_SHIFT_V2 8
|
||||
#define TX_DMA_FPORT_MASK_V2 0xf
|
||||
@@ -639,6 +640,7 @@ enum mtk_tx_flags {
|
||||
*/
|
||||
MTK_TX_FLAGS_FPORT0 = 0x04,
|
||||
MTK_TX_FLAGS_FPORT1 = 0x08,
|
||||
+ MTK_TX_FLAGS_FPORT2 = 0x10,
|
||||
};
|
||||
|
||||
/* This enum allows us to identify how the clock is defined on the array of the
|
||||
@@ -724,6 +726,42 @@ enum mtk_dev_state {
|
||||
MTK_RESETTING
|
||||
};
|
||||
|
||||
+/* PSE Port Definition */
|
||||
+enum mtk_pse_port {
|
||||
+ PSE_ADMA_PORT = 0,
|
||||
+ PSE_GDM1_PORT,
|
||||
+ PSE_GDM2_PORT,
|
||||
+ PSE_PPE0_PORT,
|
||||
+ PSE_PPE1_PORT,
|
||||
+ PSE_QDMA_TX_PORT,
|
||||
+ PSE_QDMA_RX_PORT,
|
||||
+ PSE_DROP_PORT,
|
||||
+ PSE_WDMA0_PORT,
|
||||
+ PSE_WDMA1_PORT,
|
||||
+ PSE_TDMA_PORT,
|
||||
+ PSE_NONE_PORT,
|
||||
+ PSE_PPE2_PORT,
|
||||
+ PSE_WDMA2_PORT,
|
||||
+ PSE_EIP197_PORT,
|
||||
+ PSE_GDM3_PORT,
|
||||
+ PSE_PORT_MAX
|
||||
+};
|
||||
+
|
||||
+/* GMAC Identifier */
|
||||
+enum mtk_gmac_id {
|
||||
+ MTK_GMAC1_ID = 0,
|
||||
+ MTK_GMAC2_ID,
|
||||
+ MTK_GMAC3_ID,
|
||||
+ MTK_GMAC_ID_MAX
|
||||
+};
|
||||
+
|
||||
+/* GDM Type */
|
||||
+enum mtk_gdm_type {
|
||||
+ MTK_GDM_TYPE = 0,
|
||||
+ MTK_XGDM_TYPE,
|
||||
+ MTK_GDM_TYPE_MAX
|
||||
+};
|
||||
+
|
||||
enum mtk_tx_buf_type {
|
||||
MTK_TYPE_SKB,
|
||||
MTK_TYPE_XDP_TX,
|
||||
@@ -820,6 +858,7 @@ enum mkt_eth_capabilities {
|
||||
MTK_QDMA_BIT,
|
||||
MTK_NETSYS_V1_BIT,
|
||||
MTK_NETSYS_V2_BIT,
|
||||
+ MTK_NETSYS_V3_BIT,
|
||||
MTK_SOC_MT7628_BIT,
|
||||
MTK_RSTCTRL_PPE1_BIT,
|
||||
MTK_U3_COPHY_V2_BIT,
|
||||
@@ -856,6 +895,7 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_QDMA BIT(MTK_QDMA_BIT)
|
||||
#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
|
||||
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
|
||||
+#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
|
||||
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
|
||||
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
|
||||
#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
|
||||
@@ -0,0 +1,197 @@
|
||||
From 45b575fd9e6a455090820248bf1b98b1f2c7b6c8 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:56:00 +0000
|
||||
Subject: [PATCH 5/7] net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data
|
||||
struct to u64
|
||||
|
||||
This is a preliminary patch to introduce support for MT7988 SoC.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 +++----
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 62 ++++++++++----------
|
||||
2 files changed, 42 insertions(+), 42 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
||||
@@ -15,10 +15,10 @@
|
||||
struct mtk_eth_muxc {
|
||||
const char *name;
|
||||
int cap_bit;
|
||||
- int (*set_path)(struct mtk_eth *eth, int path);
|
||||
+ int (*set_path)(struct mtk_eth *eth, u64 path);
|
||||
};
|
||||
|
||||
-static const char *mtk_eth_path_name(int path)
|
||||
+static const char *mtk_eth_path_name(u64 path)
|
||||
{
|
||||
switch (path) {
|
||||
case MTK_ETH_PATH_GMAC1_RGMII:
|
||||
@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int
|
||||
}
|
||||
}
|
||||
|
||||
-static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
bool updated = true;
|
||||
u32 val, mask, set;
|
||||
@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
bool updated = true;
|
||||
@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
unsigned int val = 0, mask = 0, reg = 0;
|
||||
bool updated = true;
|
||||
@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
bool updated = true;
|
||||
@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
bool updated = true;
|
||||
@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth
|
||||
},
|
||||
};
|
||||
|
||||
-static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
|
||||
+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
int i, err = 0;
|
||||
|
||||
@@ -249,7 +249,7 @@ out:
|
||||
|
||||
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
|
||||
{
|
||||
- int path;
|
||||
+ u64 path;
|
||||
|
||||
path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII :
|
||||
MTK_ETH_PATH_GMAC2_SGMII;
|
||||
@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
|
||||
|
||||
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
|
||||
{
|
||||
- int path = 0;
|
||||
+ u64 path = 0;
|
||||
|
||||
if (mac_id == 1)
|
||||
path = MTK_ETH_PATH_GMAC2_GEPHY;
|
||||
@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk
|
||||
|
||||
int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
|
||||
{
|
||||
- int path;
|
||||
+ u64 path;
|
||||
|
||||
path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_RGMII :
|
||||
MTK_ETH_PATH_GMAC2_RGMII;
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -881,44 +881,44 @@ enum mkt_eth_capabilities {
|
||||
};
|
||||
|
||||
/* Supported hardware group on SoCs */
|
||||
-#define MTK_RGMII BIT(MTK_RGMII_BIT)
|
||||
-#define MTK_TRGMII BIT(MTK_TRGMII_BIT)
|
||||
-#define MTK_SGMII BIT(MTK_SGMII_BIT)
|
||||
-#define MTK_ESW BIT(MTK_ESW_BIT)
|
||||
-#define MTK_GEPHY BIT(MTK_GEPHY_BIT)
|
||||
-#define MTK_MUX BIT(MTK_MUX_BIT)
|
||||
-#define MTK_INFRA BIT(MTK_INFRA_BIT)
|
||||
-#define MTK_SHARED_SGMII BIT(MTK_SHARED_SGMII_BIT)
|
||||
-#define MTK_HWLRO BIT(MTK_HWLRO_BIT)
|
||||
-#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
|
||||
-#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
|
||||
-#define MTK_QDMA BIT(MTK_QDMA_BIT)
|
||||
-#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
|
||||
-#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
|
||||
-#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
|
||||
-#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
|
||||
-#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
|
||||
-#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
|
||||
+#define MTK_RGMII BIT_ULL(MTK_RGMII_BIT)
|
||||
+#define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT)
|
||||
+#define MTK_SGMII BIT_ULL(MTK_SGMII_BIT)
|
||||
+#define MTK_ESW BIT_ULL(MTK_ESW_BIT)
|
||||
+#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
|
||||
+#define MTK_MUX BIT_ULL(MTK_MUX_BIT)
|
||||
+#define MTK_INFRA BIT_ULL(MTK_INFRA_BIT)
|
||||
+#define MTK_SHARED_SGMII BIT_ULL(MTK_SHARED_SGMII_BIT)
|
||||
+#define MTK_HWLRO BIT_ULL(MTK_HWLRO_BIT)
|
||||
+#define MTK_SHARED_INT BIT_ULL(MTK_SHARED_INT_BIT)
|
||||
+#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT)
|
||||
+#define MTK_QDMA BIT_ULL(MTK_QDMA_BIT)
|
||||
+#define MTK_NETSYS_V1 BIT_ULL(MTK_NETSYS_V1_BIT)
|
||||
+#define MTK_NETSYS_V2 BIT_ULL(MTK_NETSYS_V2_BIT)
|
||||
+#define MTK_NETSYS_V3 BIT_ULL(MTK_NETSYS_V3_BIT)
|
||||
+#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT)
|
||||
+#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
|
||||
+#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
|
||||
|
||||
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
|
||||
- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
|
||||
#define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY \
|
||||
- BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
|
||||
#define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \
|
||||
- BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
|
||||
#define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \
|
||||
- BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
|
||||
#define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
|
||||
- BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
|
||||
|
||||
/* Supported path present on SoCs */
|
||||
-#define MTK_ETH_PATH_GMAC1_RGMII BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC1_SGMII BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC2_RGMII BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC2_GEPHY BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
|
||||
-#define MTK_ETH_PATH_GDM1_ESW BIT(MTK_ETH_PATH_GDM1_ESW_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC1_TRGMII BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
|
||||
+#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
|
||||
|
||||
#define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
|
||||
#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
|
||||
@@ -1074,7 +1074,7 @@ struct mtk_reg_map {
|
||||
struct mtk_soc_data {
|
||||
const struct mtk_reg_map *reg_map;
|
||||
u32 ana_rgc3;
|
||||
- u32 caps;
|
||||
+ u64 caps;
|
||||
u32 required_clks;
|
||||
bool required_pctl;
|
||||
u8 offload_version;
|
||||
@@ -0,0 +1,495 @@
|
||||
From 661bacf4363ca68939c15e20056b5f72fbd034e7 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sat, 25 Feb 2023 00:08:24 +0100
|
||||
Subject: [PATCH 6/7] net: ethernet: mtk_eth_soc: add support for MT7988 SoC
|
||||
|
||||
Introduce support for ethernet chip available in MT7988 SoC to
|
||||
mtk_eth_soc driver.
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 153 ++++++++++++++--
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 193 ++++++++++++++------
|
||||
2 files changed, 279 insertions(+), 67 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
|
||||
.pse_oq_sta = 0x01a0,
|
||||
};
|
||||
|
||||
+static const struct mtk_reg_map mt7988_reg_map = {
|
||||
+ .tx_irq_mask = 0x461c,
|
||||
+ .tx_irq_status = 0x4618,
|
||||
+ .pdma = {
|
||||
+ .rx_ptr = 0x6900,
|
||||
+ .rx_cnt_cfg = 0x6904,
|
||||
+ .pcrx_ptr = 0x6908,
|
||||
+ .glo_cfg = 0x6a04,
|
||||
+ .rst_idx = 0x6a08,
|
||||
+ .delay_irq = 0x6a0c,
|
||||
+ .irq_status = 0x6a20,
|
||||
+ .irq_mask = 0x6a28,
|
||||
+ .adma_rx_dbg0 = 0x6a38,
|
||||
+ .int_grp = 0x6a50,
|
||||
+ },
|
||||
+ .qdma = {
|
||||
+ .qtx_cfg = 0x4400,
|
||||
+ .qtx_sch = 0x4404,
|
||||
+ .rx_ptr = 0x4500,
|
||||
+ .rx_cnt_cfg = 0x4504,
|
||||
+ .qcrx_ptr = 0x4508,
|
||||
+ .glo_cfg = 0x4604,
|
||||
+ .rst_idx = 0x4608,
|
||||
+ .delay_irq = 0x460c,
|
||||
+ .fc_th = 0x4610,
|
||||
+ .int_grp = 0x4620,
|
||||
+ .hred = 0x4644,
|
||||
+ .ctx_ptr = 0x4700,
|
||||
+ .dtx_ptr = 0x4704,
|
||||
+ .crx_ptr = 0x4710,
|
||||
+ .drx_ptr = 0x4714,
|
||||
+ .fq_head = 0x4720,
|
||||
+ .fq_tail = 0x4724,
|
||||
+ .fq_count = 0x4728,
|
||||
+ .fq_blen = 0x472c,
|
||||
+ .tx_sch_rate = 0x4798,
|
||||
+ },
|
||||
+ .gdm1_cnt = 0x1c00,
|
||||
+ .gdma_to_ppe = 0x3333,
|
||||
+ .ppe_base = 0x2200,
|
||||
+ .wdma_base = {
|
||||
+ [0] = 0x4800,
|
||||
+ [1] = 0x4c00,
|
||||
+ },
|
||||
+ .pse_iq_sta = 0x0180,
|
||||
+ .pse_oq_sta = 0x01a0,
|
||||
+};
|
||||
+
|
||||
/* strings used by ethtool */
|
||||
static const struct mtk_ethtool_stats {
|
||||
char str[ETH_GSTRING_LEN];
|
||||
@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
|
||||
};
|
||||
|
||||
static const char * const mtk_clks_source_name[] = {
|
||||
- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
|
||||
- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
|
||||
- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
|
||||
- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
|
||||
+ "ethif",
|
||||
+ "sgmiitop",
|
||||
+ "esw",
|
||||
+ "gp0",
|
||||
+ "gp1",
|
||||
+ "gp2",
|
||||
+ "gp3",
|
||||
+ "xgp1",
|
||||
+ "xgp2",
|
||||
+ "xgp3",
|
||||
+ "crypto",
|
||||
+ "fe",
|
||||
+ "trgpll",
|
||||
+ "sgmii_tx250m",
|
||||
+ "sgmii_rx250m",
|
||||
+ "sgmii_cdr_ref",
|
||||
+ "sgmii_cdr_fb",
|
||||
+ "sgmii2_tx250m",
|
||||
+ "sgmii2_rx250m",
|
||||
+ "sgmii2_cdr_ref",
|
||||
+ "sgmii2_cdr_fb",
|
||||
+ "sgmii_ck",
|
||||
+ "eth2pll",
|
||||
+ "wocpu0",
|
||||
+ "wocpu1",
|
||||
+ "netsys0",
|
||||
+ "netsys1",
|
||||
+ "ethwarp_wocpu2",
|
||||
+ "ethwarp_wocpu1",
|
||||
+ "ethwarp_wocpu0",
|
||||
+ "top_usxgmii0_sel",
|
||||
+ "top_usxgmii1_sel",
|
||||
+ "top_sgm0_sel",
|
||||
+ "top_sgm1_sel",
|
||||
+ "top_xfi_phy0_xtal_sel",
|
||||
+ "top_xfi_phy1_xtal_sel",
|
||||
+ "top_eth_gmii_sel",
|
||||
+ "top_eth_refck_50m_sel",
|
||||
+ "top_eth_sys_200m_sel",
|
||||
+ "top_eth_sys_sel",
|
||||
+ "top_eth_xgmii_sel",
|
||||
+ "top_eth_mii_sel",
|
||||
+ "top_netsys_sel",
|
||||
+ "top_netsys_500m_sel",
|
||||
+ "top_netsys_pao_2x_sel",
|
||||
+ "top_netsys_sync_250m_sel",
|
||||
+ "top_netsys_ppefb_250m_sel",
|
||||
+ "top_netsys_warp_sel",
|
||||
};
|
||||
|
||||
void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
|
||||
@@ -1253,10 +1345,19 @@ static void mtk_tx_set_dma_desc_v2(struc
|
||||
data |= TX_DMA_LS0;
|
||||
WRITE_ONCE(desc->txd3, data);
|
||||
|
||||
- if (mac->id == MTK_GMAC3_ID)
|
||||
- data = PSE_GDM3_PORT;
|
||||
- else
|
||||
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
|
||||
+ /* set forward port */
|
||||
+ switch (mac->id) {
|
||||
+ case MTK_GMAC1_ID:
|
||||
+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
|
||||
+ break;
|
||||
+ case MTK_GMAC2_ID:
|
||||
+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
|
||||
+ break;
|
||||
+ case MTK_GMAC3_ID:
|
||||
+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
|
||||
WRITE_ONCE(desc->txd4, data);
|
||||
|
||||
@@ -5016,6 +5117,25 @@ static const struct mtk_soc_data mt7986_
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct mtk_soc_data mt7988_data = {
|
||||
+ .reg_map = &mt7988_reg_map,
|
||||
+ .ana_rgc3 = 0x128,
|
||||
+ .caps = MT7988_CAPS,
|
||||
+ .hw_features = MTK_HW_FEATURES,
|
||||
+ .required_clks = MT7988_CLKS_BITMAP,
|
||||
+ .required_pctl = false,
|
||||
+ .num_devs = 3,
|
||||
+ .txrx = {
|
||||
+ .txd_size = sizeof(struct mtk_tx_dma_v2),
|
||||
+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
|
||||
+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
+ .dma_len_offset = 8,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+
|
||||
static const struct mtk_soc_data rt5350_data = {
|
||||
.reg_map = &mt7628_reg_map,
|
||||
.caps = MT7628_CAPS,
|
||||
@@ -5034,14 +5154,15 @@ static const struct mtk_soc_data rt5350_
|
||||
};
|
||||
|
||||
const struct of_device_id of_mtk_match[] = {
|
||||
- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
|
||||
- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
|
||||
- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
|
||||
- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
|
||||
- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
|
||||
- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
|
||||
- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
|
||||
- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
|
||||
+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
|
||||
+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
|
||||
+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
|
||||
+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
|
||||
+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
|
||||
+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
|
||||
+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
|
||||
+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
|
||||
+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_mtk_match);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -116,7 +116,8 @@
|
||||
#define MTK_CDMP_EG_CTRL 0x404
|
||||
|
||||
/* GDM Exgress Control Register */
|
||||
-#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000))
|
||||
+#define MTK_GDMA_FWD_CFG(x) ((x == MTK_GMAC3_ID) ? \
|
||||
+ 0x540 : 0x500 + (x * 0x1000))
|
||||
#define MTK_GDMA_SPECIAL_TAG BIT(24)
|
||||
#define MTK_GDMA_ICS_EN BIT(22)
|
||||
#define MTK_GDMA_TCS_EN BIT(21)
|
||||
@@ -653,6 +654,11 @@ enum mtk_clks_map {
|
||||
MTK_CLK_GP0,
|
||||
MTK_CLK_GP1,
|
||||
MTK_CLK_GP2,
|
||||
+ MTK_CLK_GP3,
|
||||
+ MTK_CLK_XGP1,
|
||||
+ MTK_CLK_XGP2,
|
||||
+ MTK_CLK_XGP3,
|
||||
+ MTK_CLK_CRYPTO,
|
||||
MTK_CLK_FE,
|
||||
MTK_CLK_TRGPLL,
|
||||
MTK_CLK_SGMII_TX_250M,
|
||||
@@ -669,57 +675,108 @@ enum mtk_clks_map {
|
||||
MTK_CLK_WOCPU1,
|
||||
MTK_CLK_NETSYS0,
|
||||
MTK_CLK_NETSYS1,
|
||||
+ MTK_CLK_ETHWARP_WOCPU2,
|
||||
+ MTK_CLK_ETHWARP_WOCPU1,
|
||||
+ MTK_CLK_ETHWARP_WOCPU0,
|
||||
+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
|
||||
+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
|
||||
+ MTK_CLK_TOP_SGM_0_SEL,
|
||||
+ MTK_CLK_TOP_SGM_1_SEL,
|
||||
+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
|
||||
+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
|
||||
+ MTK_CLK_TOP_ETH_GMII_SEL,
|
||||
+ MTK_CLK_TOP_ETH_REFCK_50M_SEL,
|
||||
+ MTK_CLK_TOP_ETH_SYS_200M_SEL,
|
||||
+ MTK_CLK_TOP_ETH_SYS_SEL,
|
||||
+ MTK_CLK_TOP_ETH_XGMII_SEL,
|
||||
+ MTK_CLK_TOP_ETH_MII_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_500M_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_WARP_SEL,
|
||||
MTK_CLK_MAX
|
||||
};
|
||||
|
||||
-#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
|
||||
- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
|
||||
- BIT(MTK_CLK_TRGPLL))
|
||||
-#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
|
||||
- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
|
||||
- BIT(MTK_CLK_GP2) | \
|
||||
- BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII_CK) | \
|
||||
- BIT(MTK_CLK_ETH2PLL))
|
||||
+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
|
||||
+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
|
||||
+ BIT_ULL(MTK_CLK_TRGPLL))
|
||||
+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
|
||||
+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
|
||||
+ BIT_ULL(MTK_CLK_GP2) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CK) | \
|
||||
+ BIT_ULL(MTK_CLK_ETH2PLL))
|
||||
#define MT7621_CLKS_BITMAP (0)
|
||||
#define MT7628_CLKS_BITMAP (0)
|
||||
-#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
|
||||
- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
|
||||
- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
|
||||
- BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII2_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII_CK) | \
|
||||
- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
|
||||
-#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
|
||||
- BIT(MTK_CLK_WOCPU0) | \
|
||||
- BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII2_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII_CK))
|
||||
-#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
|
||||
- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
|
||||
- BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII2_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_FB))
|
||||
+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
|
||||
+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
|
||||
+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CK) | \
|
||||
+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
|
||||
+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
|
||||
+ BIT_ULL(MTK_CLK_WOCPU0) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CK))
|
||||
+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
|
||||
+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
|
||||
+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
|
||||
+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
|
||||
+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
|
||||
+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
|
||||
+ BIT_ULL(MTK_CLK_CRYPTO) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
|
||||
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
|
||||
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
|
||||
|
||||
enum mtk_dev_state {
|
||||
MTK_HW_INIT,
|
||||
@@ -847,6 +904,7 @@ enum mkt_eth_capabilities {
|
||||
MTK_RGMII_BIT = 0,
|
||||
MTK_TRGMII_BIT,
|
||||
MTK_SGMII_BIT,
|
||||
+ MTK_USXGMII_BIT,
|
||||
MTK_ESW_BIT,
|
||||
MTK_GEPHY_BIT,
|
||||
MTK_MUX_BIT,
|
||||
@@ -869,6 +927,8 @@ enum mkt_eth_capabilities {
|
||||
MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
|
||||
MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
|
||||
MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
|
||||
+ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
|
||||
+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
|
||||
|
||||
/* PATH BITS */
|
||||
MTK_ETH_PATH_GMAC1_RGMII_BIT,
|
||||
@@ -877,13 +937,18 @@ enum mkt_eth_capabilities {
|
||||
MTK_ETH_PATH_GMAC2_RGMII_BIT,
|
||||
MTK_ETH_PATH_GMAC2_SGMII_BIT,
|
||||
MTK_ETH_PATH_GMAC2_GEPHY_BIT,
|
||||
+ MTK_ETH_PATH_GMAC3_SGMII_BIT,
|
||||
MTK_ETH_PATH_GDM1_ESW_BIT,
|
||||
+ MTK_ETH_PATH_GMAC1_USXGMII_BIT,
|
||||
+ MTK_ETH_PATH_GMAC2_USXGMII_BIT,
|
||||
+ MTK_ETH_PATH_GMAC3_USXGMII_BIT,
|
||||
};
|
||||
|
||||
/* Supported hardware group on SoCs */
|
||||
#define MTK_RGMII BIT_ULL(MTK_RGMII_BIT)
|
||||
#define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT)
|
||||
#define MTK_SGMII BIT_ULL(MTK_SGMII_BIT)
|
||||
+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT)
|
||||
#define MTK_ESW BIT_ULL(MTK_ESW_BIT)
|
||||
#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
|
||||
#define MTK_MUX BIT_ULL(MTK_MUX_BIT)
|
||||
@@ -910,6 +975,10 @@ enum mkt_eth_capabilities {
|
||||
BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
|
||||
#define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
|
||||
BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
|
||||
+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
|
||||
+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
|
||||
|
||||
/* Supported path present on SoCs */
|
||||
#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
|
||||
@@ -918,7 +987,11 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
|
||||
#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
|
||||
#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
|
||||
#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
|
||||
|
||||
#define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
|
||||
#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
|
||||
@@ -926,7 +999,11 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
|
||||
#define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
|
||||
#define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
|
||||
+#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
|
||||
#define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
|
||||
+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
|
||||
+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
|
||||
+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
|
||||
|
||||
/* MUXes present on SoCs */
|
||||
/* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
|
||||
@@ -949,6 +1026,12 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_MUX_GMAC12_TO_GEPHY_SGMII \
|
||||
(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
|
||||
|
||||
+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \
|
||||
+ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
|
||||
+
|
||||
+#define MTK_MUX_GMAC123_TO_USXGMII \
|
||||
+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
|
||||
+
|
||||
#ifdef CONFIG_SOC_MT7621
|
||||
#define MTK_CAP_MASK MTK_NETSYS_V2
|
||||
#else
|
||||
@@ -987,9 +1070,17 @@ enum mkt_eth_capabilities {
|
||||
MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
|
||||
MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
|
||||
|
||||
-#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
|
||||
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
|
||||
- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
|
||||
+#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
|
||||
+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | \
|
||||
+ MTK_QDMA | MTK_NETSYS_V2 | \
|
||||
+ MTK_RSTCTRL_PPE1)
|
||||
+
|
||||
+#define MT7988_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
|
||||
+ MTK_GMAC3_SGMII | MTK_QDMA | \
|
||||
+ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
|
||||
+ MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 | \
|
||||
+ MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII | \
|
||||
+ MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII)
|
||||
|
||||
struct mtk_tx_dma_desc_info {
|
||||
dma_addr_t addr;
|
||||
@@ -1075,7 +1166,7 @@ struct mtk_soc_data {
|
||||
const struct mtk_reg_map *reg_map;
|
||||
u32 ana_rgc3;
|
||||
u64 caps;
|
||||
- u32 required_clks;
|
||||
+ u64 required_clks;
|
||||
bool required_pctl;
|
||||
u8 offload_version;
|
||||
u8 hash_offset;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2086,10 +2086,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr
|
||||
@@ -2126,10 +2126,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr
|
||||
{
|
||||
struct dsa_switch *ds = priv->ds;
|
||||
struct device *dev = priv->dev;
|
||||
@@ -30,7 +30,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
bus = devm_mdiobus_alloc(dev);
|
||||
if (!bus)
|
||||
return -ENOMEM;
|
||||
@@ -2106,7 +2109,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr
|
||||
@@ -2146,7 +2149,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr
|
||||
if (priv->irq)
|
||||
mt7530_setup_mdio_irq(priv);
|
||||
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
--- a/drivers/cpufreq/rockchip-cpufreq.c
|
||||
+++ b/drivers/cpufreq/rockchip-cpufreq.c
|
||||
@@ -332,13 +332,13 @@ static int rockchip_cpufreq_cluster_init
|
||||
reg_table_token = dev_pm_opp_set_regulators(dev, reg_names);
|
||||
if (reg_table_token < 0) {
|
||||
ret = reg_table_token;
|
||||
- dev_err_probe(dev, ret, "Failed to set opp regulators\n");
|
||||
+ dev_err(dev, "Failed to set opp regulators\n");
|
||||
goto np_err;
|
||||
}
|
||||
|
||||
ret = dev_pm_opp_of_get_sharing_cpus(dev, &cluster->cpus);
|
||||
if (ret) {
|
||||
- dev_err_probe(dev, ret, "Failed to get sharing cpus\n");
|
||||
+ dev_err(dev, "Failed to get sharing cpus\n");
|
||||
goto np_err;
|
||||
}
|
||||
|
||||
@@ -519,67 +519,10 @@ static int rockchip_cpufreq_init(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void rockchip_cpufreq_free_list(void *data)
|
||||
-{
|
||||
- struct cluster_info *cluster, *pos;
|
||||
-
|
||||
- list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) {
|
||||
- list_del(&cluster->list_head);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static int rockchip_cpufreq_init_list(struct device *dev)
|
||||
-{
|
||||
- struct cluster_info *cluster;
|
||||
- int cpu, ret;
|
||||
-
|
||||
- for_each_possible_cpu(cpu) {
|
||||
- cluster = rockchip_cluster_info_lookup(cpu);
|
||||
- if (cluster)
|
||||
- continue;
|
||||
-
|
||||
- cluster = devm_kzalloc(dev, sizeof(*cluster), GFP_KERNEL);
|
||||
- if (!cluster) {
|
||||
- ret = -ENOMEM;
|
||||
- goto release_cluster_info;
|
||||
- }
|
||||
-
|
||||
- ret = rockchip_cpufreq_cluster_init(cpu, cluster);
|
||||
- if (ret) {
|
||||
- dev_err_probe(dev, ret, "Failed to initialize dvfs info cpu%d\n", cpu);
|
||||
- goto release_cluster_info;
|
||||
- }
|
||||
- list_add(&cluster->list_head, &cluster_info_list);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-
|
||||
-release_cluster_info:
|
||||
- rockchip_cpufreq_free_list(NULL);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static void rockchip_cpufreq_unregister(void *data)
|
||||
-{
|
||||
- cpufreq_unregister_driver(&rockchip_cpufreq_driver);
|
||||
-}
|
||||
-
|
||||
static int rockchip_cpufreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret, cpu;
|
||||
|
||||
- ret = rockchip_cpufreq_init_list(&pdev->dev);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = devm_add_action_or_reset(&pdev->dev, rockchip_cpufreq_free_list, NULL);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = devm_register_reboot_notifier(&pdev->dev, &rockchip_cpufreq_reboot_notifier);
|
||||
- if (ret)
|
||||
- return dev_err_probe(&pdev->dev, ret, "Failed to register reboot handler\n");
|
||||
-
|
||||
for_each_possible_cpu(cpu) {
|
||||
ret = rockchip_cpufreq_init(&pdev->dev, cpu);
|
||||
if (ret)
|
||||
@@ -590,10 +533,12 @@ static int rockchip_cpufreq_probe(struct
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret, "failed register driver\n");
|
||||
|
||||
- ret = devm_add_action_or_reset(&pdev->dev, rockchip_cpufreq_unregister, NULL);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
+static int rockchip_cpufreq_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ cpufreq_unregister_driver(&rockchip_cpufreq_driver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -602,15 +547,42 @@ static struct platform_driver rockchip_c
|
||||
.name = "rockchip-cpufreq",
|
||||
},
|
||||
.probe = rockchip_cpufreq_probe,
|
||||
+ .remove = rockchip_cpufreq_remove,
|
||||
};
|
||||
|
||||
static int __init rockchip_cpufreq_driver_init(void)
|
||||
{
|
||||
- int ret;
|
||||
+ struct cluster_info *cluster, *pos;
|
||||
+ int cpu, ret;
|
||||
+
|
||||
+ for_each_possible_cpu(cpu) {
|
||||
+ cluster = rockchip_cluster_info_lookup(cpu);
|
||||
+ if (cluster)
|
||||
+ continue;
|
||||
+
|
||||
+ cluster = kzalloc(sizeof(*cluster), GFP_KERNEL);
|
||||
+ if (!cluster) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto release_cluster_info;
|
||||
+ }
|
||||
+
|
||||
+ ret = rockchip_cpufreq_cluster_init(cpu, cluster);
|
||||
+ if (ret) {
|
||||
+ pr_err("Failed to initialize dvfs info cpu%d\n", cpu);
|
||||
+ goto release_cluster_info;
|
||||
+ }
|
||||
+ list_add(&cluster->list_head, &cluster_info_list);
|
||||
+ }
|
||||
+
|
||||
+ ret = register_reboot_notifier(&rockchip_cpufreq_reboot_notifier);
|
||||
+ if (ret) {
|
||||
+ pr_err("Failed to register reboot handler\n");
|
||||
+ goto release_cluster_info;
|
||||
+ }
|
||||
|
||||
ret = platform_driver_register(&rockchip_cpufreq_platdrv);
|
||||
if (ret)
|
||||
- return ret;
|
||||
+ goto remove_reboot_notifier;
|
||||
|
||||
cpufreq_pdev = platform_device_register_data(NULL, "rockchip-cpufreq", -1,
|
||||
NULL, 0);
|
||||
@@ -624,14 +596,30 @@ static int __init rockchip_cpufreq_drive
|
||||
|
||||
unregister_platform_driver:
|
||||
platform_driver_unregister(&rockchip_cpufreq_platdrv);
|
||||
+
|
||||
+remove_reboot_notifier:
|
||||
+ unregister_reboot_notifier(&rockchip_cpufreq_reboot_notifier);
|
||||
+
|
||||
+release_cluster_info:
|
||||
+ list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) {
|
||||
+ list_del(&cluster->list_head);
|
||||
+ kfree(cluster);
|
||||
+ }
|
||||
return ret;
|
||||
}
|
||||
module_init(rockchip_cpufreq_driver_init);
|
||||
|
||||
static void __exit rockchip_cpufreq_driver_exit(void)
|
||||
{
|
||||
+ struct cluster_info *cluster, *pos;
|
||||
+
|
||||
platform_device_unregister(cpufreq_pdev);
|
||||
platform_driver_unregister(&rockchip_cpufreq_platdrv);
|
||||
+ unregister_reboot_notifier(&rockchip_cpufreq_reboot_notifier);
|
||||
+ list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) {
|
||||
+ list_del(&cluster->list_head);
|
||||
+ kfree(cluster);
|
||||
+ }
|
||||
}
|
||||
module_exit(rockchip_cpufreq_driver_exit)
|
||||
|
||||
Reference in New Issue
Block a user