We're at 5.10 stable, this can finally go.
Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
+++ /dev/null
-CONFIG_AR8216_PHY=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CEVT_R4K=y
-CONFIG_CEVT_SYSTICK_QUIRK=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLKEVT_RT3352=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_LOAD_STORE_LR=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DEBUG_PINCTRL=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
-# CONFIG_DTB_MT7620A_EVAL is not set
-# CONFIG_DTB_OMEGA2P is not set
-CONFIG_DTB_RT_NONE=y
-# CONFIG_DTB_VOCORE2 is not set
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIOLIB=y
-# CONFIG_GPIO_MT7621 is not set
-CONFIG_GPIO_RALINK=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CBPF_JIT=y
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-# CONFIG_MIPS_ELF_APPENDED_DTB is not set
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MT7621_WDT is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
-CONFIG_MTD_SPLIT_JIMAGE_FW=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_MTD_VIRT_CONCAT=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_GSW_MT7620=y
-CONFIG_NET_RALINK_MDIO=y
-CONFIG_NET_RALINK_MDIO_MT7620=y
-CONFIG_NET_RALINK_MT7620=y
-# CONFIG_NET_RALINK_RT3050 is not set
-CONFIG_NET_RALINK_SOC=y
-# CONFIG_NET_VENDOR_MEDIATEK is not set
-CONFIG_NET_VENDOR_RALINK=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_NET=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-# CONFIG_PCI_MT7621 is not set
-# CONFIG_PCI_MT7621_PHY is not set
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHY_RALINK_USB=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_RT2880=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_RALINK=y
-CONFIG_RALINK_WDT=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_SERIAL_8250_RT288X=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SOC_MT7620=y
-# CONFIG_SOC_MT7621 is not set
-# CONFIG_SOC_RT288X is not set
-# CONFIG_SOC_RT305X is not set
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_MT7621 is not set
-CONFIG_SPI_RT2880=y
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_LEDS=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
+++ /dev/null
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BOARD_SCACHE=y
-CONFIG_BOUNCE=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLKSRC_MIPS_GIC=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMMON_CLK=y
-# CONFIG_COMMON_CLK_BOSTON is not set
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_LOAD_STORE_LR=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_ACOMP2=y
-CONFIG_CRYPTO_AEAD=y
-CONFIG_CRYPTO_AEAD2=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_MANAGER2=y
-CONFIG_CRYPTO_NULL2=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DEBUG_PINCTRL=y
-CONFIG_DIMLIB=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
-# CONFIG_DTB_GNUBEE1 is not set
-# CONFIG_DTB_GNUBEE2 is not set
-CONFIG_DTB_RT_NONE=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_FIXED_PHY=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_IPI=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_MT7621=y
-# CONFIG_GPIO_RALINK is not set
-CONFIG_GPIO_WATCHDOG=y
-# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
-CONFIG_GRO_CELLS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HIGHMEM=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_I2C_MT7621=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LED_TRIGGER_PHY=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIKROTIK=y
-CONFIG_MIKROTIK_RB_SYSFS=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CBPF_JIT=y
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-CONFIG_MIPS_CM=y
-# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-CONFIG_MIPS_CPC=y
-CONFIG_MIPS_CPS=y
-# CONFIG_MIPS_CPS_NS16550_BOOL is not set
-CONFIG_MIPS_CPU_SCACHE=y
-# CONFIG_MIPS_ELF_APPENDED_DTB is not set
-CONFIG_MIPS_GIC=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_MIPS_MT=y
-CONFIG_MIPS_MT_FPAFF=y
-CONFIG_MIPS_MT_SMP=y
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_NR_CPU_NR_MAP=4
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MT7621_WDT=y
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_MT7621=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_ROUTERBOOT_PARTS=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_FIT_FW=y
-CONFIG_MTD_SPLIT_MINOR_FW=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_TRX_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MTD_VIRT_CONCAT=y
-# CONFIG_MTK_HSDMA is not set
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MT7530=y
-CONFIG_NET_DSA_TAG_MTK=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_MEDIATEK_SOC=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NET_VENDOR_MEDIATEK=y
-# CONFIG_NET_VENDOR_RALINK is not set
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_NET=y
-CONFIG_PADATA=y
-CONFIG_PCI=y
-CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_DRIVERS_GENERIC=y
-CONFIG_PCI_MT7621=y
-CONFIG_PCI_MT7621_PHY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_RALINK_USB is not set
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_AW9523=y
-CONFIG_PINCTRL_RT2880=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINCTRL_SX150X=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RALINK=y
-# CONFIG_RALINK_WDT is not set
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_BQ32K=y
-CONFIG_RTC_DRV_PCF8563=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-CONFIG_SCHED_SMT=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-# CONFIG_SOC_MT7620 is not set
-CONFIG_SOC_MT7621=y
-# CONFIG_SOC_RT288X is not set
-# CONFIG_SOC_RT305X is not set
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_MT7621=y
-# CONFIG_SPI_RT2880 is not set
-CONFIG_SRCU=y
-CONFIG_SWPHY=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_HIGHMEM=y
-CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_MIPS_CPS=y
-CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMP=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WEAK_ORDERING=y
-CONFIG_WEAK_REORDERING_BEYOND_LLSC=y
-CONFIG_XPS=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
+++ /dev/null
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CEVT_R4K=y
-CONFIG_CEVT_SYSTICK_QUIRK=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLKEVT_RT3352=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_LOAD_STORE_LR=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DEBUG_PINCTRL=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
-# CONFIG_DTB_MT7620A_EVAL is not set
-# CONFIG_DTB_OMEGA2P is not set
-CONFIG_DTB_RT_NONE=y
-# CONFIG_DTB_VOCORE2 is not set
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_FIXED_PHY=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_MT7621=y
-# CONFIG_GPIO_RALINK is not set
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CBPF_JIT=y
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-# CONFIG_MIPS_ELF_APPENDED_DTB is not set
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MT7621_WDT=y
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_TRX_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_ESW_RT3050=y
-# CONFIG_NET_RALINK_MT7620 is not set
-CONFIG_NET_RALINK_RT3050=y
-CONFIG_NET_RALINK_SOC=y
-# CONFIG_NET_VENDOR_MEDIATEK is not set
-CONFIG_NET_VENDOR_RALINK=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_NET=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-# CONFIG_PCI_MT7621 is not set
-# CONFIG_PCI_MT7621_PHY is not set
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHY_RALINK_USB=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_RT2880=y
-# CONFIG_PINCTRL_SINGLE is not set
-# CONFIG_PWM_MEDIATEK is not set
-CONFIG_RALINK=y
-# CONFIG_RALINK_WDT is not set
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SOC_MT7620=y
-# CONFIG_SOC_MT7621 is not set
-# CONFIG_SOC_RT288X is not set
-# CONFIG_SOC_RT305X is not set
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_MT7621=y
-# CONFIG_SPI_RT2880 is not set
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_LEDS=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
+++ /dev/null
-From: Paul Burton <paul.burton@mips.com>
-Date: Wed, 9 Oct 2019 23:09:45 +0000
-Subject: MIPS: cmdline: Clean up boot_command_line initialization
-
-Our current code to initialize boot_command_line is a mess. Some of this
-is due to the addition of too many options over the years, and some of
-this is due to workarounds for early_init_dt_scan_chosen() performing
-actions specific to options from other architectures that probably
-shouldn't be in generic code.
-
-Clean this up by introducing a new bootcmdline_init() function that
-simplifies the initialization somewhat. The major changes are:
-
-- Because bootcmdline_init() is a function it can return early in the
- CONFIG_CMDLINE_OVERRIDE case.
-
-- We clear boot_command_line rather than inheriting whatever
- early_init_dt_scan_chosen() may have left us. This means we no longer
- need to set boot_command_line to a space character in an attempt to
- prevent early_init_dt_scan_chosen() from copying CONFIG_CMDLINE into
- boot_command_line without us knowing about it.
-
-- Indirection via USE_PROM_CMDLINE, USE_DTB_CMDLINE, EXTEND_WITH_PROM &
- BUILTIN_EXTEND_WITH_PROM macros is removed; they seemingly served only
- to obfuscate the code.
-
-- The logic is cleaner, clearer & commented.
-
-Two minor drawbacks of this approach are:
-
-1) We call of_scan_flat_dt(), which means we scan through the DT again.
- The overhead is fairly minimal & shouldn't be noticeable.
-
-2) cmdline_scan_chosen() duplicates a small amount of the logic from
- early_init_dt_scan_chosen(). Alternatives might be to allow the
- generic FDT code to keep & expose a copy of the arguments taken from
- the /chosen node's bootargs property, or to introduce a function like
- early_init_dt_scan_chosen() that retrieves them without modification
- to handle CONFIG_CMDLINE. Neither of these sounds particularly
- cleaner though, and this way we at least keep the extra work in
- arch/mips.
-
-Origin: upstream, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7784cac697351f0cc0a4bb619594c0c99348c5aa
-Signed-off-by: Paul Burton <paul.burton@mips.com>
-Cc: linux-mips@vger.kernel.org
-
---- a/arch/mips/kernel/setup.c
-+++ b/arch/mips/kernel/setup.c
-@@ -538,11 +538,88 @@ static void __init check_kernel_sections
- }
- }
-
--#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
--#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
--#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
--#define BUILTIN_EXTEND_WITH_PROM \
-- IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)
-+static void __init bootcmdline_append(const char *s, size_t max)
-+{
-+ if (!s[0] || !max)
-+ return;
-+
-+ if (boot_command_line[0])
-+ strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
-+
-+ strlcat(boot_command_line, s, max);
-+}
-+
-+static int __init bootcmdline_scan_chosen(unsigned long node, const char *uname,
-+ int depth, void *data)
-+{
-+ bool *dt_bootargs = data;
-+ const char *p;
-+ int l;
-+
-+ if (depth != 1 || !data ||
-+ (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
-+ return 0;
-+
-+ p = of_get_flat_dt_prop(node, "bootargs", &l);
-+ if (p != NULL && l > 0) {
-+ bootcmdline_append(p, min(l, COMMAND_LINE_SIZE));
-+ *dt_bootargs = true;
-+ }
-+
-+ return 1;
-+}
-+
-+static void __init bootcmdline_init(char **cmdline_p)
-+{
-+ bool dt_bootargs = false;
-+
-+ /*
-+ * If CMDLINE_OVERRIDE is enabled then initializing the command line is
-+ * trivial - we simply use the built-in command line unconditionally &
-+ * unmodified.
-+ */
-+ if (IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) {
-+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-+ return;
-+ }
-+
-+ /*
-+ * If the user specified a built-in command line &
-+ * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
-+ * prepended to arguments from the bootloader or DT so we'll copy them
-+ * to the start of boot_command_line here. Otherwise, empty
-+ * boot_command_line to undo anything early_init_dt_scan_chosen() did.
-+ */
-+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
-+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-+ else
-+ boot_command_line[0] = 0;
-+
-+ /*
-+ * If we're configured to take boot arguments from DT, look for those
-+ * now.
-+ */
-+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB))
-+ of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs);
-+
-+ /*
-+ * If we didn't get any arguments from DT (regardless of whether that's
-+ * because we weren't configured to look for them, or because we looked
-+ * & found none) then we'll take arguments from the bootloader.
-+ * plat_mem_setup() should have filled arcs_cmdline with arguments from
-+ * the bootloader.
-+ */
-+ if (IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) || !dt_bootargs)
-+ bootcmdline_append(arcs_cmdline, COMMAND_LINE_SIZE);
-+
-+ /*
-+ * If the user specified a built-in command line & we didn't already
-+ * prepend it, we append it to boot_command_line here.
-+ */
-+ if (IS_ENABLED(CONFIG_CMDLINE_BOOL) &&
-+ !IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
-+ bootcmdline_append(builtin_cmdline, COMMAND_LINE_SIZE);
-+}
-
- /*
- * arch_mem_init - initialize memory management subsystem
-@@ -570,48 +647,12 @@ static void __init arch_mem_init(char **
- {
- extern void plat_mem_setup(void);
-
-- /*
-- * Initialize boot_command_line to an innocuous but non-empty string in
-- * order to prevent early_init_dt_scan_chosen() from copying
-- * CONFIG_CMDLINE into it without our knowledge. We handle
-- * CONFIG_CMDLINE ourselves below & don't want to duplicate its
-- * content because repeating arguments can be problematic.
-- */
-- strlcpy(boot_command_line, " ", COMMAND_LINE_SIZE);
--
- /* call board setup routine */
- plat_mem_setup();
- memblock_set_bottom_up(true);
-
--#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
-- strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
--#else
-- if ((USE_PROM_CMDLINE && arcs_cmdline[0]) ||
-- (USE_DTB_CMDLINE && !boot_command_line[0]))
-- strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
--
-- if (EXTEND_WITH_PROM && arcs_cmdline[0]) {
-- if (boot_command_line[0])
-- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
-- strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
-- }
--
--#if defined(CONFIG_CMDLINE_BOOL)
-- if (builtin_cmdline[0]) {
-- if (boot_command_line[0])
-- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
-- strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-- }
--
-- if (BUILTIN_EXTEND_WITH_PROM && arcs_cmdline[0]) {
-- if (boot_command_line[0])
-- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
-- strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
-- }
--#endif
--#endif
-+ bootcmdline_init(cmdline_p);
- strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
--
- *cmdline_p = command_line;
-
- parse_early_param();
+++ /dev/null
-From b7340422cc16c5deff100812f38114bb5ec81203 Mon Sep 17 00:00:00 2001
-From: Paul Burton <paul.burton@mips.com>
-Date: Sat, 12 Oct 2019 20:43:36 +0000
-Subject: [PATCH] MIPS: Always define builtin_cmdline
-
-Commit 7784cac69735 ("MIPS: cmdline: Clean up boot_command_line
-initialization") made use of builtin_cmdline conditional upon plain C if
-statements rather than preprocessor #ifdef's. This caused build failures
-for configurations with CONFIG_CMDLINE_BOOL=n where builtin_cmdline
-wasn't defined, for example:
-
- arch/mips/kernel/setup.c: In function 'bootcmdline_init':
->> arch/mips/kernel/setup.c:582:30: error: 'builtin_cmdline' undeclared
- (first use in this function); did you mean 'builtin_driver'?
- strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
- ^~~~~~~~~~~~~~~
- builtin_driver
- arch/mips/kernel/setup.c:582:30: note: each undeclared identifier is
- reported only once for each function it appears in
-
-Fix this by defining builtin_cmdline as an empty string in the affected
-configurations. All of the paths that use it should be optimized out
-anyway so the data itself gets optimized away too.
-
-Signed-off-by: Paul Burton <paul.burton@mips.com>
-Fixes: 7784cac69735 ("MIPS: cmdline: Clean up boot_command_line initialization")
-Reported-by: kbuild test robot <lkp@intel.com>
-Reported-by: Nathan Chancellor <natechancellor@gmail.com>
-Cc: linux-mips@vger.kernel.org
----
- arch/mips/kernel/setup.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/mips/kernel/setup.c
-+++ b/arch/mips/kernel/setup.c
-@@ -68,6 +68,8 @@ char __initdata arcs_cmdline[COMMAND_LIN
-
- #ifdef CONFIG_CMDLINE_BOOL
- static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
-+#else
-+static const char builtin_cmdline[] __initconst = "";
- #endif
-
- /*
+++ /dev/null
-From: Tobias Wolf <dev-NTEO@vplace.de>
-Subject: [v2] MIPS: Fix memory reservation in bootmem_init for certain non-usermem setups
-
-Commit 67a3ba25aa95 ("MIPS: Fix incorrect mem=X@Y handling") introduced a new
-issue for rt288x where "PHYS_OFFSET" is 0x0 but the calculated "ramstart" is
-not. As the prerequisite of custom memory map has been removed, this results
-in the full memory range of 0x0 - 0x8000000 to be marked as reserved for this
-platform.
-
-v2: Correctly compare that usermem is not null.
-
-This patch adds the originally intended prerequisite again.
-
-Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
----
-
---- a/arch/mips/kernel/setup.c
-+++ b/arch/mips/kernel/setup.c
-@@ -287,6 +287,8 @@ static unsigned long __init init_initrd(
- * Initialize the bootmem allocator. It also setup initrd related data
- * if needed.
- */
-+static int usermem __initdata;
-+
- #if defined(CONFIG_SGI_IP27) || (defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_NUMA))
-
- static void __init bootmem_init(void)
-@@ -325,7 +327,7 @@ static void __init bootmem_init(void)
- /*
- * Reserve any memory between the start of RAM and PHYS_OFFSET
- */
-- if (ramstart > PHYS_OFFSET)
-+ if (usermem && ramstart > PHYS_OFFSET)
- memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
-
- if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
-@@ -386,8 +388,6 @@ static void __init bootmem_init(void)
-
- #endif /* CONFIG_SGI_IP27 */
-
--static int usermem __initdata;
--
- static int __init early_parse_mem(char *p)
- {
- phys_addr_t start, size;
+++ /dev/null
-From ce3d4a4111a5f7e6b4e74bceae5faa6ce388e8ec Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 14 Jul 2013 23:08:11 +0200
-Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k
- irq
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/ralink/Kconfig | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/arch/mips/ralink/Kconfig
-+++ b/arch/mips/ralink/Kconfig
-@@ -1,12 +1,17 @@
- # SPDX-License-Identifier: GPL-2.0
- if RALINK
-
-+config CEVT_SYSTICK_QUIRK
-+ bool
-+ default n
-+
- config CLKEVT_RT3352
- bool
- depends on SOC_RT305X || SOC_MT7620
- default y
- select TIMER_OF
- select CLKSRC_MMIO
-+ select CEVT_SYSTICK_QUIRK
-
- config RALINK_ILL_ACC
- bool
---- a/arch/mips/kernel/cevt-r4k.c
-+++ b/arch/mips/kernel/cevt-r4k.c
-@@ -15,6 +15,26 @@
- #include <asm/time.h>
- #include <asm/cevt-r4k.h>
-
-+static int mips_state_oneshot(struct clock_event_device *evt)
-+{
-+ if (!cp0_timer_irq_installed) {
-+ cp0_timer_irq_installed = 1;
-+ setup_irq(evt->irq, &c0_compare_irqaction);
-+ }
-+
-+ return 0;
-+}
-+
-+static int mips_state_shutdown(struct clock_event_device *evt)
-+{
-+ if (cp0_timer_irq_installed) {
-+ cp0_timer_irq_installed = 0;
-+ remove_irq(evt->irq, &c0_compare_irqaction);
-+ }
-+
-+ return 0;
-+}
-+
- static int mips_next_event(unsigned long delta,
- struct clock_event_device *evt)
- {
-@@ -281,17 +301,21 @@ int r4k_clockevent_init(void)
- cd->rating = 300;
- cd->irq = irq;
- cd->cpumask = cpumask_of(cpu);
-+ cd->set_state_shutdown = mips_state_shutdown;
-+ cd->set_state_oneshot = mips_state_oneshot;
- cd->set_next_event = mips_next_event;
- cd->event_handler = mips_event_handler;
-
- clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff);
-
-+#ifndef CONFIG_CEVT_SYSTICK_QUIRK
- if (cp0_timer_irq_installed)
- return 0;
-
- cp0_timer_irq_installed = 1;
-
- setup_irq(irq, &c0_compare_irqaction);
-+#endif
-
- return 0;
- }
+++ /dev/null
-From bd30f19a006fb52bac80c6463c49dd2f4159f4ac Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 28 Jul 2013 16:26:41 +0200
-Subject: [PATCH 06/53] MIPS: ralink: add cpu frequency scaling
-
-This feature will break udelay() and cause the delay loop to have longer delays
-when the frequency is scaled causing a performance hit.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/ralink/cevt-rt3352.c | 38 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/arch/mips/ralink/cevt-rt3352.c
-+++ b/arch/mips/ralink/cevt-rt3352.c
-@@ -29,6 +29,10 @@
- /* enable the counter */
- #define CFG_CNT_EN 0x1
-
-+/* mt7620 frequency scaling defines */
-+#define CLK_LUT_CFG 0x40
-+#define SLEEP_EN BIT(31)
-+
- struct systick_device {
- void __iomem *membase;
- struct clock_event_device dev;
-@@ -36,21 +40,53 @@ struct systick_device {
- int freq_scale;
- };
-
-+static void (*systick_freq_scaling)(struct systick_device *sdev, int status);
-+
- static int systick_set_oneshot(struct clock_event_device *evt);
- static int systick_shutdown(struct clock_event_device *evt);
-
-+static inline void mt7620_freq_scaling(struct systick_device *sdev, int status)
-+{
-+ if (sdev->freq_scale == status)
-+ return;
-+
-+ sdev->freq_scale = status;
-+
-+ pr_info("%s: %s autosleep mode\n", sdev->dev.name,
-+ (status) ? ("enable") : ("disable"));
-+ if (status)
-+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) | SLEEP_EN, CLK_LUT_CFG);
-+ else
-+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) & ~SLEEP_EN, CLK_LUT_CFG);
-+}
-+
-+static inline unsigned int read_count(struct systick_device *sdev)
-+{
-+ return ioread32(sdev->membase + SYSTICK_COUNT);
-+}
-+
-+static inline unsigned int read_compare(struct systick_device *sdev)
-+{
-+ return ioread32(sdev->membase + SYSTICK_COMPARE);
-+}
-+
-+static inline void write_compare(struct systick_device *sdev, unsigned int val)
-+{
-+ iowrite32(val, sdev->membase + SYSTICK_COMPARE);
-+}
-+
- static int systick_next_event(unsigned long delta,
- struct clock_event_device *evt)
- {
- struct systick_device *sdev;
-- u32 count;
-+ int res;
-
- sdev = container_of(evt, struct systick_device, dev);
-- count = ioread32(sdev->membase + SYSTICK_COUNT);
-- count = (count + delta) % SYSTICK_FREQ;
-- iowrite32(count, sdev->membase + SYSTICK_COMPARE);
-+ delta += read_count(sdev);
-+ write_compare(sdev, delta);
-+ res = ((int)(read_count(sdev) - delta) >= 0) ? -ETIME : 0;
-
-- return 0;
-+ return res;
- }
-
- static void systick_event_handler(struct clock_event_device *dev)
-@@ -60,20 +96,25 @@ static void systick_event_handler(struct
-
- static irqreturn_t systick_interrupt(int irq, void *dev_id)
- {
-- struct clock_event_device *dev = (struct clock_event_device *) dev_id;
-+ int ret = 0;
-+ struct clock_event_device *cdev;
-+ struct systick_device *sdev;
-
-- dev->event_handler(dev);
-+ if (read_c0_cause() & STATUSF_IP7) {
-+ cdev = (struct clock_event_device *) dev_id;
-+ sdev = container_of(cdev, struct systick_device, dev);
-+
-+ /* Clear Count/Compare Interrupt */
-+ write_compare(sdev, read_compare(sdev));
-+ cdev->event_handler(cdev);
-+ ret = 1;
-+ }
-
-- return IRQ_HANDLED;
-+ return IRQ_RETVAL(ret);
- }
-
- static struct systick_device systick = {
- .dev = {
-- /*
-- * cevt-r4k uses 300, make sure systick
-- * gets used if available
-- */
-- .rating = 310,
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .set_next_event = systick_next_event,
- .set_state_shutdown = systick_shutdown,
-@@ -95,9 +136,15 @@ static int systick_shutdown(struct clock
- sdev = container_of(evt, struct systick_device, dev);
-
- if (sdev->irq_requested)
-- free_irq(systick.dev.irq, &systick_irqaction);
-+ remove_irq(systick.dev.irq, &systick_irqaction);
- sdev->irq_requested = 0;
-- iowrite32(0, systick.membase + SYSTICK_CONFIG);
-+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
-+
-+ if (systick_freq_scaling)
-+ systick_freq_scaling(sdev, 0);
-+
-+ if (systick_freq_scaling)
-+ systick_freq_scaling(sdev, 1);
-
- return 0;
- }
-@@ -117,34 +164,48 @@ static int systick_set_oneshot(struct cl
- return 0;
- }
-
-+static const struct of_device_id systick_match[] = {
-+ { .compatible = "ralink,mt7620a-systick", .data = mt7620_freq_scaling},
-+ {},
-+};
-+
- static int __init ralink_systick_init(struct device_node *np)
- {
-+ const struct of_device_id *match;
-+ int rating = 200;
- int ret;
-
- systick.membase = of_iomap(np, 0);
- if (!systick.membase)
- return -ENXIO;
-
-- systick_irqaction.name = np->name;
-- systick.dev.name = np->name;
-- clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
-- systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
-- systick.dev.max_delta_ticks = 0x7fff;
-- systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
-- systick.dev.min_delta_ticks = 0x3;
-+ match = of_match_node(systick_match, np);
-+ if (match) {
-+ systick_freq_scaling = match->data;
-+ /*
-+ * cevt-r4k uses 300, make sure systick
-+ * gets used if available
-+ */
-+ rating = 310;
-+ }
-+
-+ /* enable counter than register clock source */
-+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
-+ clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
-+ SYSTICK_FREQ, rating, 16, clocksource_mmio_readl_up);
-+
-+ /* register clock event */
- systick.dev.irq = irq_of_parse_and_map(np, 0);
- if (!systick.dev.irq) {
- pr_err("%pOFn: request_irq failed", np);
- return -EINVAL;
- }
-
-- ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
-- SYSTICK_FREQ, 301, 16,
-- clocksource_mmio_readl_up);
-- if (ret)
-- return ret;
--
-- clockevents_register_device(&systick.dev);
-+ systick_irqaction.name = np->name;
-+ systick.dev.name = np->name;
-+ systick.dev.rating = rating;
-+ systick.dev.cpumask = cpumask_of(0);
-+ clockevents_config_and_register(&systick.dev, SYSTICK_FREQ, 0x3, 0x7fff);
-
- pr_info("%pOFn: running - mult: %d, shift: %d\n",
- np, systick.dev.mult, systick.dev.shift);
+++ /dev/null
-From 67b7bff0fd364c194e653f69baa623ba2141bd4c Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 4 Aug 2014 18:46:02 +0200
-Subject: [PATCH 07/53] MIPS: ralink: copy the commandline from the devicetree
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/ralink/of.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/mips/ralink/of.c
-+++ b/arch/mips/ralink/of.c
-@@ -82,6 +82,8 @@ void __init plat_mem_setup(void)
-
- __dt_setup_arch(dtb);
-
-+ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
-+
- of_scan_flat_dt(early_init_dt_find_memory, NULL);
- if (memory_dtb)
- of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+++ /dev/null
-From f15d27f9c90ede4b16eb37f9ae573ef81c2b6996 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 31 Dec 2020 18:49:12 +0100
-Subject: [PATCH] MIPS: add bootargs-override property
-
-Add support for the bootargs-override property to the chosen node
-similar to the one used on ipq806x or mpc85xx.
-
-This is necessary, as the U-Boot used on some boards, notably the
-Ubiquiti UniFi 6 Lite, overwrite the bootargs property of the chosen
-node leading to a kernel panic when loading OpenWrt.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/mips/kernel/setup.c | 30 ++++++++++++++++++++++++++++++
- 1 file changed, 30 insertions(+)
-
---- a/arch/mips/kernel/setup.c
-+++ b/arch/mips/kernel/setup.c
-@@ -571,8 +571,28 @@ static int __init bootcmdline_scan_chose
- return 1;
- }
-
-+static int __init bootcmdline_scan_chosen_override(unsigned long node, const char *uname,
-+ int depth, void *data)
-+{
-+ bool *dt_bootargs = data;
-+ const char *p;
-+ int l;
-+
-+ if (depth != 1 || !data || strcmp(uname, "chosen") != 0)
-+ return 0;
-+
-+ p = of_get_flat_dt_prop(node, "bootargs-override", &l);
-+ if (p != NULL && l > 0) {
-+ strlcpy(boot_command_line, p, COMMAND_LINE_SIZE);
-+ *dt_bootargs = true;
-+ }
-+
-+ return 1;
-+}
-+
- static void __init bootcmdline_init(char **cmdline_p)
- {
-+ bool dt_bootargs_override = false;
- bool dt_bootargs = false;
-
- /*
-@@ -586,6 +606,14 @@ static void __init bootcmdline_init(char
- }
-
- /*
-+ * If bootargs-override in the chosen node is set, use this as the
-+ * command line
-+ */
-+ of_scan_flat_dt(bootcmdline_scan_chosen_override, &dt_bootargs_override);
-+ if (dt_bootargs_override)
-+ return;
-+
-+ /*
- * If the user specified a built-in command line &
- * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
- * prepended to arguments from the bootloader or DT so we'll copy them
+++ /dev/null
-From 5ede027f6c4a57ed25da872420508b7f1168b36b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 7 Dec 2015 17:15:32 +0100
-Subject: [PATCH 13/53] owrt: hack: fix mt7688 cache issue
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/kernel/setup.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/kernel/setup.c
-+++ b/arch/mips/kernel/setup.c
-@@ -723,8 +723,6 @@ static void __init arch_mem_init(char **
- memblock_reserve(crashk_res.start,
- crashk_res.end - crashk_res.start + 1);
- #endif
-- device_tree_init();
--
- /*
- * In order to reduce the possibility of kernel panic when failed to
- * get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate
-@@ -841,6 +839,7 @@ void __init setup_arch(char **cmdline_p)
-
- cpu_cache_init();
- paging_init();
-+ device_tree_init();
- }
-
- unsigned long kernelsp[NR_CPUS];
+++ /dev/null
-From 9e6ce539092a1dd605a20bf73c655a9de58d8641 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 7 Dec 2015 17:18:05 +0100
-Subject: [PATCH 15/53] arch: mips: do not select illegal access driver by
- default
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/ralink/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/mips/ralink/Kconfig
-+++ b/arch/mips/ralink/Kconfig
-@@ -14,9 +14,9 @@ config CLKEVT_RT3352
- select CEVT_SYSTICK_QUIRK
-
- config RALINK_ILL_ACC
-- bool
-+ bool "illegal access irq"
- depends on SOC_RT305X
-- default y
-+ default n
-
- config IRQ_INTC
- bool
+++ /dev/null
-From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 12 Aug 2014 20:49:27 +0200
-Subject: [PATCH 24/53] GPIO: add named gpio exports
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/gpio/gpiolib-of.c | 68 +++++++++++++++++++++++++++++++++++++++++
- drivers/gpio/gpiolib-sysfs.c | 10 +++++-
- include/asm-generic/gpio.h | 6 ++++
- include/linux/gpio/consumer.h | 8 +++++
- 4 files changed, 91 insertions(+), 1 deletion(-)
-
---- a/drivers/gpio/gpiolib-of.c
-+++ b/drivers/gpio/gpiolib-of.c
-@@ -19,6 +19,8 @@
- #include <linux/pinctrl/pinctrl.h>
- #include <linux/slab.h>
- #include <linux/gpio/machine.h>
-+#include <linux/init.h>
-+#include <linux/platform_device.h>
-
- #include "gpiolib.h"
- #include "gpiolib-of.h"
-@@ -915,3 +917,68 @@ void of_gpiochip_remove(struct gpio_chip
- {
- of_node_put(chip->of_node);
- }
-+
-+static struct of_device_id gpio_export_ids[] = {
-+ { .compatible = "gpio-export" },
-+ { /* sentinel */ }
-+};
-+
-+static int of_gpio_export_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct device_node *cnp;
-+ u32 val;
-+ int nb = 0;
-+
-+ for_each_child_of_node(np, cnp) {
-+ const char *name = NULL;
-+ int gpio;
-+ bool dmc;
-+ int max_gpio = 1;
-+ int i;
-+
-+ of_property_read_string(cnp, "gpio-export,name", &name);
-+
-+ if (!name)
-+ max_gpio = of_gpio_count(cnp);
-+
-+ for (i = 0; i < max_gpio; i++) {
-+ unsigned flags = 0;
-+ enum of_gpio_flags of_flags;
-+
-+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
-+ if (!gpio_is_valid(gpio))
-+ return gpio;
-+
-+ if (of_flags == OF_GPIO_ACTIVE_LOW)
-+ flags |= GPIOF_ACTIVE_LOW;
-+
-+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
-+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-+ else
-+ flags |= GPIOF_IN;
-+
-+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
-+ continue;
-+
-+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
-+ gpio_export_with_name(gpio, dmc, name);
-+ nb++;
-+ }
-+ }
-+
-+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver gpio_export_driver = {
-+ .driver = {
-+ .name = "gpio-export",
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(gpio_export_ids),
-+ },
-+ .probe = of_gpio_export_probe,
-+};
-+
-+module_platform_driver(gpio_export_driver);
---- a/drivers/gpio/gpiolib-sysfs.c
-+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -571,7 +571,7 @@ static struct class gpio_class = {
- *
- * Returns zero on success, else an error.
- */
--int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
- {
- struct gpio_chip *chip;
- struct gpio_device *gdev;
-@@ -633,6 +633,8 @@ int gpiod_export(struct gpio_desc *desc,
- offset = gpio_chip_hwgpio(desc);
- if (chip->names && chip->names[offset])
- ioname = chip->names[offset];
-+ if (name)
-+ ioname = name;
-
- dev = device_create_with_groups(&gpio_class, &gdev->dev,
- MKDEV(0, 0), data, gpio_groups,
-@@ -654,6 +656,12 @@ err_unlock:
- gpiod_dbg(desc, "%s: status %d\n", __func__, status);
- return status;
- }
-+EXPORT_SYMBOL_GPL(__gpiod_export);
-+
-+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-+{
-+ return __gpiod_export(desc, direction_may_change, NULL);
-+}
- EXPORT_SYMBOL_GPL(gpiod_export);
-
- static int match_export(struct device *dev, const void *desc)
---- a/include/asm-generic/gpio.h
-+++ b/include/asm-generic/gpio.h
-@@ -127,6 +127,12 @@ static inline int gpio_export(unsigned g
- return gpiod_export(gpio_to_desc(gpio), direction_may_change);
- }
-
-+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
-+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
-+{
-+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
-+}
-+
- static inline int gpio_export_link(struct device *dev, const char *name,
- unsigned gpio)
- {
---- a/include/linux/gpio/consumer.h
-+++ b/include/linux/gpio/consumer.h
-@@ -668,6 +668,7 @@ static inline void devm_acpi_dev_remove_
-
- #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
-
-+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
- int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
- int gpiod_export_link(struct device *dev, const char *name,
- struct gpio_desc *desc);
-@@ -675,6 +676,13 @@ void gpiod_unexport(struct gpio_desc *de
-
- #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
-
-+static inline int _gpiod_export(struct gpio_desc *desc,
-+ bool direction_may_change,
-+ const char *name)
-+{
-+ return -ENOSYS;
-+}
-+
- static inline int gpiod_export(struct gpio_desc *desc,
- bool direction_may_change)
- {
+++ /dev/null
-From d410e5478c622c01fcf31427533df5f433df9146 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 28 Jul 2013 19:45:30 +0200
-Subject: [PATCH 26/53] DT: Add documentation for gpio-ralink
-
-Describe gpio-ralink binding.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Cc: devicetree@vger.kernel.org
-Cc: linux-gpio@vger.kernel.org
----
- .../devicetree/bindings/gpio/gpio-ralink.txt | 40 ++++++++++++++++++++
- 1 file changed, 40 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
-@@ -0,0 +1,40 @@
-+Ralink SoC GPIO controller bindings
-+
-+Required properties:
-+- compatible:
-+ - "ralink,rt2880-gpio" for Ralink controllers
-+- #gpio-cells : Should be two.
-+ - first cell is the pin number
-+ - second cell is used to specify optional parameters (unused)
-+- gpio-controller : Marks the device node as a GPIO controller
-+- reg : Physical base address and length of the controller's registers
-+- interrupt-parent: phandle to the INTC device node
-+- interrupts : Specify the INTC interrupt number
-+- ngpios : Specify the number of GPIOs
-+- ralink,register-map : The register layout depends on the GPIO bank and actual
-+ SoC type. Register offsets need to be in this order.
-+ [ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ]
-+
-+Optional properties:
-+- ralink,gpio-base : Specify the GPIO chips base number
-+
-+Example:
-+
-+ gpio0: gpio@600 {
-+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
-+
-+ #gpio-cells = <2>;
-+ gpio-controller;
-+
-+ reg = <0x600 0x34>;
-+
-+ interrupt-parent = <&intc>;
-+ interrupts = <6>;
-+
-+ ngpios = <24>;
-+ ralink,gpio-base = <0>;
-+ ralink,register-map = [ 00 04 08 0c
-+ 20 24 28 2c
-+ 30 34 ];
-+
-+ };
+++ /dev/null
-From 69fdd2c4f937796b934e89c33acde9d082e27bfd Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 4 Aug 2014 20:36:29 +0200
-Subject: [PATCH 27/53] GPIO: MIPS: ralink: add gpio driver for ralink SoC
-
-Add gpio driver for Ralink SoC. This driver makes the gpio core on
-RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Cc: linux-gpio@vger.kernel.org
----
- arch/mips/include/asm/mach-ralink/gpio.h | 24 ++
- drivers/gpio/Kconfig | 6 +
- drivers/gpio/Makefile | 1 +
- drivers/gpio/gpio-ralink.c | 355 ++++++++++++++++++++++++++++++
- 4 files changed, 386 insertions(+)
- create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h
- create mode 100644 drivers/gpio/gpio-ralink.c
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-ralink/gpio.h
-@@ -0,0 +1,24 @@
-+/*
-+ * Ralink SoC GPIO API support
-+ *
-+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
-+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ *
-+ */
-+
-+#ifndef __ASM_MACH_RALINK_GPIO_H
-+#define __ASM_MACH_RALINK_GPIO_H
-+
-+#define ARCH_NR_GPIOS 128
-+#include <asm-generic/gpio.h>
-+
-+#define gpio_get_value __gpio_get_value
-+#define gpio_set_value __gpio_set_value
-+#define gpio_cansleep __gpio_cansleep
-+#define gpio_to_irq __gpio_to_irq
-+
-+#endif /* __ASM_MACH_RALINK_GPIO_H */
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -471,6 +471,12 @@ config GPIO_SNPS_CREG
- where only several fields in register belong to GPIO lines and
- each GPIO line owns a field with different length and on/off value.
-
-+config GPIO_RALINK
-+ bool "Ralink GPIO Support"
-+ depends on RALINK
-+ help
-+ Say yes here to support the Ralink SoC GPIO device
-+
- config GPIO_SPEAR_SPICS
- bool "ST SPEAr13xx SPI Chip Select as GPIO support"
- depends on PLAT_SPEAR
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -112,6 +112,7 @@ obj-$(CONFIG_GPIO_PISOSR) += gpio-pisos
- obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
- obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o
- obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
-+obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o
- obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
- obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
- obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
---- /dev/null
-+++ b/drivers/gpio/gpio-ralink.c
-@@ -0,0 +1,341 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ *
-+ * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
-+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/io.h>
-+#include <linux/gpio.h>
-+#include <linux/spinlock.h>
-+#include <linux/platform_device.h>
-+#include <linux/of_irq.h>
-+#include <linux/irqdomain.h>
-+#include <linux/interrupt.h>
-+
-+enum ralink_gpio_reg {
-+ GPIO_REG_INT = 0,
-+ GPIO_REG_EDGE,
-+ GPIO_REG_RENA,
-+ GPIO_REG_FENA,
-+ GPIO_REG_DATA,
-+ GPIO_REG_DIR,
-+ GPIO_REG_POL,
-+ GPIO_REG_SET,
-+ GPIO_REG_RESET,
-+ GPIO_REG_TOGGLE,
-+ GPIO_REG_MAX
-+};
-+
-+struct ralink_gpio_chip {
-+ struct gpio_chip chip;
-+ u8 regs[GPIO_REG_MAX];
-+
-+ spinlock_t lock;
-+ void __iomem *membase;
-+ struct irq_domain *domain;
-+ int irq;
-+
-+ u32 rising;
-+ u32 falling;
-+};
-+
-+#define MAP_MAX 4
-+static struct irq_domain *irq_map[MAP_MAX];
-+static int irq_map_count;
-+static atomic_t irq_refcount = ATOMIC_INIT(0);
-+
-+static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip)
-+{
-+ struct ralink_gpio_chip *rg;
-+
-+ rg = container_of(chip, struct ralink_gpio_chip, chip);
-+
-+ return rg;
-+}
-+
-+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val)
-+{
-+ iowrite32(val, rg->membase + rg->regs[reg]);
-+}
-+
-+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg)
-+{
-+ return ioread32(rg->membase + rg->regs[reg]);
-+}
-+
-+static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-+{
-+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
-+
-+ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset));
-+}
-+
-+static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset)
-+{
-+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
-+
-+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
-+}
-+
-+static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-+{
-+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
-+ unsigned long flags;
-+ u32 t;
-+
-+ spin_lock_irqsave(&rg->lock, flags);
-+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
-+ t &= ~BIT(offset);
-+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
-+ spin_unlock_irqrestore(&rg->lock, flags);
-+
-+ return 0;
-+}
-+
-+static int ralink_gpio_direction_output(struct gpio_chip *chip,
-+ unsigned offset, int value)
-+{
-+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
-+ unsigned long flags;
-+ u32 t;
-+
-+ spin_lock_irqsave(&rg->lock, flags);
-+ ralink_gpio_set(chip, offset, value);
-+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
-+ t |= BIT(offset);
-+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
-+ spin_unlock_irqrestore(&rg->lock, flags);
-+
-+ return 0;
-+}
-+
-+static int ralink_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
-+{
-+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
-+
-+ if (rg->irq < 1)
-+ return -1;
-+
-+ return irq_create_mapping(rg->domain, pin);
-+}
-+
-+static void ralink_gpio_irq_handler(struct irq_desc *desc)
-+{
-+ int i;
-+
-+ for (i = 0; i < irq_map_count; i++) {
-+ struct irq_domain *domain = irq_map[i];
-+ struct ralink_gpio_chip *rg;
-+ unsigned long pending;
-+ int bit;
-+
-+ rg = (struct ralink_gpio_chip *) domain->host_data;
-+ pending = rt_gpio_r32(rg, GPIO_REG_INT);
-+
-+ for_each_set_bit(bit, &pending, rg->chip.ngpio) {
-+ u32 map = irq_find_mapping(domain, bit);
-+ generic_handle_irq(map);
-+ rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit));
-+ }
-+ }
-+}
-+
-+static void ralink_gpio_irq_unmask(struct irq_data *d)
-+{
-+ struct ralink_gpio_chip *rg;
-+ unsigned long flags;
-+ u32 rise, fall;
-+
-+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
-+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
-+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
-+
-+ spin_lock_irqsave(&rg->lock, flags);
-+ rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising));
-+ rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling));
-+ spin_unlock_irqrestore(&rg->lock, flags);
-+}
-+
-+static void ralink_gpio_irq_mask(struct irq_data *d)
-+{
-+ struct ralink_gpio_chip *rg;
-+ unsigned long flags;
-+ u32 rise, fall;
-+
-+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
-+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
-+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
-+
-+ spin_lock_irqsave(&rg->lock, flags);
-+ rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq));
-+ rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq));
-+ spin_unlock_irqrestore(&rg->lock, flags);
-+}
-+
-+static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type)
-+{
-+ struct ralink_gpio_chip *rg;
-+ u32 mask = BIT(d->hwirq);
-+
-+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
-+
-+ if (type == IRQ_TYPE_PROBE) {
-+ if ((rg->rising | rg->falling) & mask)
-+ return 0;
-+
-+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
-+ }
-+
-+ if (type & IRQ_TYPE_EDGE_RISING)
-+ rg->rising |= mask;
-+ else
-+ rg->rising &= ~mask;
-+
-+ if (type & IRQ_TYPE_EDGE_FALLING)
-+ rg->falling |= mask;
-+ else
-+ rg->falling &= ~mask;
-+
-+ return 0;
-+}
-+
-+static struct irq_chip ralink_gpio_irq_chip = {
-+ .name = "GPIO",
-+ .irq_unmask = ralink_gpio_irq_unmask,
-+ .irq_mask = ralink_gpio_irq_mask,
-+ .irq_mask_ack = ralink_gpio_irq_mask,
-+ .irq_set_type = ralink_gpio_irq_type,
-+};
-+
-+static int gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
-+{
-+ irq_set_chip_and_handler(irq, &ralink_gpio_irq_chip, handle_level_irq);
-+ irq_set_handler_data(irq, d);
-+
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops irq_domain_ops = {
-+ .xlate = irq_domain_xlate_onecell,
-+ .map = gpio_map,
-+};
-+
-+static void ralink_gpio_irq_init(struct device_node *np,
-+ struct ralink_gpio_chip *rg)
-+{
-+ if (irq_map_count >= MAP_MAX)
-+ return;
-+
-+ rg->irq = irq_of_parse_and_map(np, 0);
-+ if (!rg->irq)
-+ return;
-+
-+ rg->domain = irq_domain_add_linear(np, rg->chip.ngpio,
-+ &irq_domain_ops, rg);
-+ if (!rg->domain) {
-+ dev_err(rg->chip.parent, "irq_domain_add_linear failed\n");
-+ return;
-+ }
-+
-+ irq_map[irq_map_count++] = rg->domain;
-+
-+ rt_gpio_w32(rg, GPIO_REG_RENA, 0x0);
-+ rt_gpio_w32(rg, GPIO_REG_FENA, 0x0);
-+
-+ if (!atomic_read(&irq_refcount))
-+ irq_set_chained_handler(rg->irq, ralink_gpio_irq_handler);
-+ atomic_inc(&irq_refcount);
-+
-+ dev_info(rg->chip.parent, "registering %d irq handlers\n", rg->chip.ngpio);
-+}
-+
-+static int ralink_gpio_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node;
-+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ struct ralink_gpio_chip *rg;
-+ const __be32 *ngpio, *gpiobase;
-+
-+ if (!res) {
-+ dev_err(&pdev->dev, "failed to find resource\n");
-+ return -ENOMEM;
-+ }
-+
-+ rg = devm_kzalloc(&pdev->dev,
-+ sizeof(struct ralink_gpio_chip), GFP_KERNEL);
-+ if (!rg)
-+ return -ENOMEM;
-+
-+ rg->membase = devm_ioremap_resource(&pdev->dev, res);
-+ if (!rg->membase) {
-+ dev_err(&pdev->dev, "cannot remap I/O memory region\n");
-+ return -ENOMEM;
-+ }
-+
-+ if (of_property_read_u8_array(np, "ralink,register-map",
-+ rg->regs, GPIO_REG_MAX)) {
-+ dev_err(&pdev->dev, "failed to read register definition\n");
-+ return -EINVAL;
-+ }
-+
-+ ngpio = of_get_property(np, "ngpios", NULL);
-+ if (!ngpio) {
-+ dev_err(&pdev->dev, "failed to read number of pins\n");
-+ return -EINVAL;
-+ }
-+
-+ gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
-+ if (gpiobase)
-+ rg->chip.base = be32_to_cpu(*gpiobase);
-+ else
-+ rg->chip.base = -1;
-+
-+ spin_lock_init(&rg->lock);
-+
-+ rg->chip.parent = &pdev->dev;
-+ rg->chip.label = dev_name(&pdev->dev);
-+ rg->chip.of_node = np;
-+ rg->chip.ngpio = be32_to_cpu(*ngpio);
-+ rg->chip.direction_input = ralink_gpio_direction_input;
-+ rg->chip.direction_output = ralink_gpio_direction_output;
-+ rg->chip.get = ralink_gpio_get;
-+ rg->chip.set = ralink_gpio_set;
-+ rg->chip.request = gpiochip_generic_request;
-+ rg->chip.to_irq = ralink_gpio_to_irq;
-+ rg->chip.free = gpiochip_generic_free;
-+
-+ /* set polarity to low for all lines */
-+ rt_gpio_w32(rg, GPIO_REG_POL, 0);
-+
-+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
-+
-+ ralink_gpio_irq_init(np, rg);
-+
-+ return gpiochip_add(&rg->chip);
-+}
-+
-+static const struct of_device_id ralink_gpio_match[] = {
-+ { .compatible = "ralink,rt2880-gpio" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ralink_gpio_match);
-+
-+static struct platform_driver ralink_gpio_driver = {
-+ .probe = ralink_gpio_probe,
-+ .driver = {
-+ .name = "rt2880_gpio",
-+ .owner = THIS_MODULE,
-+ .of_match_table = ralink_gpio_match,
-+ },
-+};
-+
-+static int __init ralink_gpio_init(void)
-+{
-+ return platform_driver_register(&ralink_gpio_driver);
-+}
-+
-+subsys_initcall(ralink_gpio_init);
+++ /dev/null
-From 57fa7f2f4ef6f78ce1d30509c0d111aa3791b524 Mon Sep 17 00:00:00 2001
-From: Daniel Santos <daniel.santos@pobox.com>
-Date: Sun, 4 Nov 2018 20:24:32 -0600
-Subject: gpio-ralink: Add support for GPIO as interrupt-controller
-
-Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
----
- Documentation/devicetree/bindings/gpio/gpio-ralink.txt | 6 ++++++
- drivers/gpio/gpio-ralink.c | 2 +-
- 2 files changed, 7 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
-+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
-@@ -17,6 +17,9 @@ Required properties:
-
- Optional properties:
- - ralink,gpio-base : Specify the GPIO chips base number
-+- interrupt-controller : marks this as an interrupt controller
-+- #interrupt-cells : a standard two-cell interrupt flag, see
-+ interrupt-controller/interrupts.txt
-
- Example:
-
-@@ -28,6 +31,9 @@ Example:
-
- reg = <0x600 0x34>;
-
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+
- interrupt-parent = <&intc>;
- interrupts = <6>;
-
---- a/drivers/gpio/gpio-ralink.c
-+++ b/drivers/gpio/gpio-ralink.c
-@@ -220,7 +220,7 @@ static int gpio_map(struct irq_domain *d
- }
-
- static const struct irq_domain_ops irq_domain_ops = {
-- .xlate = irq_domain_xlate_onecell,
-+ .xlate = irq_domain_xlate_twocell,
- .map = gpio_map,
- };
-
+++ /dev/null
-From 975e76214cd2516eb6cfff4c3eec581872645e88 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 19 Sep 2013 01:50:59 +0200
-Subject: [PATCH 31/53] uvc: add iPassion iP2970 support
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/media/usb/uvc/uvc_driver.c | 12 +++
- drivers/media/usb/uvc/uvc_status.c | 2 +
- drivers/media/usb/uvc/uvc_video.c | 147 ++++++++++++++++++++++++++++++++++++
- drivers/media/usb/uvc/uvcvideo.h | 5 +-
- 4 files changed, 165 insertions(+), 1 deletion(-)
-
---- a/drivers/media/usb/uvc/uvc_driver.c
-+++ b/drivers/media/usb/uvc/uvc_driver.c
-@@ -2916,6 +2916,18 @@ static const struct usb_device_id uvc_id
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
-+ /* iPassion iP2970 */
-+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
-+ | USB_DEVICE_ID_MATCH_INT_INFO,
-+ .idVendor = 0x1B3B,
-+ .idProduct = 0x2970,
-+ .bInterfaceClass = USB_CLASS_VIDEO,
-+ .bInterfaceSubClass = 1,
-+ .bInterfaceProtocol = 0,
-+ .driver_info = UVC_QUIRK_PROBE_MINMAX
-+ | UVC_QUIRK_STREAM_NO_FID
-+ | UVC_QUIRK_MOTION
-+ | UVC_QUIRK_SINGLE_ISO },
- /* Generic USB Video Class */
- { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
- { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
---- a/drivers/media/usb/uvc/uvc_status.c
-+++ b/drivers/media/usb/uvc/uvc_status.c
-@@ -223,6 +223,7 @@ static void uvc_status_complete(struct u
- if (uvc_event_control(urb, status, len))
- /* The URB will be resubmitted in work context. */
- return;
-+ dev->motion = 1;
- break;
- }
-
-@@ -271,6 +272,7 @@ int uvc_status_init(struct uvc_device *d
- }
-
- pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
-+ dev->motion = 0;
-
- /* For high-speed interrupt endpoints, the bInterval value is used as
- * an exponent of two. Some developers forgot about it.
---- a/drivers/media/usb/uvc/uvc_video.c
-+++ b/drivers/media/usb/uvc/uvc_video.c
-@@ -16,6 +16,11 @@
- #include <linux/wait.h>
- #include <linux/atomic.h>
- #include <asm/unaligned.h>
-+#include <linux/skbuff.h>
-+#include <linux/kobject.h>
-+#include <linux/netlink.h>
-+#include <linux/kobject.h>
-+#include <linux/workqueue.h>
-
- #include <media/v4l2-common.h>
-
-@@ -1188,9 +1193,149 @@ static void uvc_video_decode_data(struct
- uvc_urb->async_operations++;
- }
-
-+struct bh_priv {
-+ unsigned long seen;
-+};
-+
-+struct bh_event {
-+ const char *name;
-+ struct sk_buff *skb;
-+ struct work_struct work;
-+};
-+
-+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, "webcam", ##args )
-+#define BH_DBG(fmt, args...) do {} while (0)
-+#define BH_SKB_SIZE 2048
-+
-+extern u64 uevent_next_seqnum(void);
-+static int seen = 0;
-+
-+static int bh_event_add_var(struct bh_event *event, int argv,
-+ const char *format, ...)
-+{
-+ static char buf[128];
-+ char *s;
-+ va_list args;
-+ int len;
-+
-+ if (argv)
-+ return 0;
-+
-+ va_start(args, format);
-+ len = vsnprintf(buf, sizeof(buf), format, args);
-+ va_end(args);
-+
-+ if (len >= sizeof(buf)) {
-+ BH_ERR("buffer size too small\n");
-+ WARN_ON(1);
-+ return -ENOMEM;
-+ }
-+
-+ s = skb_put(event->skb, len + 1);
-+ strcpy(s, buf);
-+
-+ BH_DBG("added variable '%s'\n", s);
-+
-+ return 0;
-+}
-+
-+static int motion_hotplug_fill_event(struct bh_event *event)
-+{
-+ int s = jiffies;
-+ int ret;
-+
-+ if (!seen)
-+ seen = jiffies;
-+
-+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
-+ if (ret)
-+ return ret;
-+
-+ ret = bh_event_add_var(event, 0, "PATH=%s",
-+ "/sbin:/bin:/usr/sbin:/usr/bin");
-+ if (ret)
-+ return ret;
-+
-+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=usb");
-+ if (ret)
-+ return ret;
-+
-+ ret = bh_event_add_var(event, 0, "ACTION=motion");
-+ if (ret)
-+ return ret;
-+
-+ ret = bh_event_add_var(event, 0, "SEEN=%d", s - seen);
-+ if (ret)
-+ return ret;
-+ seen = s;
-+
-+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
-+
-+ return ret;
-+}
-+
-+static void motion_hotplug_work(struct work_struct *work)
-+{
-+ struct bh_event *event = container_of(work, struct bh_event, work);
-+ int ret = 0;
-+
-+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
-+ if (!event->skb)
-+ goto out_free_event;
-+
-+ ret = bh_event_add_var(event, 0, "%s@", "add");
-+ if (ret)
-+ goto out_free_skb;
-+
-+ ret = motion_hotplug_fill_event(event);
-+ if (ret)
-+ goto out_free_skb;
-+
-+ NETLINK_CB(event->skb).dst_group = 1;
-+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
-+
-+out_free_skb:
-+ if (ret) {
-+ BH_ERR("work error %d\n", ret);
-+ kfree_skb(event->skb);
-+ }
-+out_free_event:
-+ kfree(event);
-+}
-+
-+static int motion_hotplug_create_event(void)
-+{
-+ struct bh_event *event;
-+
-+ event = kzalloc(sizeof(*event), GFP_KERNEL);
-+ if (!event)
-+ return -ENOMEM;
-+
-+ event->name = "motion";
-+
-+ INIT_WORK(&event->work, (void *)(void *)motion_hotplug_work);
-+ schedule_work(&event->work);
-+
-+ return 0;
-+}
-+
-+#define MOTION_FLAG_OFFSET 4
- static void uvc_video_decode_end(struct uvc_streaming *stream,
- struct uvc_buffer *buf, const u8 *data, int len)
- {
-+ if ((stream->dev->quirks & UVC_QUIRK_MOTION) &&
-+ (data[len - 2] == 0xff) && (data[len - 1] == 0xd9)) {
-+ u8 *mem;
-+ buf->state = UVC_BUF_STATE_READY;
-+ mem = (u8 *) (buf->mem + MOTION_FLAG_OFFSET);
-+ if ( stream->dev->motion ) {
-+ stream->dev->motion = 0;
-+ motion_hotplug_create_event();
-+ } else {
-+ *mem &= 0x7f;
-+ }
-+ }
-+
- /* Mark the buffer as done if the EOF marker is set. */
- if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
- uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
-@@ -1747,6 +1892,8 @@ static int uvc_init_video_isoc(struct uv
- if (npackets == 0)
- return -ENOMEM;
-
-+ if (stream->dev->quirks & UVC_QUIRK_SINGLE_ISO)
-+ npackets = 1;
- size = npackets * psize;
-
- for_each_uvc_urb(uvc_urb, stream) {
---- a/drivers/media/usb/uvc/uvcvideo.h
-+++ b/drivers/media/usb/uvc/uvcvideo.h
-@@ -199,7 +199,9 @@
- #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400
- #define UVC_QUIRK_FORCE_Y8 0x00000800
- #define UVC_QUIRK_FORCE_BPP 0x00001000
--
-+#define UVC_QUIRK_MOTION 0x00001000
-+#define UVC_QUIRK_SINGLE_ISO 0x00002000
-+
- /* Format flags */
- #define UVC_FMT_FLAG_COMPRESSED 0x00000001
- #define UVC_FMT_FLAG_STREAM 0x00000002
-@@ -666,6 +668,7 @@ struct uvc_device {
- u8 *status;
- struct input_dev *input;
- char input_phys[64];
-+ int motion;
-
- struct uvc_ctrl_work {
- struct work_struct work;
+++ /dev/null
-From ee9081b2726a5ca8cde5497afdc5425e21ff8f8b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 15 Jul 2013 00:39:21 +0200
-Subject: [PATCH 37/53] mtd: cfi cmdset 0002 force word write
-
----
- drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -40,7 +40,7 @@
- #include <linux/mtd/xip.h>
-
- #define AMD_BOOTLOC_BUG
--#define FORCE_WORD_WRITE 0
-+#define FORCE_WORD_WRITE 1
-
- #define MAX_RETRIES 3
-
+++ /dev/null
-From da6015e7f19d749f135f7ac55c4ec47b06faa868 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 9 Aug 2013 20:12:59 +0200
-Subject: [PATCH 41/53] DT: Add documentation for spi-rt2880
-
-Describe the SPI master found on the MIPS based Ralink RT2880 SoC.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- .../devicetree/bindings/spi/spi-rt2880.txt | 28 ++++++++++++++++++++
- 1 file changed, 28 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/spi/spi-rt2880.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/spi/spi-rt2880.txt
-@@ -0,0 +1,28 @@
-+Ralink SoC RT2880 SPI master controller.
-+
-+This SPI controller is found on most wireless SoCs made by ralink.
-+
-+Required properties:
-+- compatible : "ralink,rt2880-spi"
-+- reg : The register base for the controller.
-+- #address-cells : <1>, as required by generic SPI binding.
-+- #size-cells : <0>, also as required by generic SPI binding.
-+
-+Child nodes as per the generic SPI binding.
-+
-+Example:
-+
-+ spi@b00 {
-+ compatible = "ralink,rt2880-spi";
-+ reg = <0xb00 0x100>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ m25p80@0 {
-+ compatible = "m25p80";
-+ reg = <0>;
-+ spi-max-frequency = <10000000>;
-+ };
-+ };
-+
+++ /dev/null
-From 683af4ebb91a1600df1946ac4769d916b8a1be65 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 27 Jul 2014 11:15:12 +0100
-Subject: [PATCH 42/53] SPI: ralink: add Ralink SoC spi driver
-
-Add the driver needed to make SPI work on Ralink SoC.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: John Crispin <blogic@openwrt.org>
----
- drivers/spi/Kconfig | 6 +
- drivers/spi/Makefile | 1 +
- drivers/spi/spi-rt2880.c | 530 ++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 537 insertions(+)
- create mode 100644 drivers/spi/spi-rt2880.c
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -605,6 +605,12 @@ config SPI_QCOM_GENI
- This driver can also be built as a module. If so, the module
- will be called spi-geni-qcom.
-
-+config SPI_RT2880
-+ tristate "Ralink RT288x SPI Controller"
-+ depends on RALINK
-+ help
-+ This selects a driver for the Ralink RT288x/RT305x SPI Controller.
-+
- config SPI_S3C24XX
- tristate "Samsung S3C24XX series SPI"
- depends on ARCH_S3C24XX
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -87,6 +87,7 @@ obj-$(CONFIG_SPI_QUP) += spi-qup.o
- obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
- obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
- obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
-+obj-$(CONFIG_SPI_RT2880) += spi-rt2880.o
- obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
- spi-s3c24xx-hw-y := spi-s3c24xx.o
- spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o
---- /dev/null
-+++ b/drivers/spi/spi-rt2880.c
-@@ -0,0 +1,530 @@
-+/*
-+ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver
-+ *
-+ * Copyright (C) 2011 Sergiy <piratfm@gmail.com>
-+ * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
-+ *
-+ * Some parts are based on spi-orion.c:
-+ * Author: Shadi Ammouri <shadi@marvell.com>
-+ * Copyright (C) 2007-2008 Marvell Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/delay.h>
-+#include <linux/io.h>
-+#include <linux/reset.h>
-+#include <linux/spi/spi.h>
-+#include <linux/platform_device.h>
-+#include <linux/gpio.h>
-+
-+#define DRIVER_NAME "spi-rt2880"
-+
-+#define RAMIPS_SPI_STAT 0x00
-+#define RAMIPS_SPI_CFG 0x10
-+#define RAMIPS_SPI_CTL 0x14
-+#define RAMIPS_SPI_DATA 0x20
-+#define RAMIPS_SPI_ADDR 0x24
-+#define RAMIPS_SPI_BS 0x28
-+#define RAMIPS_SPI_USER 0x2C
-+#define RAMIPS_SPI_TXFIFO 0x30
-+#define RAMIPS_SPI_RXFIFO 0x34
-+#define RAMIPS_SPI_FIFO_STAT 0x38
-+#define RAMIPS_SPI_MODE 0x3C
-+#define RAMIPS_SPI_DEV_OFFSET 0x40
-+#define RAMIPS_SPI_DMA 0x80
-+#define RAMIPS_SPI_DMASTAT 0x84
-+#define RAMIPS_SPI_ARBITER 0xF0
-+
-+/* SPISTAT register bit field */
-+#define SPISTAT_BUSY BIT(0)
-+
-+/* SPICFG register bit field */
-+#define SPICFG_ADDRMODE BIT(12)
-+#define SPICFG_RXENVDIS BIT(11)
-+#define SPICFG_RXCAP BIT(10)
-+#define SPICFG_SPIENMODE BIT(9)
-+#define SPICFG_MSBFIRST BIT(8)
-+#define SPICFG_SPICLKPOL BIT(6)
-+#define SPICFG_RXCLKEDGE_FALLING BIT(5)
-+#define SPICFG_TXCLKEDGE_FALLING BIT(4)
-+#define SPICFG_HIZSPI BIT(3)
-+#define SPICFG_SPICLK_PRESCALE_MASK 0x7
-+#define SPICFG_SPICLK_DIV2 0
-+#define SPICFG_SPICLK_DIV4 1
-+#define SPICFG_SPICLK_DIV8 2
-+#define SPICFG_SPICLK_DIV16 3
-+#define SPICFG_SPICLK_DIV32 4
-+#define SPICFG_SPICLK_DIV64 5
-+#define SPICFG_SPICLK_DIV128 6
-+#define SPICFG_SPICLK_DISABLE 7
-+
-+/* SPICTL register bit field */
-+#define SPICTL_START BIT(4)
-+#define SPICTL_HIZSDO BIT(3)
-+#define SPICTL_STARTWR BIT(2)
-+#define SPICTL_STARTRD BIT(1)
-+#define SPICTL_SPIENA BIT(0)
-+
-+/* SPIUSER register bit field */
-+#define SPIUSER_USERMODE BIT(21)
-+#define SPIUSER_INSTR_PHASE BIT(20)
-+#define SPIUSER_ADDR_PHASE_MASK 0x7
-+#define SPIUSER_ADDR_PHASE_OFFSET 17
-+#define SPIUSER_MODE_PHASE BIT(16)
-+#define SPIUSER_DUMMY_PHASE_MASK 0x3
-+#define SPIUSER_DUMMY_PHASE_OFFSET 14
-+#define SPIUSER_DATA_PHASE_MASK 0x3
-+#define SPIUSER_DATA_PHASE_OFFSET 12
-+#define SPIUSER_DATA_READ (BIT(0) << SPIUSER_DATA_PHASE_OFFSET)
-+#define SPIUSER_DATA_WRITE (BIT(1) << SPIUSER_DATA_PHASE_OFFSET)
-+#define SPIUSER_ADDR_TYPE_OFFSET 9
-+#define SPIUSER_MODE_TYPE_OFFSET 6
-+#define SPIUSER_DUMMY_TYPE_OFFSET 3
-+#define SPIUSER_DATA_TYPE_OFFSET 0
-+#define SPIUSER_TRANSFER_MASK 0x7
-+#define SPIUSER_TRANSFER_SINGLE BIT(0)
-+#define SPIUSER_TRANSFER_DUAL BIT(1)
-+#define SPIUSER_TRANSFER_QUAD BIT(2)
-+
-+#define SPIUSER_TRANSFER_TYPE(type) ( \
-+ (type << SPIUSER_ADDR_TYPE_OFFSET) | \
-+ (type << SPIUSER_MODE_TYPE_OFFSET) | \
-+ (type << SPIUSER_DUMMY_TYPE_OFFSET) | \
-+ (type << SPIUSER_DATA_TYPE_OFFSET) \
-+)
-+
-+/* SPIFIFOSTAT register bit field */
-+#define SPIFIFOSTAT_TXEMPTY BIT(19)
-+#define SPIFIFOSTAT_RXEMPTY BIT(18)
-+#define SPIFIFOSTAT_TXFULL BIT(17)
-+#define SPIFIFOSTAT_RXFULL BIT(16)
-+#define SPIFIFOSTAT_FIFO_MASK 0xff
-+#define SPIFIFOSTAT_TX_OFFSET 8
-+#define SPIFIFOSTAT_RX_OFFSET 0
-+
-+#define SPI_FIFO_DEPTH 16
-+
-+/* SPIMODE register bit field */
-+#define SPIMODE_MODE_OFFSET 24
-+#define SPIMODE_DUMMY_OFFSET 0
-+
-+/* SPIARB register bit field */
-+#define SPICTL_ARB_EN BIT(31)
-+#define SPICTL_CSCTL1 BIT(16)
-+#define SPI1_POR BIT(1)
-+#define SPI0_POR BIT(0)
-+
-+#define RT2880_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | \
-+ SPI_CS_HIGH)
-+
-+static atomic_t hw_reset_count = ATOMIC_INIT(0);
-+
-+struct rt2880_spi {
-+ struct spi_master *master;
-+ void __iomem *base;
-+ u32 speed;
-+ u16 wait_loops;
-+ u16 mode;
-+ struct clk *clk;
-+};
-+
-+static inline struct rt2880_spi *spidev_to_rt2880_spi(struct spi_device *spi)
-+{
-+ return spi_master_get_devdata(spi->master);
-+}
-+
-+static inline u32 rt2880_spi_read(struct rt2880_spi *rs, u32 reg)
-+{
-+ return ioread32(rs->base + reg);
-+}
-+
-+static inline void rt2880_spi_write(struct rt2880_spi *rs, u32 reg,
-+ const u32 val)
-+{
-+ iowrite32(val, rs->base + reg);
-+}
-+
-+static inline void rt2880_spi_setbits(struct rt2880_spi *rs, u32 reg, u32 mask)
-+{
-+ void __iomem *addr = rs->base + reg;
-+
-+ iowrite32((ioread32(addr) | mask), addr);
-+}
-+
-+static inline void rt2880_spi_clrbits(struct rt2880_spi *rs, u32 reg, u32 mask)
-+{
-+ void __iomem *addr = rs->base + reg;
-+
-+ iowrite32((ioread32(addr) & ~mask), addr);
-+}
-+
-+static u32 rt2880_spi_baudrate_get(struct spi_device *spi, unsigned int speed)
-+{
-+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
-+ u32 rate;
-+ u32 prescale;
-+
-+ /*
-+ * the supported rates are: 2, 4, 8, ... 128
-+ * round up as we look for equal or less speed
-+ */
-+ rate = DIV_ROUND_UP(clk_get_rate(rs->clk), speed);
-+ rate = roundup_pow_of_two(rate);
-+
-+ /* Convert the rate to SPI clock divisor value. */
-+ prescale = ilog2(rate / 2);
-+
-+ /* some tolerance. double and add 100 */
-+ rs->wait_loops = (8 * HZ * loops_per_jiffy) /
-+ (clk_get_rate(rs->clk) / rate);
-+ rs->wait_loops = (rs->wait_loops << 1) + 100;
-+ rs->speed = speed;
-+
-+ dev_dbg(&spi->dev, "speed: %lu/%u, rate: %u, prescal: %u, loops: %hu\n",
-+ clk_get_rate(rs->clk) / rate, speed, rate, prescale,
-+ rs->wait_loops);
-+
-+ return prescale;
-+}
-+
-+static u32 get_arbiter_offset(struct spi_master *master)
-+{
-+ u32 offset;
-+
-+ offset = RAMIPS_SPI_ARBITER;
-+ if (master->bus_num == 1)
-+ offset -= RAMIPS_SPI_DEV_OFFSET;
-+
-+ return offset;
-+}
-+
-+static void rt2880_spi_set_cs(struct spi_device *spi, bool enable)
-+{
-+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
-+
-+ if (enable)
-+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
-+ else
-+ rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
-+}
-+
-+static int rt2880_spi_wait_ready(struct rt2880_spi *rs, int len)
-+{
-+ int loop = rs->wait_loops * len;
-+
-+ while ((rt2880_spi_read(rs, RAMIPS_SPI_STAT) & SPISTAT_BUSY) && --loop)
-+ cpu_relax();
-+
-+ if (loop)
-+ return 0;
-+
-+ return -ETIMEDOUT;
-+}
-+
-+static void rt2880_dump_reg(struct spi_master *master)
-+{
-+ struct rt2880_spi *rs = spi_master_get_devdata(master);
-+
-+ dev_dbg(&master->dev, "stat: %08x, cfg: %08x, ctl: %08x, " \
-+ "data: %08x, arb: %08x\n",
-+ rt2880_spi_read(rs, RAMIPS_SPI_STAT),
-+ rt2880_spi_read(rs, RAMIPS_SPI_CFG),
-+ rt2880_spi_read(rs, RAMIPS_SPI_CTL),
-+ rt2880_spi_read(rs, RAMIPS_SPI_DATA),
-+ rt2880_spi_read(rs, get_arbiter_offset(master)));
-+}
-+
-+static int rt2880_spi_transfer_one(struct spi_master *master,
-+ struct spi_device *spi, struct spi_transfer *xfer)
-+{
-+ struct rt2880_spi *rs = spi_master_get_devdata(master);
-+ unsigned len;
-+ const u8 *tx = xfer->tx_buf;
-+ u8 *rx = xfer->rx_buf;
-+ int err = 0;
-+
-+ /* change clock speed */
-+ if (unlikely(rs->speed != xfer->speed_hz)) {
-+ u32 reg;
-+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
-+ reg &= ~SPICFG_SPICLK_PRESCALE_MASK;
-+ reg |= rt2880_spi_baudrate_get(spi, xfer->speed_hz);
-+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
-+ }
-+
-+ if (tx) {
-+ len = xfer->len;
-+ while (len-- > 0) {
-+ rt2880_spi_write(rs, RAMIPS_SPI_DATA, *tx++);
-+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR);
-+ err = rt2880_spi_wait_ready(rs, 1);
-+ if (err) {
-+ dev_err(&spi->dev, "TX failed, err=%d\n", err);
-+ goto out;
-+ }
-+ }
-+ }
-+
-+ if (rx) {
-+ len = xfer->len;
-+ while (len-- > 0) {
-+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD);
-+ err = rt2880_spi_wait_ready(rs, 1);
-+ if (err) {
-+ dev_err(&spi->dev, "RX failed, err=%d\n", err);
-+ goto out;
-+ }
-+ *rx++ = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA);
-+ }
-+ }
-+
-+out:
-+ return err;
-+}
-+
-+/* copy from spi.c */
-+static void spi_set_cs(struct spi_device *spi, bool enable)
-+{
-+ if (spi->mode & SPI_CS_HIGH)
-+ enable = !enable;
-+
-+ if (spi->cs_gpio >= 0)
-+ gpio_set_value(spi->cs_gpio, !enable);
-+ else if (spi->master->set_cs)
-+ spi->master->set_cs(spi, !enable);
-+}
-+
-+static int rt2880_spi_setup(struct spi_device *spi)
-+{
-+ struct spi_master *master = spi->master;
-+ struct rt2880_spi *rs = spi_master_get_devdata(master);
-+ u32 reg, old_reg, arbit_off;
-+
-+ if ((spi->max_speed_hz > master->max_speed_hz) ||
-+ (spi->max_speed_hz < master->min_speed_hz)) {
-+ dev_err(&spi->dev, "invalide requested speed %d Hz\n",
-+ spi->max_speed_hz);
-+ return -EINVAL;
-+ }
-+
-+ if (!(master->bits_per_word_mask &
-+ BIT(spi->bits_per_word - 1))) {
-+ dev_err(&spi->dev, "invalide bits_per_word %d\n",
-+ spi->bits_per_word);
-+ return -EINVAL;
-+ }
-+
-+ /* the hardware seems can't work on mode0 force it to mode3 */
-+ if ((spi->mode & (SPI_CPOL | SPI_CPHA)) == SPI_MODE_0) {
-+ dev_warn(&spi->dev, "force spi mode3\n");
-+ spi->mode |= SPI_MODE_3;
-+ }
-+
-+ /* chip polarity */
-+ arbit_off = get_arbiter_offset(master);
-+ reg = old_reg = rt2880_spi_read(rs, arbit_off);
-+ if (spi->mode & SPI_CS_HIGH) {
-+ switch (master->bus_num) {
-+ case 1:
-+ reg |= SPI1_POR;
-+ break;
-+ default:
-+ reg |= SPI0_POR;
-+ break;
-+ }
-+ } else {
-+ switch (master->bus_num) {
-+ case 1:
-+ reg &= ~SPI1_POR;
-+ break;
-+ default:
-+ reg &= ~SPI0_POR;
-+ break;
-+ }
-+ }
-+
-+ /* enable spi1 */
-+ if (master->bus_num == 1)
-+ reg |= SPICTL_ARB_EN;
-+
-+ if (reg != old_reg)
-+ rt2880_spi_write(rs, arbit_off, reg);
-+
-+ /* deselected the spi device */
-+ spi_set_cs(spi, false);
-+
-+ rt2880_dump_reg(master);
-+
-+ return 0;
-+}
-+
-+static int rt2880_spi_prepare_message(struct spi_master *master,
-+ struct spi_message *msg)
-+{
-+ struct rt2880_spi *rs = spi_master_get_devdata(master);
-+ struct spi_device *spi = msg->spi;
-+ u32 reg;
-+
-+ if ((rs->mode == spi->mode) && (rs->speed == spi->max_speed_hz))
-+ return 0;
-+
-+#if 0
-+ /* set spido to tri-state */
-+ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO);
-+#endif
-+
-+ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
-+
-+ reg &= ~(SPICFG_MSBFIRST | SPICFG_SPICLKPOL |
-+ SPICFG_RXCLKEDGE_FALLING |
-+ SPICFG_TXCLKEDGE_FALLING |
-+ SPICFG_SPICLK_PRESCALE_MASK);
-+
-+ /* MSB */
-+ if (!(spi->mode & SPI_LSB_FIRST))
-+ reg |= SPICFG_MSBFIRST;
-+
-+ /* spi mode */
-+ switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
-+ case SPI_MODE_0:
-+ reg |= SPICFG_TXCLKEDGE_FALLING;
-+ break;
-+ case SPI_MODE_1:
-+ reg |= SPICFG_RXCLKEDGE_FALLING;
-+ break;
-+ case SPI_MODE_2:
-+ reg |= SPICFG_SPICLKPOL | SPICFG_RXCLKEDGE_FALLING;
-+ break;
-+ case SPI_MODE_3:
-+ reg |= SPICFG_SPICLKPOL | SPICFG_TXCLKEDGE_FALLING;
-+ break;
-+ }
-+ rs->mode = spi->mode;
-+
-+#if 0
-+ /* set spiclk and spiena to tri-state */
-+ reg |= SPICFG_HIZSPI;
-+#endif
-+
-+ /* clock divide */
-+ reg |= rt2880_spi_baudrate_get(spi, spi->max_speed_hz);
-+
-+ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
-+
-+ return 0;
-+}
-+
-+static int rt2880_spi_probe(struct platform_device *pdev)
-+{
-+ struct spi_master *master;
-+ struct rt2880_spi *rs;
-+ void __iomem *base;
-+ struct resource *r;
-+ struct clk *clk;
-+ int ret;
-+
-+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ base = devm_ioremap_resource(&pdev->dev, r);
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ clk = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(clk)) {
-+ dev_err(&pdev->dev, "unable to get SYS clock\n");
-+ return PTR_ERR(clk);
-+ }
-+
-+ ret = clk_prepare_enable(clk);
-+ if (ret)
-+ goto err_clk;
-+
-+ master = spi_alloc_master(&pdev->dev, sizeof(*rs));
-+ if (master == NULL) {
-+ dev_dbg(&pdev->dev, "master allocation failed\n");
-+ ret = -ENOMEM;
-+ goto err_clk;
-+ }
-+
-+ master->dev.of_node = pdev->dev.of_node;
-+ master->mode_bits = RT2880_SPI_MODE_BITS;
-+ master->bits_per_word_mask = SPI_BPW_MASK(8);
-+ master->min_speed_hz = clk_get_rate(clk) / 128;
-+ master->max_speed_hz = clk_get_rate(clk) / 2;
-+ master->flags = SPI_MASTER_HALF_DUPLEX;
-+ master->setup = rt2880_spi_setup;
-+ master->prepare_message = rt2880_spi_prepare_message;
-+ master->set_cs = rt2880_spi_set_cs;
-+ master->transfer_one = rt2880_spi_transfer_one,
-+
-+ dev_set_drvdata(&pdev->dev, master);
-+
-+ rs = spi_master_get_devdata(master);
-+ rs->master = master;
-+ rs->base = base;
-+ rs->clk = clk;
-+
-+ if (atomic_inc_return(&hw_reset_count) == 1)
-+ device_reset(&pdev->dev);
-+
-+ ret = devm_spi_register_master(&pdev->dev, master);
-+ if (ret < 0) {
-+ dev_err(&pdev->dev, "devm_spi_register_master error.\n");
-+ goto err_master;
-+ }
-+
-+ return ret;
-+
-+err_master:
-+ spi_master_put(master);
-+ kfree(master);
-+err_clk:
-+ clk_disable_unprepare(clk);
-+
-+ return ret;
-+}
-+
-+static int rt2880_spi_remove(struct platform_device *pdev)
-+{
-+ struct spi_master *master;
-+ struct rt2880_spi *rs;
-+
-+ master = dev_get_drvdata(&pdev->dev);
-+ rs = spi_master_get_devdata(master);
-+
-+ clk_disable_unprepare(rs->clk);
-+ atomic_dec(&hw_reset_count);
-+
-+ return 0;
-+}
-+
-+MODULE_ALIAS("platform:" DRIVER_NAME);
-+
-+static const struct of_device_id rt2880_spi_match[] = {
-+ { .compatible = "ralink,rt2880-spi" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, rt2880_spi_match);
-+
-+static struct platform_driver rt2880_spi_driver = {
-+ .driver = {
-+ .name = DRIVER_NAME,
-+ .owner = THIS_MODULE,
-+ .of_match_table = rt2880_spi_match,
-+ },
-+ .probe = rt2880_spi_probe,
-+ .remove = rt2880_spi_remove,
-+};
-+
-+module_platform_driver(rt2880_spi_driver);
-+
-+MODULE_DESCRIPTION("Ralink SPI driver");
-+MODULE_AUTHOR("Sergiy <piratfm@gmail.com>");
-+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
-+MODULE_LICENSE("GPL");
+++ /dev/null
-From 723b8beaabf3c3c4b1ce69480141f1e926f3f3b2 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 27 Jul 2014 09:52:56 +0100
-Subject: [PATCH 44/53] i2c: MIPS: adds ralink I2C driver
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- .../devicetree/bindings/i2c/i2c-ralink.txt | 27 ++
- drivers/i2c/busses/Kconfig | 4 +
- drivers/i2c/busses/Makefile | 1 +
- drivers/i2c/busses/i2c-ralink.c | 327 ++++++++++++++++++++
- 4 files changed, 359 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/i2c/i2c-ralink.txt
- create mode 100644 drivers/i2c/busses/i2c-ralink.c
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt
-@@ -0,0 +1,27 @@
-+I2C for Ralink platforms
-+
-+Required properties :
-+- compatible : Must be "link,rt3052-i2c"
-+- reg: physical base address of the controller and length of memory mapped
-+ region.
-+- #address-cells = <1>;
-+- #size-cells = <0>;
-+
-+Optional properties:
-+- Child nodes conforming to i2c bus binding
-+
-+Example :
-+
-+palmbus@10000000 {
-+ i2c@900 {
-+ compatible = "link,rt3052-i2c";
-+ reg = <0x900 0x100>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ hwmon@4b {
-+ compatible = "national,lm92";
-+ reg = <0x4b>;
-+ };
-+ };
-+};
---- a/drivers/i2c/busses/Kconfig
-+++ b/drivers/i2c/busses/Kconfig
-@@ -922,6 +922,11 @@ config I2C_RK3X
- This driver can also be built as a module. If so, the module will
- be called i2c-rk3x.
-
-+config I2C_RALINK
-+ tristate "Ralink I2C Controller"
-+ depends on RALINK && !SOC_MT7621
-+ select OF_I2C
-+
- config HAVE_S3C2410_I2C
- bool
- help
---- a/drivers/i2c/busses/Makefile
-+++ b/drivers/i2c/busses/Makefile
-@@ -91,6 +91,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
- obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
- obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
- obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
-+obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o
- obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom-geni.o
- obj-$(CONFIG_I2C_QUP) += i2c-qup.o
- obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-ralink.c
-@@ -0,0 +1,435 @@
-+/*
-+ * drivers/i2c/busses/i2c-ralink.c
-+ *
-+ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com>
-+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com>
-+ *
-+ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus.
-+ * (C) 2014 Sittisak <sittisaks@hotmail.com>
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/interrupt.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/reset.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/platform_device.h>
-+#include <linux/of_platform.h>
-+#include <linux/i2c.h>
-+#include <linux/io.h>
-+#include <linux/err.h>
-+#include <linux/clk.h>
-+
-+#define REG_CONFIG_REG 0x00
-+#define REG_CLKDIV_REG 0x04
-+#define REG_DEVADDR_REG 0x08
-+#define REG_ADDR_REG 0x0C
-+#define REG_DATAOUT_REG 0x10
-+#define REG_DATAIN_REG 0x14
-+#define REG_STATUS_REG 0x18
-+#define REG_STARTXFR_REG 0x1C
-+#define REG_BYTECNT_REG 0x20
-+
-+/* REG_CONFIG_REG */
-+#define I2C_ADDRLEN_OFFSET 5
-+#define I2C_DEVADLEN_OFFSET 2
-+#define I2C_ADDRLEN_MASK 0x3
-+#define I2C_ADDR_DIS BIT(1)
-+#define I2C_DEVADDR_DIS BIT(0)
-+#define I2C_ADDRLEN_8 (7 << I2C_ADDRLEN_OFFSET)
-+#define I2C_DEVADLEN_7 (6 << I2C_DEVADLEN_OFFSET)
-+#define I2C_CONF_DEFAULT (I2C_ADDRLEN_8 | I2C_DEVADLEN_7)
-+
-+/* REG_CLKDIV_REG */
-+#define I2C_CLKDIV_MASK 0xffff
-+
-+/* REG_DEVADDR_REG */
-+#define I2C_DEVADDR_MASK 0x7f
-+
-+/* REG_ADDR_REG */
-+#define I2C_ADDR_MASK 0xff
-+
-+/* REG_STATUS_REG */
-+#define I2C_STARTERR BIT(4)
-+#define I2C_ACKERR BIT(3)
-+#define I2C_DATARDY BIT(2)
-+#define I2C_SDOEMPTY BIT(1)
-+#define I2C_BUSY BIT(0)
-+
-+/* REG_STARTXFR_REG */
-+#define NOSTOP_CMD BIT(2)
-+#define NODATA_CMD BIT(1)
-+#define READ_CMD BIT(0)
-+
-+/* REG_BYTECNT_REG */
-+#define BYTECNT_MAX 64
-+#define SET_BYTECNT(x) (x - 1)
-+
-+/* timeout waiting for I2C devices to respond (clock streching) */
-+#define TIMEOUT_MS 1000
-+#define DELAY_INTERVAL_US 100
-+
-+struct rt_i2c {
-+ void __iomem *base;
-+ struct clk *clk;
-+ struct device *dev;
-+ struct i2c_adapter adap;
-+ u32 cur_clk;
-+ u32 clk_div;
-+ u32 flags;
-+};
-+
-+static void rt_i2c_w32(struct rt_i2c *i2c, u32 val, unsigned reg)
-+{
-+ iowrite32(val, i2c->base + reg);
-+}
-+
-+static u32 rt_i2c_r32(struct rt_i2c *i2c, unsigned reg)
-+{
-+ return ioread32(i2c->base + reg);
-+}
-+
-+static int poll_down_timeout(void __iomem *addr, u32 mask)
-+{
-+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
-+
-+ do {
-+ if (!(readl_relaxed(addr) & mask))
-+ return 0;
-+
-+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
-+ } while (time_before(jiffies, timeout));
-+
-+ return (readl_relaxed(addr) & mask) ? -EAGAIN : 0;
-+}
-+
-+static int rt_i2c_wait_idle(struct rt_i2c *i2c)
-+{
-+ int ret;
-+
-+ ret = poll_down_timeout(i2c->base + REG_STATUS_REG, I2C_BUSY);
-+ if (ret < 0)
-+ dev_dbg(i2c->dev, "idle err(%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static int poll_up_timeout(void __iomem *addr, u32 mask)
-+{
-+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
-+ u32 status;
-+
-+ do {
-+ status = readl_relaxed(addr);
-+
-+ /* check error status */
-+ if (status & I2C_STARTERR)
-+ return -EAGAIN;
-+ else if (status & I2C_ACKERR)
-+ return -ENXIO;
-+ else if (status & mask)
-+ return 0;
-+
-+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
-+ } while (time_before(jiffies, timeout));
-+
-+ return -ETIMEDOUT;
-+}
-+
-+static int rt_i2c_wait_rx_done(struct rt_i2c *i2c)
-+{
-+ int ret;
-+
-+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_DATARDY);
-+ if (ret < 0)
-+ dev_dbg(i2c->dev, "rx err(%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static int rt_i2c_wait_tx_done(struct rt_i2c *i2c)
-+{
-+ int ret;
-+
-+ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_SDOEMPTY);
-+ if (ret < 0)
-+ dev_dbg(i2c->dev, "tx err(%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static void rt_i2c_reset(struct rt_i2c *i2c)
-+{
-+ device_reset(i2c->adap.dev.parent);
-+ barrier();
-+ rt_i2c_w32(i2c, i2c->clk_div, REG_CLKDIV_REG);
-+}
-+
-+static void rt_i2c_dump_reg(struct rt_i2c *i2c)
-+{
-+ dev_dbg(i2c->dev, "conf %08x, clkdiv %08x, devaddr %08x, " \
-+ "addr %08x, dataout %08x, datain %08x, " \
-+ "status %08x, startxfr %08x, bytecnt %08x\n",
-+ rt_i2c_r32(i2c, REG_CONFIG_REG),
-+ rt_i2c_r32(i2c, REG_CLKDIV_REG),
-+ rt_i2c_r32(i2c, REG_DEVADDR_REG),
-+ rt_i2c_r32(i2c, REG_ADDR_REG),
-+ rt_i2c_r32(i2c, REG_DATAOUT_REG),
-+ rt_i2c_r32(i2c, REG_DATAIN_REG),
-+ rt_i2c_r32(i2c, REG_STATUS_REG),
-+ rt_i2c_r32(i2c, REG_STARTXFR_REG),
-+ rt_i2c_r32(i2c, REG_BYTECNT_REG));
-+}
-+
-+static int rt_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
-+ int num)
-+{
-+ struct rt_i2c *i2c;
-+ struct i2c_msg *pmsg;
-+ unsigned char addr;
-+ int i, j, ret;
-+ u32 cmd;
-+
-+ i2c = i2c_get_adapdata(adap);
-+
-+ for (i = 0; i < num; i++) {
-+ pmsg = &msgs[i];
-+ if (i == (num - 1))
-+ cmd = 0;
-+ else
-+ cmd = NOSTOP_CMD;
-+
-+ dev_dbg(i2c->dev, "addr: 0x%x, len: %d, flags: 0x%x, stop: %d\n",
-+ pmsg->addr, pmsg->len, pmsg->flags,
-+ (cmd == 0)? 1 : 0);
-+
-+ /* wait hardware idle */
-+ if ((ret = rt_i2c_wait_idle(i2c)))
-+ goto err_timeout;
-+
-+ if (pmsg->flags & I2C_M_TEN) {
-+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT, REG_CONFIG_REG);
-+ /* 10 bits address */
-+ addr = 0x78 | ((pmsg->addr >> 8) & 0x03);
-+ rt_i2c_w32(i2c, addr & I2C_DEVADDR_MASK,
-+ REG_DEVADDR_REG);
-+ rt_i2c_w32(i2c, pmsg->addr & I2C_ADDR_MASK,
-+ REG_ADDR_REG);
-+ } else {
-+ rt_i2c_w32(i2c, I2C_CONF_DEFAULT | I2C_ADDR_DIS,
-+ REG_CONFIG_REG);
-+ /* 7 bits address */
-+ rt_i2c_w32(i2c, pmsg->addr & I2C_DEVADDR_MASK,
-+ REG_DEVADDR_REG);
-+ }
-+
-+ /* buffer length */
-+ if (pmsg->len == 0)
-+ cmd |= NODATA_CMD;
-+ else
-+ rt_i2c_w32(i2c, SET_BYTECNT(pmsg->len),
-+ REG_BYTECNT_REG);
-+
-+ j = 0;
-+ if (pmsg->flags & I2C_M_RD) {
-+ cmd |= READ_CMD;
-+ /* start transfer */
-+ barrier();
-+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
-+ do {
-+ /* wait */
-+ if ((ret = rt_i2c_wait_rx_done(i2c)))
-+ goto err_timeout;
-+ /* read data */
-+ if (pmsg->len)
-+ pmsg->buf[j] = rt_i2c_r32(i2c,
-+ REG_DATAIN_REG);
-+ j++;
-+ } while (j < pmsg->len);
-+ } else {
-+ do {
-+ /* write data */
-+ if (pmsg->len)
-+ rt_i2c_w32(i2c, pmsg->buf[j],
-+ REG_DATAOUT_REG);
-+ /* start transfer */
-+ if (j == 0) {
-+ barrier();
-+ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
-+ }
-+ /* wait */
-+ if ((ret = rt_i2c_wait_tx_done(i2c)))
-+ goto err_timeout;
-+ j++;
-+ } while (j < pmsg->len);
-+ }
-+ }
-+ /* the return value is number of executed messages */
-+ ret = i;
-+
-+ return ret;
-+
-+err_timeout:
-+ rt_i2c_dump_reg(i2c);
-+ rt_i2c_reset(i2c);
-+ return ret;
-+}
-+
-+static u32 rt_i2c_func(struct i2c_adapter *a)
-+{
-+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-+}
-+
-+static const struct i2c_algorithm rt_i2c_algo = {
-+ .master_xfer = rt_i2c_master_xfer,
-+ .functionality = rt_i2c_func,
-+};
-+
-+static const struct of_device_id i2c_rt_dt_ids[] = {
-+ { .compatible = "ralink,rt2880-i2c" },
-+ { /* sentinel */ }
-+};
-+
-+MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids);
-+
-+static struct i2c_adapter_quirks rt_i2c_quirks = {
-+ .max_write_len = BYTECNT_MAX,
-+ .max_read_len = BYTECNT_MAX,
-+};
-+
-+static int rt_i2c_init(struct rt_i2c *i2c)
-+{
-+ u32 reg;
-+
-+ /* i2c_sclk = periph_clk / ((2 * clk_div) + 5) */
-+ i2c->clk_div = (clk_get_rate(i2c->clk) - (5 * i2c->cur_clk)) /
-+ (2 * i2c->cur_clk);
-+ if (i2c->clk_div < 8)
-+ i2c->clk_div = 8;
-+ if (i2c->clk_div > I2C_CLKDIV_MASK)
-+ i2c->clk_div = I2C_CLKDIV_MASK;
-+
-+ /* check support combinde/repeated start message */
-+ rt_i2c_w32(i2c, NOSTOP_CMD, REG_STARTXFR_REG);
-+ reg = rt_i2c_r32(i2c, REG_STARTXFR_REG) & NOSTOP_CMD;
-+
-+ rt_i2c_reset(i2c);
-+
-+ return reg;
-+}
-+
-+static int rt_i2c_probe(struct platform_device *pdev)
-+{
-+ struct resource *res;
-+ struct rt_i2c *i2c;
-+ struct i2c_adapter *adap;
-+ const struct of_device_id *match;
-+ int ret, restart;
-+
-+ match = of_match_device(i2c_rt_dt_ids, &pdev->dev);
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!res) {
-+ dev_err(&pdev->dev, "no memory resource found\n");
-+ return -ENODEV;
-+ }
-+
-+ i2c = devm_kzalloc(&pdev->dev, sizeof(struct rt_i2c), GFP_KERNEL);
-+ if (!i2c) {
-+ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n");
-+ return -ENOMEM;
-+ }
-+
-+ i2c->base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(i2c->base))
-+ return PTR_ERR(i2c->base);
-+
-+ i2c->clk = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(i2c->clk)) {
-+ dev_err(&pdev->dev, "no clock defined\n");
-+ return -ENODEV;
-+ }
-+ clk_prepare_enable(i2c->clk);
-+ i2c->dev = &pdev->dev;
-+
-+ if (of_property_read_u32(pdev->dev.of_node,
-+ "clock-frequency", &i2c->cur_clk))
-+ i2c->cur_clk = 100000;
-+
-+ adap = &i2c->adap;
-+ adap->owner = THIS_MODULE;
-+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
-+ adap->algo = &rt_i2c_algo;
-+ adap->retries = 3;
-+ adap->dev.parent = &pdev->dev;
-+ i2c_set_adapdata(adap, i2c);
-+ adap->dev.of_node = pdev->dev.of_node;
-+ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
-+ adap->quirks = &rt_i2c_quirks;
-+
-+ platform_set_drvdata(pdev, i2c);
-+
-+ restart = rt_i2c_init(i2c);
-+
-+ ret = i2c_add_adapter(adap);
-+ if (ret < 0) {
-+ dev_err(&pdev->dev, "failed to add adapter\n");
-+ clk_disable_unprepare(i2c->clk);
-+ return ret;
-+ }
-+
-+ dev_info(&pdev->dev, "clock %uKHz, re-start %ssupport\n",
-+ i2c->cur_clk/1000, restart ? "" : "not ");
-+
-+ return ret;
-+}
-+
-+static int rt_i2c_remove(struct platform_device *pdev)
-+{
-+ struct rt_i2c *i2c = platform_get_drvdata(pdev);
-+
-+ i2c_del_adapter(&i2c->adap);
-+ clk_disable_unprepare(i2c->clk);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver rt_i2c_driver = {
-+ .probe = rt_i2c_probe,
-+ .remove = rt_i2c_remove,
-+ .driver = {
-+ .owner = THIS_MODULE,
-+ .name = "i2c-ralink",
-+ .of_match_table = i2c_rt_dt_ids,
-+ },
-+};
-+
-+static int __init i2c_rt_init (void)
-+{
-+ return platform_driver_register(&rt_i2c_driver);
-+}
-+subsys_initcall(i2c_rt_init);
-+
-+static void __exit i2c_rt_exit (void)
-+{
-+ platform_driver_unregister(&rt_i2c_driver);
-+}
-+module_exit(i2c_rt_exit);
-+
-+MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>");
-+MODULE_DESCRIPTION("Ralink I2c host driver");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:Ralink-I2C");
+++ /dev/null
-From 23147af14531cbdada194b94120ef8774f46292d Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 13 Nov 2014 19:08:40 +0100
-Subject: [PATCH 46/53] mmc: MIPS: ralink: add sdhci for mt7620a SoC
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/mmc/host/Kconfig | 2 +
- drivers/mmc/host/Makefile | 1 +
- drivers/mmc/host/mtk-mmc/Kconfig | 16 +
- drivers/mmc/host/mtk-mmc/Makefile | 42 +
- drivers/mmc/host/mtk-mmc/board.h | 137 ++
- drivers/mmc/host/mtk-mmc/dbg.c | 347 ++++
- drivers/mmc/host/mtk-mmc/dbg.h | 156 ++
- drivers/mmc/host/mtk-mmc/mt6575_sd.h | 1001 +++++++++++
- drivers/mmc/host/mtk-mmc/sd.c | 3060 ++++++++++++++++++++++++++++++++++
- 9 files changed, 4762 insertions(+)
- create mode 100644 drivers/mmc/host/mtk-mmc/Kconfig
- create mode 100644 drivers/mmc/host/mtk-mmc/Makefile
- create mode 100644 drivers/mmc/host/mtk-mmc/board.h
- create mode 100644 drivers/mmc/host/mtk-mmc/dbg.c
- create mode 100644 drivers/mmc/host/mtk-mmc/dbg.h
- create mode 100644 drivers/mmc/host/mtk-mmc/mt6575_sd.h
- create mode 100644 drivers/mmc/host/mtk-mmc/sd.c
-
---- a/drivers/mmc/host/Kconfig
-+++ b/drivers/mmc/host/Kconfig
-@@ -1019,3 +1019,5 @@ config MMC_SDHCI_AM654
- If you have a controller with this interface, say Y or M here.
-
- If unsure, say N.
-+
-+source "drivers/mmc/host/mtk-mmc/Kconfig"
---- a/drivers/mmc/host/Makefile
-+++ b/drivers/mmc/host/Makefile
-@@ -3,6 +3,7 @@
- # Makefile for MMC/SD host controller drivers
- #
-
-+obj-$(CONFIG_MTK_MMC) += mtk-mmc/
- obj-$(CONFIG_MMC_ARMMMCI) += armmmci.o
- armmmci-y := mmci.o
- armmmci-$(CONFIG_MMC_QCOM_DML) += mmci_qcom_dml.o
+++ /dev/null
-From 7f29222b1731e8182ba94a331531dec18865a1e4 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 27 Jul 2014 09:31:47 +0100
-Subject: [PATCH 48/53] asoc: add mt7620 support
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/ralink/of.c | 2 +
- sound/soc/Kconfig | 1 +
- sound/soc/Makefile | 1 +
- sound/soc/ralink/Kconfig | 15 ++
- sound/soc/ralink/Makefile | 11 +
- sound/soc/ralink/mt7620-i2s.c | 436 ++++++++++++++++++++++++++++++++++++++
- sound/soc/ralink/mt7620-wm8960.c | 233 ++++++++++++++++++++
- 7 files changed, 699 insertions(+)
- create mode 100644 sound/soc/ralink/Kconfig
- create mode 100644 sound/soc/ralink/Makefile
- create mode 100644 sound/soc/ralink/mt7620-i2s.c
- create mode 100644 sound/soc/ralink/mt7620-wm8960.c
-
---- a/sound/soc/Kconfig
-+++ b/sound/soc/Kconfig
-@@ -60,6 +60,7 @@ source "sound/soc/mxs/Kconfig"
- source "sound/soc/pxa/Kconfig"
- source "sound/soc/qcom/Kconfig"
- source "sound/soc/rockchip/Kconfig"
-+source "sound/soc/ralink/Kconfig"
- source "sound/soc/samsung/Kconfig"
- source "sound/soc/sh/Kconfig"
- source "sound/soc/sirf/Kconfig"
---- a/sound/soc/Makefile
-+++ b/sound/soc/Makefile
-@@ -43,6 +43,7 @@ obj-$(CONFIG_SND_SOC) += kirkwood/
- obj-$(CONFIG_SND_SOC) += pxa/
- obj-$(CONFIG_SND_SOC) += qcom/
- obj-$(CONFIG_SND_SOC) += rockchip/
-+obj-$(CONFIG_SND_SOC) += ralink/
- obj-$(CONFIG_SND_SOC) += samsung/
- obj-$(CONFIG_SND_SOC) += sh/
- obj-$(CONFIG_SND_SOC) += sirf/
---- /dev/null
-+++ b/sound/soc/ralink/Kconfig
-@@ -0,0 +1,8 @@
-+config SND_RALINK_SOC_I2S
-+ depends on RALINK && SND_SOC && !SOC_RT288X
-+ select SND_SOC_GENERIC_DMAENGINE_PCM
-+ select REGMAP_MMIO
-+ tristate "SoC Audio (I2S protocol) for Ralink SoC"
-+ help
-+ Say Y if you want to use I2S protocol and I2S codec on Ralink/MediaTek
-+ based boards.
---- /dev/null
-+++ b/sound/soc/ralink/Makefile
-@@ -0,0 +1,6 @@
-+#
-+# Ralink/MediaTek Platform Support
-+#
-+snd-soc-ralink-i2s-objs := ralink-i2s.o
-+
-+obj-$(CONFIG_SND_RALINK_SOC_I2S) += snd-soc-ralink-i2s.o
---- /dev/null
-+++ b/sound/soc/ralink/ralink-i2s.c
-@@ -0,0 +1,965 @@
-+/*
-+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
-+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/clk.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/debugfs.h>
-+#include <linux/of_device.h>
-+#include <sound/pcm_params.h>
-+#include <sound/dmaengine_pcm.h>
-+
-+#include <asm/mach-ralink/ralink_regs.h>
-+
-+#define DRV_NAME "ralink-i2s"
-+
-+#define I2S_REG_CFG0 0x00
-+#define I2S_REG_INT_STATUS 0x04
-+#define I2S_REG_INT_EN 0x08
-+#define I2S_REG_FF_STATUS 0x0c
-+#define I2S_REG_WREG 0x10
-+#define I2S_REG_RREG 0x14
-+#define I2S_REG_CFG1 0x18
-+#define I2S_REG_DIVCMP 0x20
-+#define I2S_REG_DIVINT 0x24
-+
-+/* I2S_REG_CFG0 */
-+#define I2S_REG_CFG0_EN BIT(31)
-+#define I2S_REG_CFG0_DMA_EN BIT(30)
-+#define I2S_REG_CFG0_BYTE_SWAP BIT(28)
-+#define I2S_REG_CFG0_TX_EN BIT(24)
-+#define I2S_REG_CFG0_RX_EN BIT(20)
-+#define I2S_REG_CFG0_SLAVE BIT(16)
-+#define I2S_REG_CFG0_RX_THRES 12
-+#define I2S_REG_CFG0_TX_THRES 4
-+#define I2S_REG_CFG0_THRES_MASK (0xf << I2S_REG_CFG0_RX_THRES) | \
-+ (4 << I2S_REG_CFG0_TX_THRES)
-+#define I2S_REG_CFG0_DFT_THRES (4 << I2S_REG_CFG0_RX_THRES) | \
-+ (4 << I2S_REG_CFG0_TX_THRES)
-+/* RT305x */
-+#define I2S_REG_CFG0_CLK_DIS BIT(8)
-+#define I2S_REG_CFG0_TXCH_SWAP BIT(3)
-+#define I2S_REG_CFG0_TXCH1_OFF BIT(2)
-+#define I2S_REG_CFG0_TXCH0_OFF BIT(1)
-+#define I2S_REG_CFG0_SLAVE_EN BIT(0)
-+/* RT3883 */
-+#define I2S_REG_CFG0_RXCH_SWAP BIT(11)
-+#define I2S_REG_CFG0_RXCH1_OFF BIT(10)
-+#define I2S_REG_CFG0_RXCH0_OFF BIT(9)
-+#define I2S_REG_CFG0_WS_INV BIT(0)
-+/* MT7628 */
-+#define I2S_REG_CFG0_FMT_LE BIT(29)
-+#define I2S_REG_CFG0_SYS_BE BIT(28)
-+#define I2S_REG_CFG0_NORM_24 BIT(18)
-+#define I2S_REG_CFG0_DATA_24 BIT(17)
-+
-+/* I2S_REG_INT_STATUS */
-+#define I2S_REG_INT_RX_FAULT BIT(7)
-+#define I2S_REG_INT_RX_OVRUN BIT(6)
-+#define I2S_REG_INT_RX_UNRUN BIT(5)
-+#define I2S_REG_INT_RX_THRES BIT(4)
-+#define I2S_REG_INT_TX_FAULT BIT(3)
-+#define I2S_REG_INT_TX_OVRUN BIT(2)
-+#define I2S_REG_INT_TX_UNRUN BIT(1)
-+#define I2S_REG_INT_TX_THRES BIT(0)
-+#define I2S_REG_INT_TX_MASK 0xf
-+#define I2S_REG_INT_RX_MASK 0xf0
-+
-+/* I2S_REG_INT_STATUS */
-+#define I2S_RX_AVCNT(x) ((x >> 4) & 0xf)
-+#define I2S_TX_AVCNT(x) (x & 0xf)
-+/* MT7628 */
-+#define MT7628_I2S_RX_AVCNT(x) ((x >> 8) & 0x1f)
-+#define MT7628_I2S_TX_AVCNT(x) (x & 0x1f)
-+
-+/* I2S_REG_CFG1 */
-+#define I2S_REG_CFG1_LBK BIT(31)
-+#define I2S_REG_CFG1_EXTLBK BIT(30)
-+/* RT3883 */
-+#define I2S_REG_CFG1_LEFT_J BIT(0)
-+#define I2S_REG_CFG1_RIGHT_J BIT(1)
-+#define I2S_REG_CFG1_FMT_MASK 0x3
-+
-+/* I2S_REG_DIVCMP */
-+#define I2S_REG_DIVCMP_CLKEN BIT(31)
-+#define I2S_REG_DIVCMP_DIVCOMP_MASK 0x1ff
-+
-+/* I2S_REG_DIVINT */
-+#define I2S_REG_DIVINT_MASK 0x3ff
-+
-+/* BCLK dividers */
-+#define RALINK_I2S_DIVCMP 0
-+#define RALINK_I2S_DIVINT 1
-+
-+/* FIFO */
-+#define RALINK_I2S_FIFO_SIZE 32
-+
-+/* feature flags */
-+#define RALINK_FLAGS_TXONLY BIT(0)
-+#define RALINK_FLAGS_LEFT_J BIT(1)
-+#define RALINK_FLAGS_RIGHT_J BIT(2)
-+#define RALINK_FLAGS_ENDIAN BIT(3)
-+#define RALINK_FLAGS_24BIT BIT(4)
-+
-+#define RALINK_I2S_INT_EN 0
-+
-+struct ralink_i2s_stats {
-+ u32 dmafault;
-+ u32 overrun;
-+ u32 underrun;
-+ u32 belowthres;
-+};
-+
-+struct ralink_i2s {
-+ struct device *dev;
-+ void __iomem *regs;
-+ struct clk *clk;
-+ struct regmap *regmap;
-+ u32 flags;
-+ unsigned int fmt;
-+ u16 txdma_req;
-+ u16 rxdma_req;
-+
-+ struct snd_dmaengine_dai_dma_data playback_dma_data;
-+ struct snd_dmaengine_dai_dma_data capture_dma_data;
-+
-+ struct dentry *dbg_dir;
-+ struct dentry *dbg_stats;
-+ struct ralink_i2s_stats txstats;
-+ struct ralink_i2s_stats rxstats;
-+};
-+
-+static void ralink_i2s_dump_regs(struct ralink_i2s *i2s)
-+{
-+ u32 buf[10];
-+ int ret;
-+
-+ ret = regmap_bulk_read(i2s->regmap, I2S_REG_CFG0,
-+ buf, ARRAY_SIZE(buf));
-+
-+ dev_dbg(i2s->dev, "CFG0: %08x, INTSTAT: %08x, INTEN: %08x, " \
-+ "FFSTAT: %08x, WREG: %08x, RREG: %08x, " \
-+ "CFG1: %08x, DIVCMP: %08x, DIVINT: %08x\n",
-+ buf[0], buf[1], buf[2], buf[3], buf[4],
-+ buf[5], buf[6], buf[8], buf[9]);
-+}
-+
-+static int ralink_i2s_set_sysclk(struct snd_soc_dai *dai,
-+ int clk_id, unsigned int freq, int dir)
-+{
-+ return 0;
-+}
-+
-+static int ralink_i2s_set_sys_bclk(struct snd_soc_dai *dai, int width, int rate)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ unsigned long clk = clk_get_rate(i2s->clk);
-+ int div;
-+ uint32_t data;
-+
-+ /* disable clock at slave mode */
-+ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
-+ SND_SOC_DAIFMT_CBM_CFM) {
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_CLK_DIS,
-+ I2S_REG_CFG0_CLK_DIS);
-+ return 0;
-+ }
-+
-+ /* FREQOUT = FREQIN / (I2S_CLK_DIV + 1) */
-+ div = (clk / rate ) - 1;
-+
-+ data = rt_sysc_r32(0x30);
-+ data &= (0xff << 8);
-+ data |= (0x1 << 15) | (div << 8);
-+ rt_sysc_w32(data, 0x30);
-+
-+ /* enable clock */
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_CLK_DIS, 0);
-+
-+ dev_dbg(i2s->dev, "clk: %lu, rate: %u, div: %d\n",
-+ clk, rate, div);
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_set_bclk(struct snd_soc_dai *dai, int width, int rate)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ unsigned long clk = clk_get_rate(i2s->clk);
-+ int divint, divcomp;
-+
-+ /* disable clock at slave mode */
-+ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
-+ SND_SOC_DAIFMT_CBM_CFM) {
-+ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP,
-+ I2S_REG_DIVCMP_CLKEN, 0);
-+ return 0;
-+ }
-+
-+ /* FREQOUT = FREQIN * (1/2) * (1/(DIVINT + DIVCOMP/512)) */
-+ clk = clk / (2 * 2 * width);
-+ divint = clk / rate;
-+ divcomp = ((clk % rate) * 512) / rate;
-+
-+ if ((divint > I2S_REG_DIVINT_MASK) ||
-+ (divcomp > I2S_REG_DIVCMP_DIVCOMP_MASK))
-+ return -EINVAL;
-+
-+ regmap_update_bits(i2s->regmap, I2S_REG_DIVINT,
-+ I2S_REG_DIVINT_MASK, divint);
-+ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP,
-+ I2S_REG_DIVCMP_DIVCOMP_MASK, divcomp);
-+
-+ /* enable clock */
-+ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, I2S_REG_DIVCMP_CLKEN,
-+ I2S_REG_DIVCMP_CLKEN);
-+
-+ dev_dbg(i2s->dev, "clk: %lu, rate: %u, int: %d, comp: %d\n",
-+ clk_get_rate(i2s->clk), rate, divint, divcomp);
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ unsigned int cfg0 = 0, cfg1 = 0;
-+
-+ /* set master/slave audio interface */
-+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-+ case SND_SOC_DAIFMT_CBM_CFM:
-+ if (i2s->flags & RALINK_FLAGS_TXONLY)
-+ cfg0 |= I2S_REG_CFG0_SLAVE_EN;
-+ else
-+ cfg0 |= I2S_REG_CFG0_SLAVE;
-+ break;
-+ case SND_SOC_DAIFMT_CBS_CFS:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ /* interface format */
-+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-+ case SND_SOC_DAIFMT_I2S:
-+ break;
-+ case SND_SOC_DAIFMT_RIGHT_J:
-+ if (i2s->flags & RALINK_FLAGS_RIGHT_J) {
-+ cfg1 |= I2S_REG_CFG1_RIGHT_J;
-+ break;
-+ }
-+ return -EINVAL;
-+ case SND_SOC_DAIFMT_LEFT_J:
-+ if (i2s->flags & RALINK_FLAGS_LEFT_J) {
-+ cfg1 |= I2S_REG_CFG1_LEFT_J;
-+ break;
-+ }
-+ return -EINVAL;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ /* clock inversion */
-+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
-+ case SND_SOC_DAIFMT_NB_NF:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (i2s->flags & RALINK_FLAGS_TXONLY) {
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_SLAVE_EN, cfg0);
-+ } else {
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_SLAVE, cfg0);
-+ }
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG1,
-+ I2S_REG_CFG1_FMT_MASK, cfg1);
-+ i2s->fmt = fmt;
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_startup(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+
-+ if (dai->active)
-+ return 0;
-+
-+ /* setup status interrupt */
-+#if (RALINK_I2S_INT_EN)
-+ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0xff);
-+#else
-+ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0x0);
-+#endif
-+
-+ /* enable */
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN |
-+ I2S_REG_CFG0_THRES_MASK,
-+ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN |
-+ I2S_REG_CFG0_DFT_THRES);
-+
-+ return 0;
-+}
-+
-+static void ralink_i2s_shutdown(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+
-+ /* If both streams are stopped, disable module and clock */
-+ if (dai->active)
-+ return;
-+
-+ /*
-+ * datasheet mention when disable all control regs are cleared
-+ * to initial values. need reinit at startup.
-+ */
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_EN, 0);
-+}
-+
-+static int ralink_i2s_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ int width;
-+ int ret;
-+
-+ width = params_width(params);
-+ switch (width) {
-+ case 16:
-+ if (i2s->flags & RALINK_FLAGS_24BIT)
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_DATA_24, 0);
-+ break;
-+ case 24:
-+ if (i2s->flags & RALINK_FLAGS_24BIT) {
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_DATA_24,
-+ I2S_REG_CFG0_DATA_24);
-+ break;
-+ }
-+ return -EINVAL;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ switch (params_channels(params)) {
-+ case 2:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (i2s->flags & RALINK_FLAGS_ENDIAN) {
-+ /* system endian */
-+#ifdef SNDRV_LITTLE_ENDIAN
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_SYS_BE, 0);
-+#else
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_SYS_BE,
-+ I2S_REG_CFG0_SYS_BE);
-+#endif
-+
-+ /* data endian */
-+ switch (params_format(params)) {
-+ case SNDRV_PCM_FORMAT_S16_LE:
-+ case SNDRV_PCM_FORMAT_S24_LE:
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_FMT_LE,
-+ I2S_REG_CFG0_FMT_LE);
-+ break;
-+ case SNDRV_PCM_FORMAT_S16_BE:
-+ case SNDRV_PCM_FORMAT_S24_BE:
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
-+ I2S_REG_CFG0_FMT_LE, 0);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ }
-+
-+ /* setup bclk rate */
-+ if (i2s->flags & RALINK_FLAGS_TXONLY)
-+ ret = ralink_i2s_set_sys_bclk(dai, width, params_rate(params));
-+ else
-+ ret = ralink_i2s_set_bclk(dai, width, params_rate(params));
-+
-+ return ret;
-+}
-+
-+static int ralink_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
-+ struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+ unsigned int mask, val;
-+
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-+ mask = I2S_REG_CFG0_TX_EN;
-+ else
-+ mask = I2S_REG_CFG0_RX_EN;
-+
-+ switch (cmd) {
-+ case SNDRV_PCM_TRIGGER_START:
-+ case SNDRV_PCM_TRIGGER_RESUME:
-+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-+ val = mask;
-+ break;
-+ case SNDRV_PCM_TRIGGER_STOP:
-+ case SNDRV_PCM_TRIGGER_SUSPEND:
-+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-+ val = 0;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, mask, val);
-+
-+ return 0;
-+}
-+
-+static void ralink_i2s_init_dma_data(struct ralink_i2s *i2s,
-+ struct resource *res)
-+{
-+ struct snd_dmaengine_dai_dma_data *dma_data;
-+
-+ /* Playback */
-+ dma_data = &i2s->playback_dma_data;
-+ dma_data->addr = res->start + I2S_REG_WREG;
-+ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-+ dma_data->maxburst = 1;
-+ dma_data->slave_id = i2s->txdma_req;
-+
-+ if (i2s->flags & RALINK_FLAGS_TXONLY)
-+ return;
-+
-+ /* Capture */
-+ dma_data = &i2s->capture_dma_data;
-+ dma_data->addr = res->start + I2S_REG_RREG;
-+ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-+ dma_data->maxburst = 1;
-+ dma_data->slave_id = i2s->rxdma_req;
-+}
-+
-+static int ralink_i2s_dai_probe(struct snd_soc_dai *dai)
-+{
-+ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-+
-+ snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
-+ &i2s->capture_dma_data);
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_dai_remove(struct snd_soc_dai *dai)
-+{
-+ return 0;
-+}
-+
-+static const struct snd_soc_dai_ops ralink_i2s_dai_ops = {
-+ .set_sysclk = ralink_i2s_set_sysclk,
-+ .set_fmt = ralink_i2s_set_fmt,
-+ .startup = ralink_i2s_startup,
-+ .shutdown = ralink_i2s_shutdown,
-+ .hw_params = ralink_i2s_hw_params,
-+ .trigger = ralink_i2s_trigger,
-+};
-+
-+static struct snd_soc_dai_driver ralink_i2s_dai = {
-+ .name = DRV_NAME,
-+ .probe = ralink_i2s_dai_probe,
-+ .remove = ralink_i2s_dai_remove,
-+ .ops = &ralink_i2s_dai_ops,
-+ .capture = {
-+ .stream_name = "I2S Capture",
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .rate_min = 5512,
-+ .rate_max = 192000,
-+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
-+ },
-+ .playback = {
-+ .stream_name = "I2S Playback",
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .rate_min = 5512,
-+ .rate_max = 192000,
-+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
-+ },
-+ .symmetric_rates = 1,
-+};
-+
-+static struct snd_pcm_hardware ralink_pcm_hardware = {
-+ .info = SNDRV_PCM_INFO_MMAP |
-+ SNDRV_PCM_INFO_MMAP_VALID |
-+ SNDRV_PCM_INFO_INTERLEAVED |
-+ SNDRV_PCM_INFO_BLOCK_TRANSFER,
-+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
-+ .channels_min = 2,
-+ .channels_max = 2,
-+ .period_bytes_min = PAGE_SIZE,
-+ .period_bytes_max = PAGE_SIZE * 2,
-+ .periods_min = 2,
-+ .periods_max = 128,
-+ .buffer_bytes_max = 128 * 1024,
-+ .fifo_size = RALINK_I2S_FIFO_SIZE,
-+};
-+
-+static const struct snd_dmaengine_pcm_config ralink_dmaengine_pcm_config = {
-+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-+ .pcm_hardware = &ralink_pcm_hardware,
-+ .prealloc_buffer_size = 256 * PAGE_SIZE,
-+};
-+
-+static const struct snd_soc_component_driver ralink_i2s_component = {
-+ .name = DRV_NAME,
-+};
-+
-+static bool ralink_i2s_readable_reg(struct device *dev, unsigned int reg)
-+{
-+ return true;
-+}
-+
-+static bool ralink_i2s_volatile_reg(struct device *dev, unsigned int reg)
-+{
-+ switch (reg) {
-+ case I2S_REG_INT_STATUS:
-+ case I2S_REG_FF_STATUS:
-+ return true;
-+ }
-+ return false;
-+}
-+
-+static bool ralink_i2s_writeable_reg(struct device *dev, unsigned int reg)
-+{
-+ switch (reg) {
-+ case I2S_REG_FF_STATUS:
-+ case I2S_REG_RREG:
-+ return false;
-+ }
-+ return true;
-+}
-+
-+static const struct regmap_config ralink_i2s_regmap_config = {
-+ .reg_bits = 32,
-+ .reg_stride = 4,
-+ .val_bits = 32,
-+ .writeable_reg = ralink_i2s_writeable_reg,
-+ .readable_reg = ralink_i2s_readable_reg,
-+ .volatile_reg = ralink_i2s_volatile_reg,
-+ .max_register = I2S_REG_DIVINT,
-+};
-+
-+#if (RALINK_I2S_INT_EN)
-+static irqreturn_t ralink_i2s_irq(int irq, void *devid)
-+{
-+ struct ralink_i2s *i2s = devid;
-+ u32 status;
-+
-+ regmap_read(i2s->regmap, I2S_REG_INT_STATUS, &status);
-+ if (unlikely(!status))
-+ return IRQ_NONE;
-+
-+ /* tx stats */
-+ if (status & I2S_REG_INT_TX_MASK) {
-+ if (status & I2S_REG_INT_TX_THRES)
-+ i2s->txstats.belowthres++;
-+ if (status & I2S_REG_INT_TX_UNRUN)
-+ i2s->txstats.underrun++;
-+ if (status & I2S_REG_INT_TX_OVRUN)
-+ i2s->txstats.overrun++;
-+ if (status & I2S_REG_INT_TX_FAULT)
-+ i2s->txstats.dmafault++;
-+ }
-+
-+ /* rx stats */
-+ if (status & I2S_REG_INT_RX_MASK) {
-+ if (status & I2S_REG_INT_RX_THRES)
-+ i2s->rxstats.belowthres++;
-+ if (status & I2S_REG_INT_RX_UNRUN)
-+ i2s->rxstats.underrun++;
-+ if (status & I2S_REG_INT_RX_OVRUN)
-+ i2s->rxstats.overrun++;
-+ if (status & I2S_REG_INT_RX_FAULT)
-+ i2s->rxstats.dmafault++;
-+ }
-+
-+ /* clean status bits */
-+ regmap_write(i2s->regmap, I2S_REG_INT_STATUS, status);
-+
-+ return IRQ_HANDLED;
-+}
-+#endif
-+
-+#if IS_ENABLED(CONFIG_DEBUG_FS)
-+static int ralink_i2s_stats_show(struct seq_file *s, void *unused)
-+{
-+ struct ralink_i2s *i2s = s->private;
-+
-+ seq_printf(s, "tx stats\n");
-+ seq_printf(s, "\tbelow threshold\t%u\n", i2s->txstats.belowthres);
-+ seq_printf(s, "\tunder run\t%u\n", i2s->txstats.underrun);
-+ seq_printf(s, "\tover run\t%u\n", i2s->txstats.overrun);
-+ seq_printf(s, "\tdma fault\t%u\n", i2s->txstats.dmafault);
-+
-+ seq_printf(s, "rx stats\n");
-+ seq_printf(s, "\tbelow threshold\t%u\n", i2s->rxstats.belowthres);
-+ seq_printf(s, "\tunder run\t%u\n", i2s->rxstats.underrun);
-+ seq_printf(s, "\tover run\t%u\n", i2s->rxstats.overrun);
-+ seq_printf(s, "\tdma fault\t%u\n", i2s->rxstats.dmafault);
-+
-+ ralink_i2s_dump_regs(i2s);
-+
-+ return 0;
-+}
-+
-+static int ralink_i2s_stats_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, ralink_i2s_stats_show, inode->i_private);
-+}
-+
-+static const struct file_operations ralink_i2s_stats_ops = {
-+ .open = ralink_i2s_stats_open,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+ .release = single_release,
-+};
-+
-+static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s)
-+{
-+ i2s->dbg_dir = debugfs_create_dir(dev_name(i2s->dev), NULL);
-+ if (!i2s->dbg_dir)
-+ return -ENOMEM;
-+
-+ i2s->dbg_stats = debugfs_create_file("stats", S_IRUGO,
-+ i2s->dbg_dir, i2s, &ralink_i2s_stats_ops);
-+ if (!i2s->dbg_stats) {
-+ debugfs_remove(i2s->dbg_dir);
-+ return -ENOMEM;
-+ }
-+
-+ return 0;
-+}
-+
-+static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s)
-+{
-+ debugfs_remove(i2s->dbg_stats);
-+ debugfs_remove(i2s->dbg_dir);
-+}
-+#else
-+static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s)
-+{
-+ return 0;
-+}
-+
-+static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s)
-+{
-+}
-+#endif
-+
-+/*
-+ * TODO: these refclk setup functions should use
-+ * clock framework instead. hardcode it now.
-+ */
-+static void rt3350_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data |= (0x1 << 8);
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void rt3883_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0x3 << 13);
-+ data |= (0x1 << 13);
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void rt3552_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0xf << 8);
-+ data |= (0x3 << 8);
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void mt7620_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0x7 << 9);
-+ data |= 0x1 << 9;
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void mt7621_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0x1f << 18);
-+ data |= (0x19 << 18);
-+ data &= ~(0x1f << 12);
-+ data |= (0x1 << 12);
-+ data &= ~(0x7 << 9);
-+ data |= (0x5 << 9);
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+static void mt7628_refclk_setup(void)
-+{
-+ uint32_t data;
-+
-+ /* set i2s and refclk digital pad */
-+ data = rt_sysc_r32(0x3c);
-+ data |= 0x1f;
-+ rt_sysc_w32(data, 0x3c);
-+
-+ /* Adjust REFCLK0's driving strength */
-+ data = rt_sysc_r32(0x1354);
-+ data &= ~(0x1 << 5);
-+ rt_sysc_w32(data, 0x1354);
-+ data = rt_sysc_r32(0x1364);
-+ data |= ~(0x1 << 5);
-+ rt_sysc_w32(data, 0x1364);
-+
-+ /* set refclk output 12Mhz clock */
-+ data = rt_sysc_r32(0x2c);
-+ data &= ~(0x7 << 9);
-+ data |= 0x1 << 9;
-+ rt_sysc_w32(data, 0x2c);
-+}
-+
-+struct rt_i2s_data {
-+ u32 flags;
-+ void (*refclk_setup)(void);
-+};
-+
-+struct rt_i2s_data rt3050_i2s_data = { .flags = RALINK_FLAGS_TXONLY };
-+struct rt_i2s_data rt3350_i2s_data = { .flags = RALINK_FLAGS_TXONLY,
-+ .refclk_setup = rt3350_refclk_setup };
-+struct rt_i2s_data rt3883_i2s_data = {
-+ .flags = (RALINK_FLAGS_LEFT_J | RALINK_FLAGS_RIGHT_J),
-+ .refclk_setup = rt3883_refclk_setup };
-+struct rt_i2s_data rt3352_i2s_data = { .refclk_setup = rt3552_refclk_setup};
-+struct rt_i2s_data mt7620_i2s_data = { .refclk_setup = mt7620_refclk_setup};
-+struct rt_i2s_data mt7621_i2s_data = { .refclk_setup = mt7621_refclk_setup};
-+struct rt_i2s_data mt7628_i2s_data = {
-+ .flags = (RALINK_FLAGS_ENDIAN | RALINK_FLAGS_24BIT |
-+ RALINK_FLAGS_LEFT_J),
-+ .refclk_setup = mt7628_refclk_setup};
-+
-+static const struct of_device_id ralink_i2s_match_table[] = {
-+ { .compatible = "ralink,rt3050-i2s",
-+ .data = (void *)&rt3050_i2s_data },
-+ { .compatible = "ralink,rt3350-i2s",
-+ .data = (void *)&rt3350_i2s_data },
-+ { .compatible = "ralink,rt3883-i2s",
-+ .data = (void *)&rt3883_i2s_data },
-+ { .compatible = "ralink,rt3352-i2s",
-+ .data = (void *)&rt3352_i2s_data },
-+ { .compatible = "mediatek,mt7620-i2s",
-+ .data = (void *)&mt7620_i2s_data },
-+ { .compatible = "mediatek,mt7621-i2s",
-+ .data = (void *)&mt7621_i2s_data },
-+ { .compatible = "mediatek,mt7628-i2s",
-+ .data = (void *)&mt7628_i2s_data },
-+};
-+MODULE_DEVICE_TABLE(of, ralink_i2s_match_table);
-+
-+static int ralink_i2s_probe(struct platform_device *pdev)
-+{
-+ const struct of_device_id *match;
-+ struct device_node *np = pdev->dev.of_node;
-+ struct ralink_i2s *i2s;
-+ struct resource *res;
-+ int irq, ret;
-+ u32 dma_req;
-+ struct rt_i2s_data *data;
-+
-+ i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
-+ if (!i2s)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, i2s);
-+ i2s->dev = &pdev->dev;
-+
-+ match = of_match_device(ralink_i2s_match_table, &pdev->dev);
-+ if (!match)
-+ return -EINVAL;
-+ data = (struct rt_i2s_data *)match->data;
-+ i2s->flags = data->flags;
-+ /* setup out 12Mhz refclk to codec as mclk */
-+ if (data->refclk_setup)
-+ data->refclk_setup();
-+
-+ if (of_property_read_u32(np, "txdma-req", &dma_req)) {
-+ dev_err(&pdev->dev, "no txdma-req define\n");
-+ return -EINVAL;
-+ }
-+ i2s->txdma_req = (u16)dma_req;
-+ if (!(i2s->flags & RALINK_FLAGS_TXONLY)) {
-+ if (of_property_read_u32(np, "rxdma-req", &dma_req)) {
-+ dev_err(&pdev->dev, "no rxdma-req define\n");
-+ return -EINVAL;
-+ }
-+ i2s->rxdma_req = (u16)dma_req;
-+ }
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ i2s->regs = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(i2s->regs))
-+ return PTR_ERR(i2s->regs);
-+
-+ i2s->regmap = devm_regmap_init_mmio(&pdev->dev, i2s->regs,
-+ &ralink_i2s_regmap_config);
-+ if (IS_ERR(i2s->regmap)) {
-+ dev_err(&pdev->dev, "regmap init failed\n");
-+ return PTR_ERR(i2s->regmap);
-+ }
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0) {
-+ dev_err(&pdev->dev, "failed to get irq\n");
-+ return -EINVAL;
-+ }
-+
-+#if (RALINK_I2S_INT_EN)
-+ ret = devm_request_irq(&pdev->dev, irq, ralink_i2s_irq,
-+ 0, dev_name(&pdev->dev), i2s);
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to request irq\n");
-+ return ret;
-+ }
-+#endif
-+
-+ i2s->clk = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(i2s->clk)) {
-+ dev_err(&pdev->dev, "no clock defined\n");
-+ return PTR_ERR(i2s->clk);
-+ }
-+
-+ ret = clk_prepare_enable(i2s->clk);
-+ if (ret)
-+ return ret;
-+
-+ ralink_i2s_init_dma_data(i2s, res);
-+
-+ device_reset(&pdev->dev);
-+
-+ ret = ralink_i2s_debugfs_create(i2s);
-+ if (ret) {
-+ dev_err(&pdev->dev, "create debugfs failed\n");
-+ goto err_clk_disable;
-+ }
-+
-+ /* enable 24bits support */
-+ if (i2s->flags & RALINK_FLAGS_24BIT) {
-+ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S24_LE;
-+ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S24_LE;
-+ }
-+
-+ /* enable big endian support */
-+ if (i2s->flags & RALINK_FLAGS_ENDIAN) {
-+ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S16_BE;
-+ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S16_BE;
-+ ralink_pcm_hardware.formats |= SNDRV_PCM_FMTBIT_S16_BE;
-+ if (i2s->flags & RALINK_FLAGS_24BIT) {
-+ ralink_i2s_dai.capture.formats |=
-+ SNDRV_PCM_FMTBIT_S24_BE;
-+ ralink_i2s_dai.playback.formats |=
-+ SNDRV_PCM_FMTBIT_S24_BE;
-+ ralink_pcm_hardware.formats |=
-+ SNDRV_PCM_FMTBIT_S24_BE;
-+ }
-+ }
-+
-+ /* disable capture support */
-+ if (i2s->flags & RALINK_FLAGS_TXONLY)
-+ memset(&ralink_i2s_dai.capture, sizeof(ralink_i2s_dai.capture),
-+ 0);
-+
-+ ret = devm_snd_soc_register_component(&pdev->dev, &ralink_i2s_component,
-+ &ralink_i2s_dai, 1);
-+ if (ret)
-+ goto err_debugfs;
-+
-+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
-+ &ralink_dmaengine_pcm_config,
-+ SND_DMAENGINE_PCM_FLAG_COMPAT);
-+ if (ret)
-+ goto err_debugfs;
-+
-+ dev_info(i2s->dev, "mclk %luMHz\n", clk_get_rate(i2s->clk) / 1000000);
-+
-+ return 0;
-+
-+err_debugfs:
-+ ralink_i2s_debugfs_remove(i2s);
-+
-+err_clk_disable:
-+ clk_disable_unprepare(i2s->clk);
-+
-+ return ret;
-+}
-+
-+static int ralink_i2s_remove(struct platform_device *pdev)
-+{
-+ struct ralink_i2s *i2s = platform_get_drvdata(pdev);
-+
-+ ralink_i2s_debugfs_remove(i2s);
-+ clk_disable_unprepare(i2s->clk);
-+
-+ return 0;
-+}
-+
-+static struct platform_driver ralink_i2s_driver = {
-+ .probe = ralink_i2s_probe,
-+ .remove = ralink_i2s_remove,
-+ .driver = {
-+ .name = DRV_NAME,
-+ .of_match_table = ralink_i2s_match_table,
-+ },
-+};
-+module_platform_driver(ralink_i2s_driver);
-+
-+MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
-+MODULE_DESCRIPTION("Ralink/MediaTek I2S driver");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:" DRV_NAME);
+++ /dev/null
-From a7eb46e0ea4a11e4dfb56ab129bf816d1059a6c5 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 7 Dec 2015 17:31:08 +0100
-Subject: [PATCH 51/53] serial: add ugly custom baud rate hack
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/tty/serial/serial_core.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/tty/serial/serial_core.c
-+++ b/drivers/tty/serial/serial_core.c
-@@ -423,6 +423,9 @@ uart_get_baud_rate(struct uart_port *por
- break;
- }
-
-+ if (tty_termios_baud_rate(termios) == 2500000)
-+ return 250000;
-+
- for (try = 0; try < 2; try++) {
- baud = tty_termios_baud_rate(termios);
-
+++ /dev/null
-From fc8f96309c21c1bc3276427309cd7d361347d66e Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 7 Dec 2015 17:16:50 +0100
-Subject: [PATCH 52/53] pwm: add mediatek support
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/pwm/Kconfig | 9 +++
- drivers/pwm/Makefile | 1 +
- drivers/pwm/pwm-mediatek.c | 173 ++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 183 insertions(+)
- create mode 100644 drivers/pwm/pwm-mediatek.c
-
---- a/drivers/pwm/Kconfig
-+++ b/drivers/pwm/Kconfig
-@@ -316,6 +316,15 @@ config PWM_MEDIATEK
- To compile this driver as a module, choose M here: the module
- will be called pwm-mediatek.
-
-+config PWM_MEDIATEK_RAMIPS
-+ tristate "Mediatek PWM support"
-+ depends on RALINK && OF
-+ help
-+ Generic PWM framework driver for Mediatek ARM SoC.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called pwm-mxs.
-+
- config PWM_MXS
- tristate "Freescale MXS PWM support"
- depends on ARCH_MXS && OF
---- a/drivers/pwm/Makefile
-+++ b/drivers/pwm/Makefile
-@@ -29,6 +29,7 @@ obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-p
- obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
- obj-$(CONFIG_PWM_MESON) += pwm-meson.o
- obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o
-+obj-$(CONFIG_PWM_MEDIATEK_RAMIPS) += pwm-mediatek-ramips.o
- obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
- obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
- obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
---- /dev/null
-+++ b/drivers/pwm/pwm-mediatek-ramips.c
-@@ -0,0 +1,173 @@
-+/*
-+ * Mediatek Pulse Width Modulator driver
-+ *
-+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2. This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/ioport.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pwm.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+
-+#define NUM_PWM 4
-+
-+/* PWM registers and bits definitions */
-+#define PWMCON 0x00
-+#define PWMHDUR 0x04
-+#define PWMLDUR 0x08
-+#define PWMGDUR 0x0c
-+#define PWMWAVENUM 0x28
-+#define PWMDWIDTH 0x2c
-+#define PWMTHRES 0x30
-+
-+/**
-+ * struct mtk_pwm_chip - struct representing pwm chip
-+ *
-+ * @mmio_base: base address of pwm chip
-+ * @chip: linux pwm chip representation
-+ */
-+struct mtk_pwm_chip {
-+ void __iomem *mmio_base;
-+ struct pwm_chip chip;
-+};
-+
-+static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
-+{
-+ return container_of(chip, struct mtk_pwm_chip, chip);
-+}
-+
-+static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
-+ unsigned long offset)
-+{
-+ return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset);
-+}
-+
-+static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
-+ unsigned int num, unsigned long offset,
-+ unsigned long val)
-+{
-+ iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset);
-+}
-+
-+static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-+ int duty_ns, int period_ns)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 resolution = 100 / 4;
-+ u32 clkdiv = 0;
-+
-+ while (period_ns / resolution > 8191) {
-+ clkdiv++;
-+ resolution *= 2;
-+ }
-+
-+ if (clkdiv > 7)
-+ return -1;
-+
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv);
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);
-+ return 0;
-+}
-+
-+static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 val;
-+
-+ val = ioread32(pc->mmio_base);
-+ val |= BIT(pwm->hwpwm);
-+ iowrite32(val, pc->mmio_base);
-+
-+ return 0;
-+}
-+
-+static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 val;
-+
-+ val = ioread32(pc->mmio_base);
-+ val &= ~BIT(pwm->hwpwm);
-+ iowrite32(val, pc->mmio_base);
-+}
-+
-+static const struct pwm_ops mtk_pwm_ops = {
-+ .config = mtk_pwm_config,
-+ .enable = mtk_pwm_enable,
-+ .disable = mtk_pwm_disable,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int mtk_pwm_probe(struct platform_device *pdev)
-+{
-+ struct mtk_pwm_chip *pc;
-+ struct resource *r;
-+ int ret;
-+
-+ pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
-+ if (!pc)
-+ return -ENOMEM;
-+
-+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
-+ if (IS_ERR(pc->mmio_base))
-+ return PTR_ERR(pc->mmio_base);
-+
-+ platform_set_drvdata(pdev, pc);
-+
-+ pc->chip.dev = &pdev->dev;
-+ pc->chip.ops = &mtk_pwm_ops;
-+ pc->chip.base = -1;
-+ pc->chip.npwm = NUM_PWM;
-+
-+ ret = pwmchip_add(&pc->chip);
-+ if (ret < 0)
-+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
-+
-+ return ret;
-+}
-+
-+static int mtk_pwm_remove(struct platform_device *pdev)
-+{
-+ struct mtk_pwm_chip *pc = platform_get_drvdata(pdev);
-+ int i;
-+
-+ for (i = 0; i < NUM_PWM; i++)
-+ pwm_disable(&pc->chip.pwms[i]);
-+
-+ return pwmchip_remove(&pc->chip);
-+}
-+
-+static const struct of_device_id mtk_pwm_of_match[] = {
-+ { .compatible = "mediatek,mt7628-pwm" },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
-+
-+static struct platform_driver mtk_pwm_driver = {
-+ .driver = {
-+ .name = "mtk-pwm",
-+ .owner = THIS_MODULE,
-+ .of_match_table = mtk_pwm_of_match,
-+ },
-+ .probe = mtk_pwm_probe,
-+ .remove = mtk_pwm_remove,
-+};
-+
-+module_platform_driver(mtk_pwm_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
-+MODULE_ALIAS("platform:mtk-pwm");
+++ /dev/null
---- a/drivers/usb/dwc2/platform.c
-+++ b/drivers/usb/dwc2/platform.c
-@@ -431,6 +431,12 @@ static int dwc2_driver_probe(struct plat
- if (retval)
- return retval;
-
-+ /* Enable USB port before any regs access */
-+ if (readl(hsotg->regs + PCGCTL) & 0x0f) {
-+ writel(0x00, hsotg->regs + PCGCTL);
-+ /* TODO: mdelay(25) here? vendor driver don't use it */
-+ }
-+
- hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
-
- retval = dwc2_get_dr_mode(hsotg);
+++ /dev/null
---- a/arch/mips/ralink/Kconfig
-+++ b/arch/mips/ralink/Kconfig
-@@ -57,6 +57,7 @@ choice
- select COMMON_CLK
- select CLKSRC_MIPS_GIC
- select HAVE_PCI if PCI_MT7621
-+ select WEAK_REORDERING_BEYOND_LLSC
- endchoice
-
- choice
+++ /dev/null
---- a/arch/mips/kernel/mips-cm.c
-+++ b/arch/mips/kernel/mips-cm.c
-@@ -232,6 +232,7 @@ int mips_cm_probe(void)
-
- /* disable CM regions */
- write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR);
-+ /*
- write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK);
- write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR);
- write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK);
-@@ -239,7 +240,7 @@ int mips_cm_probe(void)
- write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK);
- write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR);
- write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK);
--
-+*/
- /* probe for an L2-only sync region */
- mips_cm_probe_l2sync();
-
+++ /dev/null
-From b327cd58c3fec1c6382128e929eab9bc0d68e912 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Sun, 8 Mar 2020 10:19:27 +0100
-Subject: [PATCH] staging: mt7621-pci: simplify
- 'mt7621_pcie_init_virtual_bridges' function
-
-Function 'mt7621_pcie_init_virtual_bridges' is a bit mess and can be
-refactorized properly in a cleaner way. Introduce new 'pcie_rmw' inline
-function helper to do clear and set the correct bits this function needs
-to work.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200308091928.17177-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 85 +++++++++++++--------------------
- 1 file changed, 33 insertions(+), 52 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -57,13 +57,13 @@
- #define RALINK_PCI_IOBASE 0x002C
-
- /* PCICFG virtual bridges */
--#define MT7621_BR0_MASK GENMASK(19, 16)
--#define MT7621_BR1_MASK GENMASK(23, 20)
--#define MT7621_BR2_MASK GENMASK(27, 24)
--#define MT7621_BR_ALL_MASK GENMASK(27, 16)
--#define MT7621_BR0_SHIFT 16
--#define MT7621_BR1_SHIFT 20
--#define MT7621_BR2_SHIFT 24
-+#define PCIE_P2P_MAX 3
-+#define PCIE_P2P_BR_DEVNUM_SHIFT(p) (16 + (p) * 4)
-+#define PCIE_P2P_BR_DEVNUM0_SHIFT PCIE_P2P_BR_DEVNUM_SHIFT(0)
-+#define PCIE_P2P_BR_DEVNUM1_SHIFT PCIE_P2P_BR_DEVNUM_SHIFT(1)
-+#define PCIE_P2P_BR_DEVNUM2_SHIFT PCIE_P2P_BR_DEVNUM_SHIFT(2)
-+#define PCIE_P2P_BR_DEVNUM_MASK 0xf
-+#define PCIE_P2P_BR_DEVNUM_MASK_FULL (0xfff << PCIE_P2P_BR_DEVNUM0_SHIFT)
-
- /* PCIe RC control registers */
- #define MT7621_PCIE_OFFSET 0x2000
-@@ -154,6 +154,15 @@ static inline void pcie_write(struct mt7
- writel(val, pcie->base + reg);
- }
-
-+static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set)
-+{
-+ u32 val = readl(pcie->base + reg);
-+
-+ val &= ~clr;
-+ val |= set;
-+ writel(val, pcie->base + reg);
-+}
-+
- static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg)
- {
- return readl(port->base + reg);
-@@ -554,7 +563,9 @@ static void mt7621_pcie_enable_ports(str
- static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie)
- {
- u32 pcie_link_status = 0;
-- u32 val = 0;
-+ u32 n;
-+ int i;
-+ u32 p2p_br_devnum[PCIE_P2P_MAX];
- struct mt7621_pcie_port *port;
-
- list_for_each_entry(port, &pcie->ports, list) {
-@@ -567,50 +578,20 @@ static int mt7621_pcie_init_virtual_brid
- if (pcie_link_status == 0)
- return -1;
-
-- /*
-- * pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num
-- * 3'b000 x x x
-- * 3'b001 x x 0
-- * 3'b010 x 0 x
-- * 3'b011 x 1 0
-- * 3'b100 0 x x
-- * 3'b101 1 x 0
-- * 3'b110 1 0 x
-- * 3'b111 2 1 0
-- */
-- switch (pcie_link_status) {
-- case 2:
-- val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
-- val &= ~(MT7621_BR0_MASK | MT7621_BR1_MASK);
-- val |= 0x1 << MT7621_BR0_SHIFT;
-- val |= 0x0 << MT7621_BR1_SHIFT;
-- pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
-- break;
-- case 4:
-- val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
-- val &= ~MT7621_BR_ALL_MASK;
-- val |= 0x1 << MT7621_BR0_SHIFT;
-- val |= 0x2 << MT7621_BR1_SHIFT;
-- val |= 0x0 << MT7621_BR2_SHIFT;
-- pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
-- break;
-- case 5:
-- val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
-- val &= ~MT7621_BR_ALL_MASK;
-- val |= 0x0 << MT7621_BR0_SHIFT;
-- val |= 0x2 << MT7621_BR1_SHIFT;
-- val |= 0x1 << MT7621_BR2_SHIFT;
-- pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
-- break;
-- case 6:
-- val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
-- val &= ~MT7621_BR_ALL_MASK;
-- val |= 0x2 << MT7621_BR0_SHIFT;
-- val |= 0x0 << MT7621_BR1_SHIFT;
-- val |= 0x1 << MT7621_BR2_SHIFT;
-- pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
-- break;
-- }
-+ n = 0;
-+ for (i = 0; i < PCIE_P2P_MAX; i++)
-+ if (pcie_link_status & BIT(i))
-+ p2p_br_devnum[i] = n++;
-+
-+ for (i = 0; i < PCIE_P2P_MAX; i++)
-+ if ((pcie_link_status & BIT(i)) == 0)
-+ p2p_br_devnum[i] = n++;
-+
-+ pcie_rmw(pcie, RALINK_PCI_CONFIG_ADDR,
-+ PCIE_P2P_BR_DEVNUM_MASK_FULL,
-+ (p2p_br_devnum[0] << PCIE_P2P_BR_DEVNUM0_SHIFT) |
-+ (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) |
-+ (p2p_br_devnum[2] << PCIE_P2P_BR_DEVNUM2_SHIFT));
-
- return 0;
- }
+++ /dev/null
-From 550fabd71d7fcdfe099bbf41e00e28719737161e Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Tue, 10 Mar 2020 12:34:59 +0100
-Subject: [PATCH] staging: mt7621-pci: enable clock bit for each port
-
-The clock related code concerns me from the very beginning because
-there are some set ups got from legacy driver that are not documented
-anywhere. According to the programming guide 0x7c is 'CPE_ROSC_SEL1'
-register and 0x80 is 'CPU_CPE_CN'. I do think this set up is not needed
-at all and the proper thing to do is just enable the clock bit for each
-pcie port. Hence remove useless code and do the right thing which is
-setting up the clock bit for each port enabled.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200310113459.30539-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 17 ++++++-----------
- 1 file changed, 6 insertions(+), 11 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -45,8 +45,6 @@
-
- /* rt_sysc_membase relative registers */
- #define RALINK_CLKCFG1 0x30
--#define RALINK_PCIE_CLK_GEN 0x7c
--#define RALINK_PCIE_CLK_GEN1 0x80
-
- /* Host-PCI bridge registers */
- #define RALINK_PCI_PCICFG_ADDR 0x0000
-@@ -85,10 +83,6 @@
- #define PCIE_PORT_CLK_EN(x) BIT(24 + (x))
- #define PCIE_PORT_LINKUP BIT(0)
-
--#define PCIE_CLK_GEN_EN BIT(31)
--#define PCIE_CLK_GEN_DIS 0
--#define PCIE_CLK_GEN1_DIS GENMASK(30, 24)
--#define PCIE_CLK_GEN1_EN (BIT(27) | BIT(25))
- #define MEMORY_BASE 0x0
- #define PERST_MODE_MASK GENMASK(11, 10)
- #define PERST_MODE_GPIO BIT(10)
-@@ -233,6 +227,11 @@ static inline bool mt7621_pcie_port_is_l
- return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0;
- }
-
-+static inline void mt7621_pcie_port_clk_enable(struct mt7621_pcie_port *port)
-+{
-+ rt_sysc_m32(0, PCIE_PORT_CLK_EN(port->slot), RALINK_CLKCFG1);
-+}
-+
- static inline void mt7621_pcie_port_clk_disable(struct mt7621_pcie_port *port)
- {
- rt_sysc_m32(PCIE_PORT_CLK_EN(port->slot), 0, RALINK_CLKCFG1);
-@@ -501,11 +500,6 @@ static void mt7621_pcie_init_ports(struc
- }
- }
-
-- rt_sysc_m32(0x30, 2 << 4, SYSC_REG_SYSTEM_CONFIG1);
-- rt_sysc_m32(PCIE_CLK_GEN_EN, PCIE_CLK_GEN_DIS, RALINK_PCIE_CLK_GEN);
-- rt_sysc_m32(PCIE_CLK_GEN1_DIS, PCIE_CLK_GEN1_EN, RALINK_PCIE_CLK_GEN1);
-- rt_sysc_m32(PCIE_CLK_GEN_DIS, PCIE_CLK_GEN_EN, RALINK_PCIE_CLK_GEN);
-- msleep(50);
- reset_control_deassert(pcie->rst);
- }
-
-@@ -542,6 +536,7 @@ static void mt7621_pcie_enable_ports(str
-
- list_for_each_entry(port, &pcie->ports, list) {
- if (port->enabled) {
-+ mt7621_pcie_port_clk_enable(port);
- mt7621_pcie_enable_port(port);
- dev_info(dev, "PCIE%d enabled\n", num_slots_enabled);
- num_slots_enabled++;
+++ /dev/null
-From 227a8bf421ff8b085444e51e471ef06a87228cfd Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 13 Mar 2020 21:09:08 +0100
-Subject: [PATCH] staging: mt7621-pci: use gpios for properly reset
-
-Original driver code was using three gpio's for reset
-asserts and deasserts the pcis. Instead of using that
-a general reset control with a perst gpio was introduced
-and it seems it is partially working but sometimes there
-are some unexpected hangs on boot. This commit make use of
-the three original gpios using 'reset-gpios' property of
-the device tree and removes the reset line and perst gpio.
-According to the mediatek aplication note v0.1 there are
-three gpios used for pcie ports reset control: gpio#19,
-gpio#8 and gpio#7 for slots 0, 1 and 2 respectively.
-This schema can be used separately for mt7621A but in some
-boards due to pin share issue, if the PCM and I2S function
-are enable at the same time, there are no enough GPIO to
-control per-port PCIe reset. In those cases gpio#19 is enought
-for reset the three ports together. Because of this we just
-try to get the three gpios but if some of them fail we are not
-failing in boot process, just prints a kernel notice and take
-after into account if the descriptor is or not valid in order
-to use it. All of them are set as GPIO output low configuration.
-The gpio descriptor's API takes device tree property into account
-and invert value if the pin is configured as active low.
-So we also have to properly request pins from device tree
-and set values correct in assert and deassert functions.
-After this changes the order to make all assert and
-deassert in the 'probe' process makes more sense:
-* Parse device tree.
-* make assert of the RC's and EP's before doing anything else.
-* make deassert of the RC's before initializing the phy.
-* Init the phy.
-* make deassert of the EP's before initialize pci ports.
-* Normal PCI initialization.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200313200913.24321-2-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 84 ++++++++++++++++++++-------------
- 1 file changed, 51 insertions(+), 33 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -95,6 +95,7 @@
- * @pcie: pointer to PCIe host info
- * @phy: pointer to PHY control block
- * @pcie_rst: pointer to port reset control
-+ * @gpio_rst: gpio reset
- * @slot: port slot
- * @enabled: indicates if port is enabled
- */
-@@ -104,6 +105,7 @@ struct mt7621_pcie_port {
- struct mt7621_pcie *pcie;
- struct phy *phy;
- struct reset_control *pcie_rst;
-+ struct gpio_desc *gpio_rst;
- u32 slot;
- bool enabled;
- };
-@@ -117,8 +119,6 @@ struct mt7621_pcie_port {
- * @offset: IO / Memory offset
- * @dev: Pointer to PCIe device
- * @ports: pointer to PCIe port information
-- * @perst: gpio reset
-- * @rst: pointer to pcie reset
- * @resets_inverted: depends on chip revision
- * reset lines are inverted.
- */
-@@ -133,8 +133,6 @@ struct mt7621_pcie {
- resource_size_t io;
- } offset;
- struct list_head ports;
-- struct gpio_desc *perst;
-- struct reset_control *rst;
- bool resets_inverted;
- };
-
-@@ -210,16 +208,16 @@ static void write_config(struct mt7621_p
- pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA);
- }
-
--static inline void mt7621_perst_gpio_pcie_assert(struct mt7621_pcie *pcie)
-+static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port)
- {
-- gpiod_set_value(pcie->perst, 0);
-- mdelay(PERST_DELAY_US);
-+ if (port->gpio_rst)
-+ gpiod_set_value(port->gpio_rst, 1);
- }
-
--static inline void mt7621_perst_gpio_pcie_deassert(struct mt7621_pcie *pcie)
-+static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port)
- {
-- gpiod_set_value(pcie->perst, 1);
-- mdelay(PERST_DELAY_US);
-+ if (port->gpio_rst)
-+ gpiod_set_value(port->gpio_rst, 0);
- }
-
- static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port)
-@@ -367,6 +365,13 @@ static int mt7621_pcie_parse_port(struct
- if (IS_ERR(port->phy))
- return PTR_ERR(port->phy);
-
-+ port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
-+ GPIOD_OUT_LOW);
-+ if (IS_ERR(port->gpio_rst)) {
-+ dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot);
-+ return PTR_ERR(port->gpio_rst);
-+ }
-+
- port->slot = slot;
- port->pcie = pcie;
-
-@@ -383,12 +388,6 @@ static int mt7621_pcie_parse_dt(struct m
- struct resource regs;
- int err;
-
-- pcie->perst = devm_gpiod_get(dev, "perst", GPIOD_OUT_HIGH);
-- if (IS_ERR(pcie->perst)) {
-- dev_err(dev, "failed to get gpio perst\n");
-- return PTR_ERR(pcie->perst);
-- }
--
- err = of_address_to_resource(node, 0, ®s);
- if (err) {
- dev_err(dev, "missing \"reg\" property\n");
-@@ -399,12 +398,6 @@ static int mt7621_pcie_parse_dt(struct m
- if (IS_ERR(pcie->base))
- return PTR_ERR(pcie->base);
-
-- pcie->rst = devm_reset_control_get_exclusive(dev, "pcie");
-- if (PTR_ERR(pcie->rst) == -EPROBE_DEFER) {
-- dev_err(dev, "failed to get pcie reset control\n");
-- return PTR_ERR(pcie->rst);
-- }
--
- for_each_available_child_of_node(node, child) {
- int slot;
-
-@@ -458,16 +451,49 @@ static int mt7621_pcie_init_port(struct
- return 0;
- }
-
-+static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie)
-+{
-+ struct mt7621_pcie_port *port;
-+
-+ list_for_each_entry(port, &pcie->ports, list) {
-+ /* PCIe RC reset assert */
-+ mt7621_control_assert(port);
-+
-+ /* PCIe EP reset assert */
-+ mt7621_rst_gpio_pcie_assert(port);
-+ }
-+
-+ mdelay(PERST_DELAY_US);
-+}
-+
-+static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie)
-+{
-+ struct mt7621_pcie_port *port;
-+
-+ list_for_each_entry(port, &pcie->ports, list)
-+ mt7621_control_deassert(port);
-+}
-+
-+static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie)
-+{
-+ struct mt7621_pcie_port *port;
-+
-+ list_for_each_entry(port, &pcie->ports, list)
-+ mt7621_rst_gpio_pcie_deassert(port);
-+
-+ mdelay(PERST_DELAY_US);
-+}
-+
- static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
- {
- struct device *dev = pcie->dev;
- struct mt7621_pcie_port *port, *tmp;
-- u32 val = 0;
- int err;
-
- rt_sysc_m32(PERST_MODE_MASK, PERST_MODE_GPIO, MT7621_GPIO_MODE);
-
-- mt7621_perst_gpio_pcie_assert(pcie);
-+ mt7621_pcie_reset_assert(pcie);
-+ mt7621_pcie_reset_rc_deassert(pcie);
-
- list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
- u32 slot = port->slot;
-@@ -476,16 +502,10 @@ static void mt7621_pcie_init_ports(struc
- if (err) {
- dev_err(dev, "Initiating port %d failed\n", slot);
- list_del(&port->list);
-- } else {
-- val = read_config(pcie, slot, PCIE_FTS_NUM);
-- dev_info(dev, "Port %d N_FTS = %x\n", slot,
-- (unsigned int)val);
- }
- }
-
-- reset_control_assert(pcie->rst);
--
-- mt7621_perst_gpio_pcie_deassert(pcie);
-+ mt7621_pcie_reset_ep_deassert(pcie);
-
- list_for_each_entry(port, &pcie->ports, list) {
- u32 slot = port->slot;
-@@ -499,8 +519,6 @@ static void mt7621_pcie_init_ports(struc
- port->enabled = false;
- }
- }
--
-- reset_control_deassert(pcie->rst);
- }
-
- static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port)
+++ /dev/null
-From e462e7d3211479df42357a620fa788a2257556b7 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 13 Mar 2020 21:09:09 +0100
-Subject: [PATCH] staging: mt7621-pci: change value for 'PERST_DELAY_MS'
-
-Value of 'PERST_DELAY_MS' is too high and it is ok just
-to set up to 100 ms. Update also define name from
-'PERST_DELAY_US' into 'PERST_DELAY_MS'
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200313200913.24321-3-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -86,7 +86,7 @@
- #define MEMORY_BASE 0x0
- #define PERST_MODE_MASK GENMASK(11, 10)
- #define PERST_MODE_GPIO BIT(10)
--#define PERST_DELAY_US 1000
-+#define PERST_DELAY_MS 100
-
- /**
- * struct mt7621_pcie_port - PCIe port information
-@@ -463,7 +463,7 @@ static void mt7621_pcie_reset_assert(str
- mt7621_rst_gpio_pcie_assert(port);
- }
-
-- mdelay(PERST_DELAY_US);
-+ mdelay(PERST_DELAY_MS);
- }
-
- static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie)
-@@ -481,7 +481,7 @@ static void mt7621_pcie_reset_ep_deasser
- list_for_each_entry(port, &pcie->ports, list)
- mt7621_rst_gpio_pcie_deassert(port);
-
-- mdelay(PERST_DELAY_US);
-+ mdelay(PERST_DELAY_MS);
- }
-
- static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
+++ /dev/null
-From 4d6a758f2cd2122a7d895f913854c13da62ba6df Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 13 Mar 2020 21:09:12 +0100
-Subject: [PATCH] staging: mt7621-pci: release gpios after pci initialization
-
-R3G's LEDs fail to initialize because one of them uses GPIO8
-Hence, release the GPIO resources after PCIe initialization
-and properly release also in driver error path.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200313200913.24321-6-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 23 ++++++++++++++++++-----
- 1 file changed, 18 insertions(+), 5 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -484,6 +484,15 @@ static void mt7621_pcie_reset_ep_deasser
- mdelay(PERST_DELAY_MS);
- }
-
-+static void mt7621_pcie_release_gpios(struct mt7621_pcie *pcie)
-+{
-+ struct mt7621_pcie_port *port;
-+
-+ list_for_each_entry(port, &pcie->ports, list)
-+ if (port->gpio_rst)
-+ gpiod_put(port->gpio_rst);
-+}
-+
- static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
- {
- struct device *dev = pcie->dev;
-@@ -683,7 +692,8 @@ static int mt7621_pci_probe(struct platf
- err = mt7621_pcie_init_virtual_bridges(pcie);
- if (err) {
- dev_err(dev, "Nothing is connected in virtual bridges. Exiting...");
-- return 0;
-+ err = 0;
-+ goto out_release_gpios;
- }
-
- mt7621_pcie_enable_ports(pcie);
-@@ -691,7 +701,7 @@ static int mt7621_pci_probe(struct platf
- err = mt7621_pci_parse_request_of_pci_ranges(pcie);
- if (err) {
- dev_err(dev, "Error requesting pci resources from ranges");
-- return err;
-+ goto out_release_gpios;
- }
-
- setup_cm_memory_region(pcie);
-@@ -699,16 +709,19 @@ static int mt7621_pci_probe(struct platf
- err = mt7621_pcie_request_resources(pcie, &res);
- if (err) {
- dev_err(dev, "Error requesting resources\n");
-- return err;
-+ goto out_release_gpios;
- }
-
- err = mt7621_pcie_register_host(bridge, &res);
- if (err) {
- dev_err(dev, "Error registering host\n");
-- return err;
-+ goto out_release_gpios;
- }
-
-- return 0;
-+out_release_gpios:
-+ mt7621_pcie_release_gpios(pcie);
-+
-+ return err;
- }
-
- static const struct of_device_id mt7621_pci_ids[] = {
+++ /dev/null
-From 4be54c3a495f08c05a8e485566e5b88cd3537f16 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 13 Mar 2020 21:09:13 +0100
-Subject: [PATCH] staging: mt7621-pci: delete no more needed
- 'mt7621_reset_port'
-
-After review all the resets at the beggining the function
-'mt7621_reset_port' is not needed anymore. Hence delete it
-and its uses.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200313200913.24321-7-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 13 -------------
- 1 file changed, 13 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -255,13 +255,6 @@ static inline void mt7621_control_deasse
- reset_control_assert(port->pcie_rst);
- }
-
--static void mt7621_reset_port(struct mt7621_pcie_port *port)
--{
-- mt7621_control_assert(port);
-- msleep(100);
-- mt7621_control_deassert(port);
--}
--
- static void setup_cm_memory_region(struct mt7621_pcie *pcie)
- {
- struct resource *mem_resource = &pcie->mem;
-@@ -427,12 +420,6 @@ static int mt7621_pcie_init_port(struct
- u32 slot = port->slot;
- int err;
-
-- /*
-- * Any MT7621 Ralink pcie controller that doesn't have 0x0101 at
-- * the end of the chip_id has inverted PCI resets.
-- */
-- mt7621_reset_port(port);
--
- err = phy_init(port->phy);
- if (err) {
- dev_err(dev, "failed to initialize port%d phy\n", slot);
+++ /dev/null
-From bf0c6782e5b9a6deee4e223655325dc004fae8dd Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Sun, 15 Mar 2020 17:01:54 +0100
-Subject: [PATCH] staging: mt7621-pci-phy: add 'mt7621_phy_rmw' to simplify
- code
-
-In order to simplify driver code and decrease a bit LOC add new
-function 'mt7621_phy_rmw' where clear and set bits are passed as
-arguments.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200315160154.10292-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 158 +++++++++++-------------
- 1 file changed, 71 insertions(+), 87 deletions(-)
-
---- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
-+++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
-@@ -120,17 +120,25 @@ static inline void phy_write(struct mt76
- regmap_write(phy->regmap, reg, val);
- }
-
-+static inline void mt7621_phy_rmw(struct mt7621_pci_phy *phy,
-+ u32 reg, u32 clr, u32 set)
-+{
-+ u32 val = phy_read(phy, reg);
-+
-+ val &= ~clr;
-+ val |= set;
-+ phy_write(phy, val, reg);
-+}
-+
- static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy,
- struct mt7621_pci_phy_instance *instance)
- {
- u32 offset = (instance->index != 1) ?
- RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH;
-- u32 reg;
-
-- reg = phy_read(phy, offset);
-- reg &= ~(RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
-- reg |= (RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
-- phy_write(phy, reg, offset);
-+ mt7621_phy_rmw(phy, offset,
-+ RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC,
-+ RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
- }
-
- static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy,
-@@ -139,97 +147,77 @@ static void mt7621_set_phy_for_ssc(struc
- struct device *dev = phy->dev;
- u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
- u32 offset;
-- u32 val;
-
- reg = (reg >> 6) & 0x7;
- /* Set PCIe Port PHY to disable SSC */
- /* Debug Xtal Type */
-- val = phy_read(phy, RG_PE1_FRC_H_XTAL_REG);
-- val &= ~(RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE);
-- val |= RG_PE1_FRC_H_XTAL_TYPE;
-- val |= RG_PE1_H_XTAL_TYPE_VAL(0x00);
-- phy_write(phy, val, RG_PE1_FRC_H_XTAL_REG);
-+ mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG,
-+ RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE,
-+ RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00));
-
- /* disable port */
- offset = (instance->index != 1) ?
- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
-- val = phy_read(phy, offset);
-- val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
-- val |= RG_PE1_FRC_PHY_EN;
-- phy_write(phy, val, offset);
--
-- /* Set Pre-divider ratio (for host mode) */
-- val = phy_read(phy, RG_PE1_H_PLL_REG);
-- val &= ~(RG_PE1_H_PLL_PREDIV);
-+ mt7621_phy_rmw(phy, offset,
-+ RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
-
- if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
-- val |= RG_PE1_H_PLL_PREDIV_VAL(0x01);
-- phy_write(phy, val, RG_PE1_H_PLL_REG);
-+ /* Set Pre-divider ratio (for host mode) */
-+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
-+ RG_PE1_H_PLL_PREDIV,
-+ RG_PE1_H_PLL_PREDIV_VAL(0x01));
- dev_info(dev, "Xtal is 40MHz\n");
-- } else { /* 25MHz | 20MHz Xtal */
-- val |= RG_PE1_H_PLL_PREDIV_VAL(0x00);
-- phy_write(phy, val, RG_PE1_H_PLL_REG);
-- if (reg >= 6) {
-- dev_info(dev, "Xtal is 25MHz\n");
--
-- /* Select feedback clock */
-- val = phy_read(phy, RG_PE1_H_PLL_FBKSEL_REG);
-- val &= ~(RG_PE1_H_PLL_FBKSEL);
-- val |= RG_PE1_H_PLL_FBKSEL_VAL(0x01);
-- phy_write(phy, val, RG_PE1_H_PLL_FBKSEL_REG);
--
-- /* DDS NCPO PCW (for host mode) */
-- val = phy_read(phy, RG_PE1_H_LCDDS_SSC_PRD_REG);
-- val &= ~(RG_PE1_H_LCDDS_SSC_PRD);
-- val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000);
-- phy_write(phy, val, RG_PE1_H_LCDDS_SSC_PRD_REG);
--
-- /* DDS SSC dither period control */
-- val = phy_read(phy, RG_PE1_H_LCDDS_SSC_PRD_REG);
-- val &= ~(RG_PE1_H_LCDDS_SSC_PRD);
-- val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d);
-- phy_write(phy, val, RG_PE1_H_LCDDS_SSC_PRD_REG);
--
-- /* DDS SSC dither amplitude control */
-- val = phy_read(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG);
-- val &= ~(RG_PE1_H_LCDDS_SSC_DELTA |
-- RG_PE1_H_LCDDS_SSC_DELTA1);
-- val |= RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a);
-- val |= RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a);
-- phy_write(phy, val, RG_PE1_H_LCDDS_SSC_DELTA_REG);
-- } else {
-- dev_info(dev, "Xtal is 20MHz\n");
-- }
-+ } else if (reg >= 6) { /* 25MHz Xal */
-+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
-+ RG_PE1_H_PLL_PREDIV,
-+ RG_PE1_H_PLL_PREDIV_VAL(0x00));
-+ /* Select feedback clock */
-+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_FBKSEL_REG,
-+ RG_PE1_H_PLL_FBKSEL,
-+ RG_PE1_H_PLL_FBKSEL_VAL(0x01));
-+ /* DDS NCPO PCW (for host mode) */
-+ mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
-+ RG_PE1_H_LCDDS_SSC_PRD,
-+ RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000));
-+ /* DDS SSC dither period control */
-+ mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
-+ RG_PE1_H_LCDDS_SSC_PRD,
-+ RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d));
-+ /* DDS SSC dither amplitude control */
-+ mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG,
-+ RG_PE1_H_LCDDS_SSC_DELTA |
-+ RG_PE1_H_LCDDS_SSC_DELTA1,
-+ RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a) |
-+ RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a));
-+ dev_info(dev, "Xtal is 25MHz\n");
-+ } else { /* 20MHz Xtal */
-+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
-+ RG_PE1_H_PLL_PREDIV,
-+ RG_PE1_H_PLL_PREDIV_VAL(0x00));
-+
-+ dev_info(dev, "Xtal is 20MHz\n");
- }
-
- /* DDS clock inversion */
-- val = phy_read(phy, RG_PE1_LCDDS_CLK_PH_INV_REG);
-- val &= ~(RG_PE1_LCDDS_CLK_PH_INV);
-- val |= RG_PE1_LCDDS_CLK_PH_INV;
-- phy_write(phy, val, RG_PE1_LCDDS_CLK_PH_INV_REG);
-+ mt7621_phy_rmw(phy, RG_PE1_LCDDS_CLK_PH_INV_REG,
-+ RG_PE1_LCDDS_CLK_PH_INV, RG_PE1_LCDDS_CLK_PH_INV);
-
- /* Set PLL bits */
-- val = phy_read(phy, RG_PE1_H_PLL_REG);
-- val &= ~(RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR |
-- RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN);
-- val |= RG_PE1_H_PLL_BC_VAL(0x02);
-- val |= RG_PE1_H_PLL_BP_VAL(0x06);
-- val |= RG_PE1_H_PLL_IR_VAL(0x02);
-- val |= RG_PE1_H_PLL_IC_VAL(0x01);
-- val |= RG_PE1_PLL_DIVEN_VAL(0x02);
-- phy_write(phy, val, RG_PE1_H_PLL_REG);
--
-- val = phy_read(phy, RG_PE1_H_PLL_BR_REG);
-- val &= ~(RG_PE1_H_PLL_BR);
-- val |= RG_PE1_H_PLL_BR_VAL(0x00);
-- phy_write(phy, val, RG_PE1_H_PLL_BR_REG);
-+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
-+ RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR |
-+ RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN,
-+ RG_PE1_H_PLL_BC_VAL(0x02) | RG_PE1_H_PLL_BP_VAL(0x06) |
-+ RG_PE1_H_PLL_IR_VAL(0x02) | RG_PE1_H_PLL_IC_VAL(0x01) |
-+ RG_PE1_PLL_DIVEN_VAL(0x02));
-+
-+ mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG,
-+ RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00));
-
- if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
- /* set force mode enable of da_pe1_mstckdiv */
-- val = phy_read(phy, RG_PE1_MSTCKDIV_REG);
-- val &= ~(RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV);
-- val |= (RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV);
-- phy_write(phy, val, RG_PE1_MSTCKDIV_REG);
-+ mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG,
-+ RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV,
-+ RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV);
- }
- }
-
-@@ -252,13 +240,11 @@ static int mt7621_pci_phy_power_on(struc
- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
- u32 offset = (instance->index != 1) ?
- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
-- u32 val;
-
- /* Enable PHY and disable force mode */
-- val = phy_read(mphy, offset);
-- val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
-- val |= (RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
-- phy_write(mphy, val, offset);
-+ mt7621_phy_rmw(mphy, offset,
-+ RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
-+ RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
-
- return 0;
- }
-@@ -269,13 +255,11 @@ static int mt7621_pci_phy_power_off(stru
- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
- u32 offset = (instance->index != 1) ?
- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
-- u32 val;
-
- /* Disable PHY */
-- val = phy_read(mphy, offset);
-- val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
-- val |= RG_PE1_FRC_PHY_EN;
-- phy_write(mphy, val, offset);
-+ mt7621_phy_rmw(mphy, offset,
-+ RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
-+ RG_PE1_FRC_PHY_EN);
-
- return 0;
- }
+++ /dev/null
-From 3faf4e1c537de86058fc22a851cd979489b9185e Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Wed, 18 Mar 2020 10:44:45 +0100
-Subject: [PATCH] staging: mt7621-pci: fix io space and properly set resource
- limits
-
-Function 'mt7621_pci_parse_request_of_pci_ranges' is using
-'of_pci_range_to_resource' to get both mem and io resources.
-Internally this function calls to 'pci_address_to_pio' which
-returns -1 if io space address is an address > IO_SPACE_LIMIT
-which is 0xFFFF for mips. This mt7621 soc has io space in physical
-address 0x1e160000. In order to fix this, overwrite invalid io
-0xffffffff with properly values from the device tree and set
-mapped address of this resource as io port base memory address
-calling 'set_io_port_base' function. There is also need to properly
-setup resource limits and io and memory windows with properly
-parsed values instead of set them as 'no limit' which it is wrong.
-For any reason I don't really know legacy driver sets up mem window
-as 0xFFFFFFFF and any other value seems to does not work as expected,
-so set up also here with same values.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200318094445.19669-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 43 +++++++++++++++++++--------------
- 1 file changed, 25 insertions(+), 18 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -118,6 +118,7 @@ struct mt7621_pcie_port {
- * @busn: bus range
- * @offset: IO / Memory offset
- * @dev: Pointer to PCIe device
-+ * @io_map_base: virtual memory base address for io
- * @ports: pointer to PCIe port information
- * @resets_inverted: depends on chip revision
- * reset lines are inverted.
-@@ -132,6 +133,7 @@ struct mt7621_pcie {
- resource_size_t mem;
- resource_size_t io;
- } offset;
-+ unsigned long io_map_base;
- struct list_head ports;
- bool resets_inverted;
- };
-@@ -291,22 +293,21 @@ static int mt7621_pci_parse_request_of_p
- }
-
- for_each_of_pci_range(&parser, &range) {
-- struct resource *res = NULL;
--
- switch (range.flags & IORESOURCE_TYPE_BITS) {
- case IORESOURCE_IO:
-- ioremap(range.cpu_addr, range.size);
-- res = &pcie->io;
-+ pcie->io_map_base =
-+ (unsigned long)ioremap(range.cpu_addr,
-+ range.size);
-+ of_pci_range_to_resource(&range, node, &pcie->io);
-+ pcie->io.start = range.cpu_addr;
-+ pcie->io.end = range.cpu_addr + range.size - 1;
- pcie->offset.io = 0x00000000UL;
- break;
- case IORESOURCE_MEM:
-- res = &pcie->mem;
-+ of_pci_range_to_resource(&range, node, &pcie->mem);
- pcie->offset.mem = 0x00000000UL;
- break;
- }
--
-- if (res)
-- of_pci_range_to_resource(&range, node, res);
- }
-
- err = of_pci_parse_bus_range(node, &pcie->busn);
-@@ -318,6 +319,8 @@ static int mt7621_pci_parse_request_of_p
- pcie->busn.flags = IORESOURCE_BUS;
- }
-
-+ set_io_port_base(pcie->io_map_base);
-+
- return 0;
- }
-
-@@ -548,6 +551,10 @@ static void mt7621_pcie_enable_ports(str
- u32 slot;
- u32 val;
-
-+ /* Setup MEMWIN and IOWIN */
-+ pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE);
-+ pcie_write(pcie, pcie->io.start, RALINK_PCI_IOBASE);
-+
- list_for_each_entry(port, &pcie->ports, list) {
- if (port->enabled) {
- mt7621_pcie_port_clk_enable(port);
-@@ -668,11 +675,17 @@ static int mt7621_pci_probe(struct platf
- return err;
- }
-
-+ err = mt7621_pci_parse_request_of_pci_ranges(pcie);
-+ if (err) {
-+ dev_err(dev, "Error requesting pci resources from ranges");
-+ goto out_release_gpios;
-+ }
-+
- /* set resources limits */
-- iomem_resource.start = 0;
-- iomem_resource.end = ~0UL; /* no limit */
-- ioport_resource.start = 0;
-- ioport_resource.end = ~0UL; /* no limit */
-+ iomem_resource.start = pcie->mem.start;
-+ iomem_resource.end = pcie->mem.end;
-+ ioport_resource.start = pcie->io.start;
-+ ioport_resource.end = pcie->io.end;
-
- mt7621_pcie_init_ports(pcie);
-
-@@ -685,12 +698,6 @@ static int mt7621_pci_probe(struct platf
-
- mt7621_pcie_enable_ports(pcie);
-
-- err = mt7621_pci_parse_request_of_pci_ranges(pcie);
-- if (err) {
-- dev_err(dev, "Error requesting pci resources from ranges");
-- goto out_release_gpios;
-- }
--
- setup_cm_memory_region(pcie);
-
- err = mt7621_pcie_request_resources(pcie, &res);
+++ /dev/null
-From 0a3085ae142d8f5cf905b104bc66db3721a2fa33 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Thu, 19 Mar 2020 10:57:33 +0100
-Subject: [PATCH] staging: mt7621-pci: fix register to set up virtual bridges
-
-Instead of being using PCI Configuration and Status Register to
-set up virtual bridges we are using CONFIG_ADDR Register which is
-wrong. Hence, set the correct value.
-
-Fixes: 9a5e71a68d20 ("staging: mt7621-pci: simplify 'mt7621_pcie_init_virtual_bridges' function")
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200319095733.1557-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -603,7 +603,7 @@ static int mt7621_pcie_init_virtual_brid
- if ((pcie_link_status & BIT(i)) == 0)
- p2p_br_devnum[i] = n++;
-
-- pcie_rmw(pcie, RALINK_PCI_CONFIG_ADDR,
-+ pcie_rmw(pcie, RALINK_PCI_PCICFG_ADDR,
- PCIE_P2P_BR_DEVNUM_MASK_FULL,
- (p2p_br_devnum[0] << PCIE_P2P_BR_DEVNUM0_SHIFT) |
- (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) |
+++ /dev/null
-From 23a788c23ed10e0d79092fcb693dcf0e357e1f7e Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Thu, 19 Mar 2020 17:14:16 +0100
-Subject: [PATCH] staging: mt7621-pci: don't return if get gpio fails
-
-In some platforms gpio's are not used for reset but
-for other purposes. Because of that when we try to
-get them are valid gpio's but are already assigned
-to do other function. To avoid those kind of problems
-in those platforms just notice the fail in the kernel
-but continue doing normal boot.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200319161416.19033-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -363,10 +363,8 @@ static int mt7621_pcie_parse_port(struct
-
- port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
- GPIOD_OUT_LOW);
-- if (IS_ERR(port->gpio_rst)) {
-- dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot);
-- return PTR_ERR(port->gpio_rst);
-- }
-+ if (IS_ERR(port->gpio_rst))
-+ dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot);
-
- port->slot = slot;
- port->pcie = pcie;
+++ /dev/null
-From 91eb47531421f0e8c9bc4594b4a7caa0e59dc83e Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 20 Mar 2020 12:01:19 +0100
-Subject: [PATCH] staging: mt7621-pci-phy: avoid to create to different phys
- for a dual port one
-
-This soc has two phy's for the pcie one of them using just a different
-register for settig it up but sharing all the rest of the config. Until
-now we was presenting this schema as three different phy's in the device
-tree using the 'phy-cells' node property to discriminate an index and
-setting up a complete phy for the dual port index. This sometimes worked
-properly but reconfiguring the same registers twice presents sometimes
-some unstable pcie links and the ports was not properly being detected.
-The problems only appears on hard resets and soft resets was properly
-working. Instead of having this schema just set two phy's in the device
-ree and use the 'phy-cells' property to say if the port has or not a dual
-port. Doing this configuration and set up becomes easier, LOC is decreased
-and the behaviour also gets deterministic with properly and stable pcie
-links in both hard and soft resets.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200320110123.9907-2-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 144 ++++++++++--------------
- 1 file changed, 59 insertions(+), 85 deletions(-)
-
---- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
-+++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
-@@ -78,31 +78,21 @@
- #define MAX_PHYS 2
-
- /**
-- * struct mt7621_pci_phy_instance - Mt7621 Pcie PHY device
-- * @phy: pointer to the kernel PHY device
-- * @port_base: base register
-- * @index: internal ID to identify the Mt7621 PCIe PHY
-- */
--struct mt7621_pci_phy_instance {
-- struct phy *phy;
-- void __iomem *port_base;
-- u32 index;
--};
--
--/**
- * struct mt7621_pci_phy - Mt7621 Pcie PHY core
- * @dev: pointer to device
- * @regmap: kernel regmap pointer
-- * @phys: pointer to Mt7621 PHY device
-- * @nphys: number of PHY devices for this core
-+ * @phy: pointer to the kernel PHY device
-+ * @port_base: base register
-+ * @has_dual_port: if the phy has dual ports.
- * @bypass_pipe_rst: mark if 'mt7621_bypass_pipe_rst'
- * needs to be executed. Depends on chip revision.
- */
- struct mt7621_pci_phy {
- struct device *dev;
- struct regmap *regmap;
-- struct mt7621_pci_phy_instance **phys;
-- int nphys;
-+ struct phy *phy;
-+ void __iomem *port_base;
-+ bool has_dual_port;
- bool bypass_pipe_rst;
- };
-
-@@ -130,23 +120,23 @@ static inline void mt7621_phy_rmw(struct
- phy_write(phy, val, reg);
- }
-
--static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy,
-- struct mt7621_pci_phy_instance *instance)
-+static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy)
- {
-- u32 offset = (instance->index != 1) ?
-- RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH;
-+ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_RST);
-+ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_CMD_FRC);
-
-- mt7621_phy_rmw(phy, offset,
-- RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC,
-- RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
-+ if (phy->has_dual_port) {
-+ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH,
-+ 0, RG_PE1_PIPE_RST);
-+ mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH,
-+ 0, RG_PE1_PIPE_CMD_FRC);
-+ }
- }
-
--static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy,
-- struct mt7621_pci_phy_instance *instance)
-+static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
- {
- struct device *dev = phy->dev;
- u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
-- u32 offset;
-
- reg = (reg >> 6) & 0x7;
- /* Set PCIe Port PHY to disable SSC */
-@@ -156,10 +146,13 @@ static void mt7621_set_phy_for_ssc(struc
- RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00));
-
- /* disable port */
-- offset = (instance->index != 1) ?
-- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
-- mt7621_phy_rmw(phy, offset,
-- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
-+ mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG,
-+ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
-+
-+ if (phy->has_dual_port) {
-+ mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
-+ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
-+ }
-
- if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
- /* Set Pre-divider ratio (for host mode) */
-@@ -223,43 +216,44 @@ static void mt7621_set_phy_for_ssc(struc
-
- static int mt7621_pci_phy_init(struct phy *phy)
- {
-- struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy);
-- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
-+ struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
-
- if (mphy->bypass_pipe_rst)
-- mt7621_bypass_pipe_rst(mphy, instance);
-+ mt7621_bypass_pipe_rst(mphy);
-
-- mt7621_set_phy_for_ssc(mphy, instance);
-+ mt7621_set_phy_for_ssc(mphy);
-
- return 0;
- }
-
- static int mt7621_pci_phy_power_on(struct phy *phy)
- {
-- struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy);
-- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
-- u32 offset = (instance->index != 1) ?
-- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
-+ struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
-
- /* Enable PHY and disable force mode */
-- mt7621_phy_rmw(mphy, offset,
-- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
-- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
-+ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG,
-+ RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN);
-+
-+ if (mphy->has_dual_port) {
-+ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
-+ RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN);
-+ }
-
- return 0;
- }
-
- static int mt7621_pci_phy_power_off(struct phy *phy)
- {
-- struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy);
-- struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
-- u32 offset = (instance->index != 1) ?
-- RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
-+ struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
-
- /* Disable PHY */
-- mt7621_phy_rmw(mphy, offset,
-- RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
-- RG_PE1_FRC_PHY_EN);
-+ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG,
-+ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
-+
-+ if (mphy->has_dual_port) {
-+ mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
-+ RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
-+ }
-
- return 0;
- }
-@@ -282,13 +276,15 @@ static struct phy *mt7621_pcie_phy_of_xl
- {
- struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev);
-
-- if (args->args_count == 0)
-- return mt7621_phy->phys[0]->phy;
--
- if (WARN_ON(args->args[0] >= MAX_PHYS))
- return ERR_PTR(-ENODEV);
-
-- return mt7621_phy->phys[args->args[0]]->phy;
-+ mt7621_phy->has_dual_port = args->args[0];
-+
-+ dev_info(dev, "PHY for 0x%08x (dual port = %d)\n",
-+ (unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port);
-+
-+ return mt7621_phy->phy;
- }
-
- static const struct soc_device_attribute mt7621_pci_quirks_match[] = {
-@@ -309,19 +305,11 @@ static int mt7621_pci_phy_probe(struct p
- struct phy_provider *provider;
- struct mt7621_pci_phy *phy;
- struct resource *res;
-- int port;
-- void __iomem *port_base;
-
- phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
- if (!phy)
- return -ENOMEM;
-
-- phy->nphys = MAX_PHYS;
-- phy->phys = devm_kcalloc(dev, phy->nphys,
-- sizeof(*phy->phys), GFP_KERNEL);
-- if (!phy->phys)
-- return -ENOMEM;
--
- attr = soc_device_match(mt7621_pci_quirks_match);
- if (attr)
- phy->bypass_pipe_rst = true;
-@@ -335,39 +323,25 @@ static int mt7621_pci_phy_probe(struct p
- return -ENXIO;
- }
-
-- port_base = devm_ioremap_resource(dev, res);
-- if (IS_ERR(port_base)) {
-+ phy->port_base = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(phy->port_base)) {
- dev_err(dev, "failed to remap phy regs\n");
-- return PTR_ERR(port_base);
-+ return PTR_ERR(phy->port_base);
- }
-
-- phy->regmap = devm_regmap_init_mmio(phy->dev, port_base,
-+ phy->regmap = devm_regmap_init_mmio(phy->dev, phy->port_base,
- &mt7621_pci_phy_regmap_config);
- if (IS_ERR(phy->regmap))
- return PTR_ERR(phy->regmap);
-
-- for (port = 0; port < MAX_PHYS; port++) {
-- struct mt7621_pci_phy_instance *instance;
-- struct phy *pphy;
--
-- instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
-- if (!instance)
-- return -ENOMEM;
--
-- phy->phys[port] = instance;
--
-- pphy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops);
-- if (IS_ERR(phy)) {
-- dev_err(dev, "failed to create phy\n");
-- return PTR_ERR(phy);
-- }
--
-- instance->port_base = port_base;
-- instance->phy = pphy;
-- instance->index = port;
-- phy_set_drvdata(pphy, instance);
-+ phy->phy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops);
-+ if (IS_ERR(phy)) {
-+ dev_err(dev, "failed to create phy\n");
-+ return PTR_ERR(phy);
- }
-
-+ phy_set_drvdata(phy->phy, phy);
-+
- provider = devm_of_phy_provider_register(dev, mt7621_pcie_phy_of_xlate);
-
- return PTR_ERR_OR_ZERO(provider);
+++ /dev/null
-From c752b54bda4d772426c5eeb56978d2e41bd525b4 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 20 Mar 2020 12:01:21 +0100
-Subject: [PATCH] staging: mt7621-pci: use only two phys from device tree
-
-In order to align work with the mt7621-pci-phy part of
-the driver and device tree which is now using only two
-real phys one of them dual ported properly parse the
-device tree and don't call phy initialization for the
-slot 1 because is being taking into account when the
-phy for the slot 0 is instantiated.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200320110123.9907-4-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -358,7 +358,7 @@ static int mt7621_pcie_parse_port(struct
-
- snprintf(name, sizeof(name), "pcie-phy%d", slot);
- port->phy = devm_phy_get(dev, name);
-- if (IS_ERR(port->phy))
-+ if (IS_ERR(port->phy) && slot != 1)
- return PTR_ERR(port->phy);
-
- port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
-@@ -495,6 +495,11 @@ static void mt7621_pcie_init_ports(struc
- list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
- u32 slot = port->slot;
-
-+ if (slot == 1) {
-+ port->enabled = true;
-+ continue;
-+ }
-+
- err = mt7621_pcie_init_port(port);
- if (err) {
- dev_err(dev, "Initiating port %d failed\n", slot);
+++ /dev/null
-From b59343b7de448c30e5b098484a7c7c5cb300df2f Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 20 Mar 2020 12:01:22 +0100
-Subject: [PATCH] staging: mt7621-pci: change variable to print for slot
-
-We are using the counter to print the slot which has been
-enabled. Use the correct associated slot for the port instead.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200320110123.9907-5-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -562,7 +562,7 @@ static void mt7621_pcie_enable_ports(str
- if (port->enabled) {
- mt7621_pcie_port_clk_enable(port);
- mt7621_pcie_enable_port(port);
-- dev_info(dev, "PCIE%d enabled\n", num_slots_enabled);
-+ dev_info(dev, "PCIE%d enabled\n", port->slot);
- num_slots_enabled++;
- }
- }
+++ /dev/null
-From 87068309300c707d659ce79232eae827604804a4 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 20 Mar 2020 12:01:23 +0100
-Subject: [PATCH] staging: mt7621-pci: be sure gpio descriptor is null on fails
-
-Function 'devm_gpiod_get_index_optional' returns NULL if the
-descriptor is invalid and the error associated for the error
-pointer is ENOENT. Sometimes if the pin is just assigned the
-error associated for the pointer might not be ENOENT but other.
-In order to avoid weirds behaviours if this happen set descriptor
-to NULL in the driver port structure.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200320110123.9907-6-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -363,8 +363,10 @@ static int mt7621_pcie_parse_port(struct
-
- port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
- GPIOD_OUT_LOW);
-- if (IS_ERR(port->gpio_rst))
-+ if (IS_ERR(port->gpio_rst)) {
- dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot);
-+ port->gpio_rst = NULL;
-+ }
-
- port->slot = slot;
- port->pcie = pcie;
+++ /dev/null
-From d81fe3c13aa6f4ab1ec318212d2007175e6d05aa Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Fri, 20 Mar 2020 16:38:37 +0100
-Subject: [PATCH] staging: mt7621-pci: avoid to poweroff the phy for slot one
-
-Phy for slot 0 and 1 is shared and handled properly in slot 0.
-If there is only one port in use,(slot 0) we shall not call the
-'phy_power_off' function with an invalid slot because kernel
-will crash with an unaligned access fault like the following:
-
-mt7621-pci 1e140000.pcie: Error applying setting, reverse things back
-mt7621-pci-phy 1e149000.pcie-phy: PHY for 0xbe149000 (dual port = 1)
-mt7621-pci-phy 1e14a000.pcie-phy: PHY for 0xbe14a000 (dual port = 0)
-mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz
-mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz
-mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK)
-Unhandled kernel unaligned access[#1]:
-CPU: 3 PID: 111 Comm: kworker/3:2 Not tainted 5.6.0-rc3-00347-g825c6f470c62-dirty #9
-Workqueue: events deferred_probe_work_func
-$ 0 : 00000000 00000001 5f60d043 8fe1ba80
-$ 4 : 0000010d 01eb9000 00000000 00000000
-$ 8 : 294b4c00 80940000 00000008 000000ce
-$12 : 2e303030 00000000 00000000 65696370
-$16 : ffffffed 0000010d 8e373cd0 8214c1e0
-$20 : 00000000 82144c80 82144680 8214c250
-$24 : 00000018 803ef8f4
-$28 : 8e372000 8e373c60 8214c080 803940e8
-Hi : 00000125
-Lo : 122f2000
-epc : 807b3328 mutex_lock+0x8/0x44
-ra : 803940e8 phy_power_off+0x28/0xb0
-Status: 1100fc03 KERNEL EXL IE
-Cause : 00800010 (ExcCode 04)
-BadVA : 0000010d
-PrId : 0001992f (MIPS 1004Kc)
-Modules linked in:
-Process kworker/3:2 (pid: 111, threadinfo=(ptrval), task=(ptrval), tls=00000000)
-Stack : 8e373cd0 803fe4f4 8e372000 8e373c90 8214c080 804fde1c 8e373c98 808d62f4
- 8e373c78 00000000 8214c254 804fe648 1e160000 804f27b8 00000001 808d62f4
- 00000000 00000001 8214c228 808d62f4 80930000 809a0000 8fd47e10 808d63d4
- 808d62d4 8fd47e10 808d0000 808d0000 8e373cd0 8e373cd0 809e2a74 809db510
- 809db510 00000006 00000001 00000000 00000000 00000000 01000000 1e1440ff
- ...
-Call Trace:
-[<807b3328>] mutex_lock+0x8/0x44
-[<803940e8>] phy_power_off+0x28/0xb0
-[<804fe648>] mt7621_pci_probe+0xc20/0xd18
-[<80402ab8>] platform_drv_probe+0x40/0x94
-[<80400a74>] really_probe+0x104/0x364
-[<803feb74>] bus_for_each_drv+0x84/0xdc
-[<80400924>] __device_attach+0xdc/0x120
-[<803ffb5c>] bus_probe_device+0xa0/0xbc
-[<80400124>] deferred_probe_work_func+0x7c/0xbc
-[<800420e8>] process_one_work+0x230/0x450
-[<80042638>] worker_thread+0x330/0x5fc
-[<80048eb0>] kthread+0x12c/0x134
-[<80007438>] ret_from_kernel_thread+0x14/0x1c
-Code: 24050002 27bdfff8 8f830000 <c0850000> 14a00005 00000000 00600825 e0810000 1020fffa
-
-Fixes: bf516f413f4e ("staging: mt7621-pci: use only two phys from device tree")
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200320153837.20415-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -517,7 +517,8 @@ static void mt7621_pcie_init_ports(struc
- if (!mt7621_pcie_port_is_linkup(port)) {
- dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n",
- slot);
-- phy_power_off(port->phy);
-+ if (slot != 1)
-+ phy_power_off(port->phy);
- mt7621_control_assert(port);
- mt7621_pcie_port_clk_disable(port);
- port->enabled = false;
+++ /dev/null
-From 9d789a7728c37e8730b6a9cca60cf155f18537ea Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Sat, 21 Mar 2020 08:26:50 +0100
-Subject: [PATCH] staging: mt7621-pci: delete release gpios related code
-
-Making gpio8 and gpio9 vendor specific and putting them
-into the specific dts file makes not needed to release
-gpios anymore because we are not occupying those pins
-in the first place if it is not necessary. When the
-device tree is parsed we can also check and return for
-the error because we rely in the fact that the related
-device for the board is correct.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200321072650.7784-3-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 27 +++++++--------------------
- 1 file changed, 7 insertions(+), 20 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -364,8 +364,8 @@ static int mt7621_pcie_parse_port(struct
- port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
- GPIOD_OUT_LOW);
- if (IS_ERR(port->gpio_rst)) {
-- dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot);
-- port->gpio_rst = NULL;
-+ dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot);
-+ return PTR_ERR(port->gpio_rst);
- }
-
- port->slot = slot;
-@@ -474,15 +474,6 @@ static void mt7621_pcie_reset_ep_deasser
- mdelay(PERST_DELAY_MS);
- }
-
--static void mt7621_pcie_release_gpios(struct mt7621_pcie *pcie)
--{
-- struct mt7621_pcie_port *port;
--
-- list_for_each_entry(port, &pcie->ports, list)
-- if (port->gpio_rst)
-- gpiod_put(port->gpio_rst);
--}
--
- static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
- {
- struct device *dev = pcie->dev;
-@@ -684,7 +675,7 @@ static int mt7621_pci_probe(struct platf
- err = mt7621_pci_parse_request_of_pci_ranges(pcie);
- if (err) {
- dev_err(dev, "Error requesting pci resources from ranges");
-- goto out_release_gpios;
-+ return err;
- }
-
- /* set resources limits */
-@@ -698,8 +689,7 @@ static int mt7621_pci_probe(struct platf
- err = mt7621_pcie_init_virtual_bridges(pcie);
- if (err) {
- dev_err(dev, "Nothing is connected in virtual bridges. Exiting...");
-- err = 0;
-- goto out_release_gpios;
-+ return 0;
- }
-
- mt7621_pcie_enable_ports(pcie);
-@@ -709,19 +699,16 @@ static int mt7621_pci_probe(struct platf
- err = mt7621_pcie_request_resources(pcie, &res);
- if (err) {
- dev_err(dev, "Error requesting resources\n");
-- goto out_release_gpios;
-+ return err;
- }
-
- err = mt7621_pcie_register_host(bridge, &res);
- if (err) {
- dev_err(dev, "Error registering host\n");
-- goto out_release_gpios;
-+ return err;
- }
-
--out_release_gpios:
-- mt7621_pcie_release_gpios(pcie);
--
-- return err;
-+ return 0;
- }
-
- static const struct of_device_id mt7621_pci_ids[] = {
+++ /dev/null
-From 60a15339ceab9fc2a6cdc85fd54b66b2c947ab4e Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Sat, 21 Mar 2020 14:36:21 +0100
-Subject: [PATCH] staging: mt7621-pci: use builtin_platform_driver()
-
-Macro builtin_platform_driver can be used for builtin drivers
-that don't do anything in driver init. So, use the macro
-builtin_platform_driver and remove some boilerplate code.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200321133624.31388-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 7 +------
- 1 file changed, 1 insertion(+), 6 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -725,9 +725,4 @@ static struct platform_driver mt7621_pci
- },
- };
-
--static int __init mt7621_pci_init(void)
--{
-- return platform_driver_register(&mt7621_pci_driver);
--}
--
--module_init(mt7621_pci_init);
-+builtin_platform_driver(mt7621_pci_driver);
+++ /dev/null
-From ffe3dee4081055b4f58bc50dd3f5c97de42cf126 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Sat, 21 Mar 2020 14:36:23 +0100
-Subject: [PATCH] staging: mt7621-pci-phy: use builtin_platform_driver()
-
-Macro builtin_platform_driver can be used for builtin drivers
-that don't do anything in driver init. So, use the macro
-builtin_platform_driver and remove some boilerplate code.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200321133624.31388-3-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 7 +------
- 1 file changed, 1 insertion(+), 6 deletions(-)
-
---- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
-+++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
-@@ -361,12 +361,7 @@ static struct platform_driver mt7621_pci
- },
- };
-
--static int __init mt7621_pci_phy_drv_init(void)
--{
-- return platform_driver_register(&mt7621_pci_phy_driver);
--}
--
--module_init(mt7621_pci_phy_drv_init);
-+builtin_platform_driver(mt7621_pci_phy_driver);
-
- MODULE_AUTHOR("Sergio Paracuellos <sergio.paracuellos@gmail.com>");
- MODULE_DESCRIPTION("MediaTek MT7621 PCIe PHY driver");
+++ /dev/null
-From ff83e3023cb8fc3b5dfc12e0c91bf1eb9dc4c4c6 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Sat, 21 Mar 2020 14:36:24 +0100
-Subject: [PATCH] staging: mt7621-pci-phy: re-do 'xtal_mode' detection
-
-Detection of the Xtal mode is using magic numbers that
-can be avoided using properly some definitions and a more
-accurate variable name from 'reg' into 'xtal_mode'. This
-increase readability.
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200321133624.31388-4-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 15 ++++++++++-----
- 1 file changed, 10 insertions(+), 5 deletions(-)
-
---- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
-+++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
-@@ -75,6 +75,9 @@
-
- #define RG_PE1_FRC_MSTCKDIV BIT(5)
-
-+#define XTAL_MODE_SEL_SHIFT 6
-+#define XTAL_MODE_SEL_MASK 0x7
-+
- #define MAX_PHYS 2
-
- /**
-@@ -136,9 +139,11 @@ static void mt7621_bypass_pipe_rst(struc
- static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
- {
- struct device *dev = phy->dev;
-- u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
-+ u32 xtal_mode;
-+
-+ xtal_mode = (rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0)
-+ >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
-
-- reg = (reg >> 6) & 0x7;
- /* Set PCIe Port PHY to disable SSC */
- /* Debug Xtal Type */
- mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG,
-@@ -154,13 +159,13 @@ static void mt7621_set_phy_for_ssc(struc
- RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
- }
-
-- if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
-+ if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */
- /* Set Pre-divider ratio (for host mode) */
- mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
- RG_PE1_H_PLL_PREDIV,
- RG_PE1_H_PLL_PREDIV_VAL(0x01));
- dev_info(dev, "Xtal is 40MHz\n");
-- } else if (reg >= 6) { /* 25MHz Xal */
-+ } else if (xtal_mode >= 6) { /* 25MHz Xal */
- mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
- RG_PE1_H_PLL_PREDIV,
- RG_PE1_H_PLL_PREDIV_VAL(0x00));
-@@ -206,7 +211,7 @@ static void mt7621_set_phy_for_ssc(struc
- mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG,
- RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00));
-
-- if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
-+ if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */
- /* set force mode enable of da_pe1_mstckdiv */
- mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG,
- RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV,
+++ /dev/null
-From 4f0f36b67564311a4ce4441510ef94848febbab2 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Sun, 22 Mar 2020 08:21:28 +0100
-Subject: [PATCH] staging: mt7621-pci: avoid to set 'iomem_resource' addresses
-
-Setting up kernel resource 'iomem_resource' for PCI with
-addresses parsed from device tree gots into a conflict within
-the usb xhci driver:
-
-xhci-mtk 1e1c0000.xhci: can't request region for resource [mem 0x1e1c0000-0x1e1c0fff]
-xhci-mtk: probe of 1e1c0000.xhci failed with error -16
-
-Don't assign it and maintain the default addresses for this
-resource seems to fix the problem. Checking legacy driver it
-is being only setting the 'ioport_resource'.
-
-Fixes: 09dd629eeabb ("staging: mt7621-pci: fix io space and properly set resource limits")
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200322072128.4454-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -679,8 +679,6 @@ static int mt7621_pci_probe(struct platf
- }
-
- /* set resources limits */
-- iomem_resource.start = pcie->mem.start;
-- iomem_resource.end = pcie->mem.end;
- ioport_resource.start = pcie->io.start;
- ioport_resource.end = pcie->io.end;
-
+++ /dev/null
-From 5fcded5e857cf66c9592e4be28c4dab4520c9177 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Thu, 9 Apr 2020 13:16:52 +0200
-Subject: [PATCH] staging: mt7621-pci: properly power off dual-ported pcie phy
-
-Pcie phy for pcie0 and pcie1 is shared using a dual ported
-one. Current code was assuming that if nothing is connected
-in pcie0 it won't be also nothing connected in pcie1. This
-assumtion is wrong for some devices such us 'Mikrotik rbm33g'
-and 'ZyXEL LTE3301-PLUS' where only connecting a card to the
-second bus on the phy is possible. For such devices kernel
-hangs in the same point because of the wrong poweroff of the
-phy getting the following trace:
-
-mt7621-pci-phy 1e149000.pcie-phy: PHY for 0xbe149000 (dual port = 1)
-mt7621-pci-phy 1e14a000.pcie-phy: PHY for 0xbe14a000 (dual port = 0)
-mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz
-mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz
-mt7621-pci 1e140000.pcie: pcie0 no card, disable it (RST & CLK)
-[hangs]
-
-The wrong assumption is located in the 'mt7621_pcie_init_ports'
-function where we are just making a power off of the phy for
-slots 0 and 2 if nothing is connected in them. Hence, only
-poweroff the phy if nothing is connected in both slot 0 and
-slot 1 avoiding the kernel to hang.
-
-Fixes: 5737cfe87a9c ("staging: mt7621-pci: avoid to poweroff the phy for slot one")
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200409111652.30964-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-pci/pci-mt7621.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -502,17 +502,25 @@ static void mt7621_pcie_init_ports(struc
-
- mt7621_pcie_reset_ep_deassert(pcie);
-
-+ tmp = NULL;
- list_for_each_entry(port, &pcie->ports, list) {
- u32 slot = port->slot;
-
- if (!mt7621_pcie_port_is_linkup(port)) {
- dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n",
- slot);
-- if (slot != 1)
-- phy_power_off(port->phy);
- mt7621_control_assert(port);
- mt7621_pcie_port_clk_disable(port);
- port->enabled = false;
-+
-+ if (slot == 0) {
-+ tmp = port;
-+ continue;
-+ }
-+
-+ if (slot == 1 && tmp && !tmp->enabled)
-+ phy_power_off(tmp->phy);
-+
- }
- }
- }
+++ /dev/null
-From fab6710e4c51f4eb622f95a08322ab5fdbe3f295 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Mon, 13 Apr 2020 07:59:42 +0200
-Subject: [PATCH] staging: mt7621-pci: fix PCIe interrupt mapping
-
-MT7621 has three assigned interrupts for the pcie. This
-interrupts should properly being mapped taking into account
-which devices are finally connected in which bus according
-to link status. So the irq mappings should be as follows
-according to link status (three bits indicating which devices
-are link up):
-
-* For PCIe Bus 1 slot 0:
- - status = 0x2 || status = 0x6 => IRQ = pcie1_irq (24).
- - status = 0x4 => IRQ = pcie2_irq (25).
- - default => IRQ = pcie0_irq (23).
-* For PCIe Bus 2 slot 0:
- - status = 0x5 || status = 0x6 => IRQ = pcie2_irq (25).
- - default => IRQ = pcie1_irq (24).
-* For PCIe Bus 2 slot 1:
- - status = 0x5 || status = 0x6 => IRQ = pcie2_irq (25).
- - default => IRQ = pcie1_irq (24).
-* For PCIe Bus 3 any slot:
- - default => IRQ = pcie2_irq (25).
-
-Because of this, the function 'of_irq_parse_and_map_pci' cannot
-be used and we need to change device tree information from using
-the 'interrupt-map' and 'interrupt-map-mask' properties into an
-'interrupts' property to be able to get irq information from the
-ports using the 'platform_get_irq' and storing an 'irq-map' into
-the pcie driver data node to properly map correct irq using a
-new 'mt7621_map_irq' function where this map will be read and the
-correct irq returned.
-
-Fixes: 46d093124df4 ("staging: mt7621-pci: improve interrupt mapping")
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Link: https://lore.kernel.org/r/20200413055942.2714-1-sergio.paracuellos@gmail.com
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/staging/mt7621-dts/mt7621.dtsi | 9 +++----
- drivers/staging/mt7621-pci/pci-mt7621.c | 36 +++++++++++++++++++++++--
- 2 files changed, 38 insertions(+), 7 deletions(-)
-
---- a/drivers/staging/mt7621-pci/pci-mt7621.c
-+++ b/drivers/staging/mt7621-pci/pci-mt7621.c
-@@ -97,6 +97,7 @@
- * @pcie_rst: pointer to port reset control
- * @gpio_rst: gpio reset
- * @slot: port slot
-+ * @irq: GIC irq
- * @enabled: indicates if port is enabled
- */
- struct mt7621_pcie_port {
-@@ -107,6 +108,7 @@ struct mt7621_pcie_port {
- struct reset_control *pcie_rst;
- struct gpio_desc *gpio_rst;
- u32 slot;
-+ int irq;
- bool enabled;
- };
-
-@@ -120,6 +122,7 @@ struct mt7621_pcie_port {
- * @dev: Pointer to PCIe device
- * @io_map_base: virtual memory base address for io
- * @ports: pointer to PCIe port information
-+ * @irq_map: irq mapping info according pcie link status
- * @resets_inverted: depends on chip revision
- * reset lines are inverted.
- */
-@@ -135,6 +138,7 @@ struct mt7621_pcie {
- } offset;
- unsigned long io_map_base;
- struct list_head ports;
-+ int irq_map[PCIE_P2P_MAX];
- bool resets_inverted;
- };
-
-@@ -279,6 +283,16 @@ static void setup_cm_memory_region(struc
- }
- }
-
-+static int mt7621_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
-+{
-+ struct mt7621_pcie *pcie = pdev->bus->sysdata;
-+ struct device *dev = pcie->dev;
-+ int irq = pcie->irq_map[slot];
-+
-+ dev_info(dev, "bus=%d slot=%d irq=%d\n", pdev->bus->number, slot, irq);
-+ return irq;
-+}
-+
- static int mt7621_pci_parse_request_of_pci_ranges(struct mt7621_pcie *pcie)
- {
- struct device *dev = pcie->dev;
-@@ -330,6 +344,7 @@ static int mt7621_pcie_parse_port(struct
- {
- struct mt7621_pcie_port *port;
- struct device *dev = pcie->dev;
-+ struct platform_device *pdev = to_platform_device(dev);
- struct device_node *pnode = dev->of_node;
- struct resource regs;
- char name[10];
-@@ -371,6 +386,12 @@ static int mt7621_pcie_parse_port(struct
- port->slot = slot;
- port->pcie = pcie;
-
-+ port->irq = platform_get_irq(pdev, slot);
-+ if (port->irq < 0) {
-+ dev_err(dev, "Failed to get IRQ for PCIe%d\n", slot);
-+ return -ENXIO;
-+ }
-+
- INIT_LIST_HEAD(&port->list);
- list_add_tail(&port->list, &pcie->ports);
-
-@@ -585,13 +606,15 @@ static int mt7621_pcie_init_virtual_brid
- {
- u32 pcie_link_status = 0;
- u32 n;
-- int i;
-+ int i = 0;
- u32 p2p_br_devnum[PCIE_P2P_MAX];
-+ int irqs[PCIE_P2P_MAX];
- struct mt7621_pcie_port *port;
-
- list_for_each_entry(port, &pcie->ports, list) {
- u32 slot = port->slot;
-
-+ irqs[i++] = port->irq;
- if (port->enabled)
- pcie_link_status |= BIT(slot);
- }
-@@ -614,6 +637,15 @@ static int mt7621_pcie_init_virtual_brid
- (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) |
- (p2p_br_devnum[2] << PCIE_P2P_BR_DEVNUM2_SHIFT));
-
-+ /* Assign IRQs */
-+ n = 0;
-+ for (i = 0; i < PCIE_P2P_MAX; i++)
-+ if (pcie_link_status & BIT(i))
-+ pcie->irq_map[n++] = irqs[i];
-+
-+ for (i = n; i < PCIE_P2P_MAX; i++)
-+ pcie->irq_map[i] = -1;
-+
- return 0;
- }
-
-@@ -638,7 +670,7 @@ static int mt7621_pcie_register_host(str
- host->busnr = pcie->busn.start;
- host->dev.parent = pcie->dev;
- host->ops = &mt7621_pci_ops;
-- host->map_irq = of_irq_parse_and_map_pci;
-+ host->map_irq = mt7621_map_irq;
- host->swizzle_irq = pci_common_swizzle;
- host->sysdata = pcie;
-
+++ /dev/null
-From 1f0400d0e2c410b04f246aefb2e9b5155eb4b0bf Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Tue, 13 Oct 2020 10:05:47 +0800
-Subject: mips: ralink: enable zboot support
-
-Some of these ralink devices come with an ancient u-boot which can't
-extract LZMA properly when image gets too big.
-Enable zboot support to get a self-extracting kernel instead of relying
-on broken u-boot support.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -631,6 +631,7 @@ config RALINK
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_SUPPORTS_MIPS16
-+ select SYS_SUPPORTS_ZBOOT
- select SYS_HAS_EARLY_PRINTK
- select CLKDEV_LOOKUP
- select ARCH_HAS_RESET_CONTROLLER
+++ /dev/null
-From 3f9ef7785a9cd69cb75f5e2ea4ca79a24752e496 Mon Sep 17 00:00:00 2001
-From: Sander Vanheule <sander@svanheule.net>
-Date: Wed, 3 Feb 2021 10:21:41 +0100
-Subject: MIPS: ralink: manage low reset lines
-
-Reset lines with indices smaller than 8 are currently considered invalid
-by the rt2880-reset reset controller.
-
-The MT7621 SoC uses a number of these low reset lines. The DTS defines
-reset lines "hsdma", "fe", and "mcm" with respective values 5, 6, and 2.
-As a result of the above restriction, these resets cannot be asserted or
-de-asserted by the reset controller. In cases where the bootloader does
-not de-assert these lines, this results in e.g. the MT7621's internal
-switch staying in reset.
-
-Change the reset controller to only ignore the system reset, so all
-reset lines with index greater than 0 are considered valid.
-
-Signed-off-by: Sander Vanheule <sander@svanheule.net>
-Acked-by: John Crispin <john@phrozen.org>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/ralink/reset.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/mips/ralink/reset.c
-+++ b/arch/mips/ralink/reset.c
-@@ -27,7 +27,7 @@ static int ralink_assert_device(struct r
- {
- u32 val;
-
-- if (id < 8)
-+ if (id == 0)
- return -1;
-
- val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
-@@ -42,7 +42,7 @@ static int ralink_deassert_device(struct
- {
- u32 val;
-
-- if (id < 8)
-+ if (id == 0)
- return -1;
-
- val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
+++ /dev/null
---- a/drivers/misc/Makefile
-+++ b/drivers/misc/Makefile
-@@ -52,6 +52,7 @@ obj-$(CONFIG_ECHO) += echo/
- obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
- obj-$(CONFIG_CXL_BASE) += cxl/
- obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
-+obj-$(CONFIG_SOC_MT7620) += linkit.o
- obj-$(CONFIG_OCXL) += ocxl/
- obj-y += cardreader/
- obj-$(CONFIG_PVPANIC) += pvpanic.o
---- /dev/null
-+++ b/drivers/misc/linkit.c
-@@ -0,0 +1,84 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * publishhed by the Free Software Foundation.
-+ *
-+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/gpio.h>
-+
-+#define LINKIT_LATCH_GPIO 11
-+
-+struct linkit_hw_data {
-+ char board[16];
-+ char rev[16];
-+};
-+
-+static void sanify_string(char *s)
-+{
-+ int i;
-+
-+ for (i = 0; i < 15; i++)
-+ if (s[i] <= 0x20)
-+ s[i] = '\0';
-+ s[15] = '\0';
-+}
-+
-+static int linkit_probe(struct platform_device *pdev)
-+{
-+ struct linkit_hw_data hw;
-+ struct mtd_info *mtd;
-+ size_t retlen;
-+ int ret;
-+
-+ mtd = get_mtd_device_nm("factory");
-+ if (IS_ERR(mtd))
-+ return PTR_ERR(mtd);
-+
-+ ret = mtd_read(mtd, 0x400, sizeof(hw), &retlen, (u_char *) &hw);
-+ put_mtd_device(mtd);
-+
-+ sanify_string(hw.board);
-+ sanify_string(hw.rev);
-+
-+ dev_info(&pdev->dev, "Version : %s\n", hw.board);
-+ dev_info(&pdev->dev, "Revision : %s\n", hw.rev);
-+
-+ if (!strcmp(hw.board, "LINKITS7688")) {
-+ dev_info(&pdev->dev, "setting up bootstrap latch\n");
-+
-+ if (devm_gpio_request(&pdev->dev, LINKIT_LATCH_GPIO, "bootstrap")) {
-+ dev_err(&pdev->dev, "failed to setup bootstrap gpio\n");
-+ return -1;
-+ }
-+ gpio_direction_output(LINKIT_LATCH_GPIO, 0);
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id linkit_match[] = {
-+ { .compatible = "mediatek,linkit" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, linkit_match);
-+
-+static struct platform_driver linkit_driver = {
-+ .probe = linkit_probe,
-+ .driver = {
-+ .name = "mtk-linkit",
-+ .owner = THIS_MODULE,
-+ .of_match_table = linkit_match,
-+ },
-+};
-+
-+int __init linkit_init(void)
-+{
-+ return platform_driver_register(&linkit_driver);
-+}
-+late_initcall_sync(linkit_init);
+++ /dev/null
-From e84e2430ee0e483842b4ff013ae8a6e7e2fa2734 Mon Sep 17 00:00:00 2001
-From: Weijie Gao <weijie.gao@mediatek.com>
-Date: Wed, 1 Apr 2020 02:07:58 +0800
-Subject: [PATCH 1/2] mtd: rawnand: add driver support for MT7621 nand
- flash controller
-
-This patch adds NAND flash controller driver for MediaTek MT7621 SoC.
-
-The NAND flash controller is similar with controllers described in
-mtk_nand.c, except that the controller from MT7621 doesn't support DMA
-transmission, and some registers' offset and fields are different.
-
-Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
----
- drivers/mtd/nand/raw/Kconfig | 8 +
- drivers/mtd/nand/raw/Makefile | 1 +
- drivers/mtd/nand/raw/mt7621_nand.c | 1348 ++++++++++++++++++++++++++++++++++++
- 3 files changed, 1357 insertions(+)
- create mode 100644 drivers/mtd/nand/raw/mt7621_nand.c
-
---- a/drivers/mtd/nand/raw/Kconfig
-+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -391,6 +391,14 @@ config MTD_NAND_QCOM
- Enables support for NAND flash chips on SoCs containing the EBI2 NAND
- controller. This controller is found on IPQ806x SoC.
-
-+config MTD_NAND_MT7621
-+ tristate "MT7621 NAND controller"
-+ depends on SOC_MT7621 || COMPILE_TEST
-+ depends on HAS_IOMEM
-+ help
-+ Enables support for NAND controller on MT7621 SoC.
-+ This driver uses PIO mode for data transmission instead of DMA mode.
-+
- config MTD_NAND_MTK
- tristate "MTK NAND controller"
- depends on ARCH_MEDIATEK || COMPILE_TEST
---- a/drivers/mtd/nand/raw/Makefile
-+++ b/drivers/mtd/nand/raw/Makefile
-@@ -52,6 +52,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n
- obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
- obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
- obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o
-+obj-$(CONFIG_MTD_NAND_MT7621) += mt7621_nand.o
- obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o
- obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o
- obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
---- /dev/null
-+++ b/drivers/mtd/nand/raw/mt7621_nand.c
-@@ -0,0 +1,1350 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * MediaTek MT7621 NAND Flash Controller driver
-+ *
-+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
-+ *
-+ * Author: Weijie Gao <weijie.gao@mediatek.com>
-+ */
-+
-+#include <linux/io.h>
-+#include <linux/clk.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/sizes.h>
-+#include <linux/iopoll.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/rawnand.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/platform_device.h>
-+#include <asm/addrspace.h>
-+
-+/* NFI core registers */
-+#define NFI_CNFG 0x000
-+#define CNFG_OP_MODE_S 12
-+#define CNFG_OP_MODE_M GENMASK(14, 12)
-+#define CNFG_OP_CUSTOM 6
-+#define CNFG_AUTO_FMT_EN BIT(9)
-+#define CNFG_HW_ECC_EN BIT(8)
-+#define CNFG_BYTE_RW BIT(6)
-+#define CNFG_READ_MODE BIT(1)
-+
-+#define NFI_PAGEFMT 0x004
-+#define PAGEFMT_FDM_ECC_S 12
-+#define PAGEFMT_FDM_ECC_M GENMASK(15, 12)
-+#define PAGEFMT_FDM_S 8
-+#define PAGEFMT_FDM_M GENMASK(11, 8)
-+#define PAGEFMT_SPARE_S 4
-+#define PAGEFMT_SPARE_M GENMASK(5, 4)
-+#define PAGEFMT_PAGE_S 0
-+#define PAGEFMT_PAGE_M GENMASK(1, 0)
-+
-+#define NFI_CON 0x008
-+#define CON_NFI_SEC_S 12
-+#define CON_NFI_SEC_M GENMASK(15, 12)
-+#define CON_NFI_BWR BIT(9)
-+#define CON_NFI_BRD BIT(8)
-+#define CON_NFI_RST BIT(1)
-+#define CON_FIFO_FLUSH BIT(0)
-+
-+#define NFI_ACCCON 0x00c
-+#define ACCCON_POECS_S 28
-+#define ACCCON_POECS_MAX 0x0f
-+#define ACCCON_POECS_DEF 3
-+#define ACCCON_PRECS_S 22
-+#define ACCCON_PRECS_MAX 0x3f
-+#define ACCCON_PRECS_DEF 3
-+#define ACCCON_C2R_S 16
-+#define ACCCON_C2R_MAX 0x3f
-+#define ACCCON_C2R_DEF 7
-+#define ACCCON_W2R_S 12
-+#define ACCCON_W2R_MAX 0x0f
-+#define ACCCON_W2R_DEF 7
-+#define ACCCON_WH_S 8
-+#define ACCCON_WH_MAX 0x0f
-+#define ACCCON_WH_DEF 15
-+#define ACCCON_WST_S 4
-+#define ACCCON_WST_MAX 0x0f
-+#define ACCCON_WST_DEF 15
-+#define ACCCON_WST_MIN 3
-+#define ACCCON_RLT_S 0
-+#define ACCCON_RLT_MAX 0x0f
-+#define ACCCON_RLT_DEF 15
-+#define ACCCON_RLT_MIN 3
-+
-+#define NFI_CMD 0x020
-+
-+#define NFI_ADDRNOB 0x030
-+#define ADDR_ROW_NOB_S 4
-+#define ADDR_ROW_NOB_M GENMASK(6, 4)
-+#define ADDR_COL_NOB_S 0
-+#define ADDR_COL_NOB_M GENMASK(2, 0)
-+
-+#define NFI_COLADDR 0x034
-+#define NFI_ROWADDR 0x038
-+
-+#define NFI_STRDATA 0x040
-+#define STR_DATA BIT(0)
-+
-+#define NFI_CNRNB 0x044
-+#define CB2R_TIME_S 4
-+#define CB2R_TIME_M GENMASK(7, 4)
-+#define STR_CNRNB BIT(0)
-+
-+#define NFI_DATAW 0x050
-+#define NFI_DATAR 0x054
-+
-+#define NFI_PIO_DIRDY 0x058
-+#define PIO_DIRDY BIT(0)
-+
-+#define NFI_STA 0x060
-+#define STA_NFI_FSM_S 16
-+#define STA_NFI_FSM_M GENMASK(19, 16)
-+#define STA_FSM_CUSTOM_DATA 14
-+#define STA_BUSY BIT(8)
-+#define STA_ADDR BIT(1)
-+#define STA_CMD BIT(0)
-+
-+#define NFI_ADDRCNTR 0x070
-+#define SEC_CNTR_S 12
-+#define SEC_CNTR_M GENMASK(15, 12)
-+#define SEC_ADDR_S 0
-+#define SEC_ADDR_M GENMASK(9, 0)
-+
-+#define NFI_CSEL 0x090
-+#define CSEL_S 0
-+#define CSEL_M GENMASK(1, 0)
-+
-+#define NFI_FDM0L 0x0a0
-+#define NFI_FDML(n) (0x0a0 + ((n) << 3))
-+
-+#define NFI_FDM0M 0x0a4
-+#define NFI_FDMM(n) (0x0a4 + ((n) << 3))
-+
-+#define NFI_MASTER_STA 0x210
-+#define MAS_ADDR GENMASK(11, 9)
-+#define MAS_RD GENMASK(8, 6)
-+#define MAS_WR GENMASK(5, 3)
-+#define MAS_RDDLY GENMASK(2, 0)
-+
-+/* ECC engine registers */
-+#define ECC_ENCCON 0x000
-+#define ENC_EN BIT(0)
-+
-+#define ECC_ENCCNFG 0x004
-+#define ENC_CNFG_MSG_S 16
-+#define ENC_CNFG_MSG_M GENMASK(28, 16)
-+#define ENC_MODE_S 4
-+#define ENC_MODE_M GENMASK(5, 4)
-+#define ENC_MODE_NFI 1
-+#define ENC_TNUM_S 0
-+#define ENC_TNUM_M GENMASK(2, 0)
-+
-+#define ECC_ENCIDLE 0x00c
-+#define ENC_IDLE BIT(0)
-+
-+#define ECC_DECCON 0x100
-+#define DEC_EN BIT(0)
-+
-+#define ECC_DECCNFG 0x104
-+#define DEC_EMPTY_EN BIT(31)
-+#define DEC_CS_S 16
-+#define DEC_CS_M GENMASK(28, 16)
-+#define DEC_CON_S 12
-+#define DEC_CON_M GENMASK(13, 12)
-+#define DEC_CON_EL 2
-+#define DEC_MODE_S 4
-+#define DEC_MODE_M GENMASK(5, 4)
-+#define DEC_MODE_NFI 1
-+#define DEC_TNUM_S 0
-+#define DEC_TNUM_M GENMASK(2, 0)
-+
-+#define ECC_DECIDLE 0x10c
-+#define DEC_IDLE BIT(1)
-+
-+#define ECC_DECENUM 0x114
-+#define ERRNUM_S 2
-+#define ERRNUM_M GENMASK(3, 0)
-+
-+#define ECC_DECDONE 0x118
-+#define DEC_DONE7 BIT(7)
-+#define DEC_DONE6 BIT(6)
-+#define DEC_DONE5 BIT(5)
-+#define DEC_DONE4 BIT(4)
-+#define DEC_DONE3 BIT(3)
-+#define DEC_DONE2 BIT(2)
-+#define DEC_DONE1 BIT(1)
-+#define DEC_DONE0 BIT(0)
-+
-+#define ECC_DECEL(n) (0x11c + (n) * 4)
-+#define DEC_EL_ODD_S 16
-+#define DEC_EL_EVEN_S 0
-+#define DEC_EL_M 0x1fff
-+#define DEC_EL_BYTE_POS_S 3
-+#define DEC_EL_BIT_POS_M GENMASK(3, 0)
-+
-+#define ECC_FDMADDR 0x13c
-+
-+/* ENCIDLE and DECIDLE */
-+#define ECC_IDLE BIT(0)
-+
-+#define ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt) \
-+ ((tpoecs) << ACCCON_POECS_S | (tprecs) << ACCCON_PRECS_S | \
-+ (tc2r) << ACCCON_C2R_S | (tw2r) << ACCCON_W2R_S | \
-+ (twh) << ACCCON_WH_S | (twst) << ACCCON_WST_S | (trlt))
-+
-+#define MASTER_STA_MASK (MAS_ADDR | MAS_RD | MAS_WR | \
-+ MAS_RDDLY)
-+#define NFI_RESET_TIMEOUT 1000000
-+#define NFI_CORE_TIMEOUT 500000
-+#define ECC_ENGINE_TIMEOUT 500000
-+
-+#define ECC_SECTOR_SIZE 512
-+#define ECC_PARITY_BITS 13
-+
-+#define NFI_FDM_SIZE 8
-+
-+#define MT7621_NFC_NAME "mt7621-nand"
-+
-+struct mt7621_nfc {
-+ struct nand_controller controller;
-+ struct nand_chip nand;
-+ struct clk *nfi_clk;
-+ struct device *dev;
-+
-+ void __iomem *nfi_regs;
-+ void __iomem *ecc_regs;
-+
-+ u32 spare_per_sector;
-+};
-+
-+static const u16 mt7621_nfi_page_size[] = { SZ_512, SZ_2K, SZ_4K };
-+static const u8 mt7621_nfi_spare_size[] = { 16, 26, 27, 28 };
-+static const u8 mt7621_ecc_strength[] = { 4, 6, 8, 10, 12 };
-+
-+static inline u32 nfi_read32(struct mt7621_nfc *nfc, u32 reg)
-+{
-+ return readl(nfc->nfi_regs + reg);
-+}
-+
-+static inline void nfi_write32(struct mt7621_nfc *nfc, u32 reg, u32 val)
-+{
-+ writel(val, nfc->nfi_regs + reg);
-+}
-+
-+static inline u16 nfi_read16(struct mt7621_nfc *nfc, u32 reg)
-+{
-+ return readw(nfc->nfi_regs + reg);
-+}
-+
-+static inline void nfi_write16(struct mt7621_nfc *nfc, u32 reg, u16 val)
-+{
-+ writew(val, nfc->nfi_regs + reg);
-+}
-+
-+static inline void ecc_write16(struct mt7621_nfc *nfc, u32 reg, u16 val)
-+{
-+ writew(val, nfc->ecc_regs + reg);
-+}
-+
-+static inline u32 ecc_read32(struct mt7621_nfc *nfc, u32 reg)
-+{
-+ return readl(nfc->ecc_regs + reg);
-+}
-+
-+static inline void ecc_write32(struct mt7621_nfc *nfc, u32 reg, u32 val)
-+{
-+ return writel(val, nfc->ecc_regs + reg);
-+}
-+
-+static inline u8 *oob_fdm_ptr(struct nand_chip *nand, int sect)
-+{
-+ return nand->oob_poi + sect * NFI_FDM_SIZE;
-+}
-+
-+static inline u8 *oob_ecc_ptr(struct mt7621_nfc *nfc, int sect)
-+{
-+ struct nand_chip *nand = &nfc->nand;
-+
-+ return nand->oob_poi + nand->ecc.steps * NFI_FDM_SIZE +
-+ sect * (nfc->spare_per_sector - NFI_FDM_SIZE);
-+}
-+
-+static inline u8 *page_data_ptr(struct nand_chip *nand, const u8 *buf,
-+ int sect)
-+{
-+ return (u8 *)buf + sect * nand->ecc.size;
-+}
-+
-+static int mt7621_ecc_wait_idle(struct mt7621_nfc *nfc, u32 reg)
-+{
-+ struct device *dev = nfc->dev;
-+ u32 val;
-+ int ret;
-+
-+ ret = readw_poll_timeout_atomic(nfc->ecc_regs + reg, val,
-+ val & ECC_IDLE, 10,
-+ ECC_ENGINE_TIMEOUT);
-+ if (ret) {
-+ dev_warn(dev, "ECC engine timed out entering idle mode\n");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mt7621_ecc_decoder_wait_done(struct mt7621_nfc *nfc, u32 sect)
-+{
-+ struct device *dev = nfc->dev;
-+ u32 val;
-+ int ret;
-+
-+ ret = readw_poll_timeout_atomic(nfc->ecc_regs + ECC_DECDONE, val,
-+ val & (1 << sect), 10,
-+ ECC_ENGINE_TIMEOUT);
-+
-+ if (ret) {
-+ dev_warn(dev, "ECC decoder for sector %d timed out\n",
-+ sect);
-+ return -ETIMEDOUT;
-+ }
-+
-+ return 0;
-+}
-+
-+static void mt7621_ecc_encoder_op(struct mt7621_nfc *nfc, bool enable)
-+{
-+ mt7621_ecc_wait_idle(nfc, ECC_ENCIDLE);
-+ ecc_write16(nfc, ECC_ENCCON, enable ? ENC_EN : 0);
-+}
-+
-+static void mt7621_ecc_decoder_op(struct mt7621_nfc *nfc, bool enable)
-+{
-+ mt7621_ecc_wait_idle(nfc, ECC_DECIDLE);
-+ ecc_write16(nfc, ECC_DECCON, enable ? DEC_EN : 0);
-+}
-+
-+static int mt7621_ecc_correct_check(struct mt7621_nfc *nfc, u8 *sector_buf,
-+ u8 *fdm_buf, u32 sect)
-+{
-+ struct nand_chip *nand = &nfc->nand;
-+ u32 decnum, num_error_bits, fdm_end_bits;
-+ u32 error_locations, error_bit_loc;
-+ u32 error_byte_pos, error_bit_pos;
-+ int bitflips = 0;
-+ u32 i;
-+
-+ decnum = ecc_read32(nfc, ECC_DECENUM);
-+ num_error_bits = (decnum >> (sect << ERRNUM_S)) & ERRNUM_M;
-+ fdm_end_bits = (nand->ecc.size + NFI_FDM_SIZE) << 3;
-+
-+ if (!num_error_bits)
-+ return 0;
-+
-+ if (num_error_bits == ERRNUM_M)
-+ return -1;
-+
-+ for (i = 0; i < num_error_bits; i++) {
-+ error_locations = ecc_read32(nfc, ECC_DECEL(i / 2));
-+ error_bit_loc = (error_locations >> ((i % 2) * DEC_EL_ODD_S)) &
-+ DEC_EL_M;
-+ error_byte_pos = error_bit_loc >> DEC_EL_BYTE_POS_S;
-+ error_bit_pos = error_bit_loc & DEC_EL_BIT_POS_M;
-+
-+ if (error_bit_loc < (nand->ecc.size << 3)) {
-+ if (sector_buf) {
-+ sector_buf[error_byte_pos] ^=
-+ (1 << error_bit_pos);
-+ }
-+ } else if (error_bit_loc < fdm_end_bits) {
-+ if (fdm_buf) {
-+ fdm_buf[error_byte_pos - nand->ecc.size] ^=
-+ (1 << error_bit_pos);
-+ }
-+ }
-+
-+ bitflips++;
-+ }
-+
-+ return bitflips;
-+}
-+
-+static int mt7621_nfc_wait_write_completion(struct mt7621_nfc *nfc,
-+ struct nand_chip *nand)
-+{
-+ struct device *dev = nfc->dev;
-+ u16 val;
-+ int ret;
-+
-+ ret = readw_poll_timeout_atomic(nfc->nfi_regs + NFI_ADDRCNTR, val,
-+ ((val & SEC_CNTR_M) >> SEC_CNTR_S) >= nand->ecc.steps, 10,
-+ NFI_CORE_TIMEOUT);
-+
-+ if (ret) {
-+ dev_warn(dev, "NFI core write operation timed out\n");
-+ return -ETIMEDOUT;
-+ }
-+
-+ return ret;
-+}
-+
-+static void mt7621_nfc_hw_reset(struct mt7621_nfc *nfc)
-+{
-+ u32 val;
-+ int ret;
-+
-+ /* reset all registers and force the NFI master to terminate */
-+ nfi_write16(nfc, NFI_CON, CON_FIFO_FLUSH | CON_NFI_RST);
-+
-+ /* wait for the master to finish the last transaction */
-+ ret = readw_poll_timeout(nfc->nfi_regs + NFI_MASTER_STA, val,
-+ !(val & MASTER_STA_MASK), 50,
-+ NFI_RESET_TIMEOUT);
-+ if (ret) {
-+ dev_warn(nfc->dev, "Failed to reset NFI master in %dms\n",
-+ NFI_RESET_TIMEOUT);
-+ }
-+
-+ /* ensure any status register affected by the NFI master is reset */
-+ nfi_write16(nfc, NFI_CON, CON_FIFO_FLUSH | CON_NFI_RST);
-+ nfi_write16(nfc, NFI_STRDATA, 0);
-+}
-+
-+static inline void mt7621_nfc_hw_init(struct mt7621_nfc *nfc)
-+{
-+ u32 acccon;
-+
-+ /*
-+ * CNRNB: nand ready/busy register
-+ * -------------------------------
-+ * 7:4: timeout register for polling the NAND busy/ready signal
-+ * 0 : poll the status of the busy/ready signal after [7:4]*16 cycles.
-+ */
-+ nfi_write16(nfc, NFI_CNRNB, CB2R_TIME_M | STR_CNRNB);
-+
-+ mt7621_nfc_hw_reset(nfc);
-+
-+ /* Apply default access timing */
-+ acccon = ACCTIMING(ACCCON_POECS_DEF, ACCCON_PRECS_DEF, ACCCON_C2R_DEF,
-+ ACCCON_W2R_DEF, ACCCON_WH_DEF, ACCCON_WST_DEF,
-+ ACCCON_RLT_DEF);
-+
-+ nfi_write32(nfc, NFI_ACCCON, acccon);
-+}
-+
-+static int mt7621_nfc_send_command(struct mt7621_nfc *nfc, u8 command)
-+{
-+ struct device *dev = nfc->dev;
-+ u32 val;
-+ int ret;
-+
-+ nfi_write32(nfc, NFI_CMD, command);
-+
-+ ret = readl_poll_timeout_atomic(nfc->nfi_regs + NFI_STA, val,
-+ !(val & STA_CMD), 10,
-+ NFI_CORE_TIMEOUT);
-+ if (ret) {
-+ dev_warn(dev, "NFI core timed out entering command mode\n");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mt7621_nfc_send_address_byte(struct mt7621_nfc *nfc, int addr)
-+{
-+ struct device *dev = nfc->dev;
-+ u32 val;
-+ int ret;
-+
-+ nfi_write32(nfc, NFI_COLADDR, addr);
-+ nfi_write32(nfc, NFI_ROWADDR, 0);
-+ nfi_write16(nfc, NFI_ADDRNOB, 1);
-+
-+ ret = readl_poll_timeout_atomic(nfc->nfi_regs + NFI_STA, val,
-+ !(val & STA_ADDR), 10,
-+ NFI_CORE_TIMEOUT);
-+ if (ret) {
-+ dev_warn(dev, "NFI core timed out entering address mode\n");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mt7621_nfc_send_address(struct mt7621_nfc *nfc, const u8 *addr,
-+ unsigned int naddrs)
-+{
-+ int ret;
-+
-+ while (naddrs) {
-+ ret = mt7621_nfc_send_address_byte(nfc, *addr);
-+ if (ret)
-+ return ret;
-+
-+ addr++;
-+ naddrs--;
-+ }
-+
-+ return 0;
-+}
-+
-+static void mt7621_nfc_wait_pio_ready(struct mt7621_nfc *nfc)
-+{
-+ struct device *dev = nfc->dev;
-+ int ret;
-+ u16 val;
-+
-+ ret = readw_poll_timeout_atomic(nfc->nfi_regs + NFI_PIO_DIRDY, val,
-+ val & PIO_DIRDY, 10,
-+ NFI_CORE_TIMEOUT);
-+ if (ret < 0)
-+ dev_err(dev, "NFI core PIO mode not ready\n");
-+}
-+
-+static u32 mt7621_nfc_pio_read(struct mt7621_nfc *nfc, bool br)
-+{
-+ u32 reg;
-+
-+ /* after each byte read, the NFI_STA reg is reset by the hardware */
-+ reg = (nfi_read32(nfc, NFI_STA) & STA_NFI_FSM_M) >> STA_NFI_FSM_S;
-+ if (reg != STA_FSM_CUSTOM_DATA) {
-+ reg = nfi_read16(nfc, NFI_CNFG);
-+ reg |= CNFG_READ_MODE | CNFG_BYTE_RW;
-+ if (!br)
-+ reg &= ~CNFG_BYTE_RW;
-+ nfi_write16(nfc, NFI_CNFG, reg);
-+
-+ /*
-+ * set to max sector to allow the HW to continue reading over
-+ * unaligned accesses
-+ */
-+ nfi_write16(nfc, NFI_CON, CON_NFI_SEC_M | CON_NFI_BRD);
-+
-+ /* trigger to fetch data */
-+ nfi_write16(nfc, NFI_STRDATA, STR_DATA);
-+ }
-+
-+ mt7621_nfc_wait_pio_ready(nfc);
-+
-+ return nfi_read32(nfc, NFI_DATAR);
-+}
-+
-+static void mt7621_nfc_read_data(struct mt7621_nfc *nfc, u8 *buf, u32 len)
-+{
-+ while (((uintptr_t)buf & 3) && len) {
-+ *buf = mt7621_nfc_pio_read(nfc, true);
-+ buf++;
-+ len--;
-+ }
-+
-+ while (len >= 4) {
-+ *(u32 *)buf = mt7621_nfc_pio_read(nfc, false);
-+ buf += 4;
-+ len -= 4;
-+ }
-+
-+ while (len) {
-+ *buf = mt7621_nfc_pio_read(nfc, true);
-+ buf++;
-+ len--;
-+ }
-+}
-+
-+static void mt7621_nfc_read_data_discard(struct mt7621_nfc *nfc, u32 len)
-+{
-+ while (len >= 4) {
-+ mt7621_nfc_pio_read(nfc, false);
-+ len -= 4;
-+ }
-+
-+ while (len) {
-+ mt7621_nfc_pio_read(nfc, true);
-+ len--;
-+ }
-+}
-+
-+static void mt7621_nfc_pio_write(struct mt7621_nfc *nfc, u32 val, bool bw)
-+{
-+ u32 reg;
-+
-+ reg = (nfi_read32(nfc, NFI_STA) & STA_NFI_FSM_M) >> STA_NFI_FSM_S;
-+ if (reg != STA_FSM_CUSTOM_DATA) {
-+ reg = nfi_read16(nfc, NFI_CNFG);
-+ reg &= ~(CNFG_READ_MODE | CNFG_BYTE_RW);
-+ if (bw)
-+ reg |= CNFG_BYTE_RW;
-+ nfi_write16(nfc, NFI_CNFG, reg);
-+
-+ nfi_write16(nfc, NFI_CON, CON_NFI_SEC_M | CON_NFI_BWR);
-+ nfi_write16(nfc, NFI_STRDATA, STR_DATA);
-+ }
-+
-+ mt7621_nfc_wait_pio_ready(nfc);
-+ nfi_write32(nfc, NFI_DATAW, val);
-+}
-+
-+static void mt7621_nfc_write_data(struct mt7621_nfc *nfc, const u8 *buf,
-+ u32 len)
-+{
-+ while (((uintptr_t)buf & 3) && len) {
-+ mt7621_nfc_pio_write(nfc, *buf, true);
-+ buf++;
-+ len--;
-+ }
-+
-+ while (len >= 4) {
-+ mt7621_nfc_pio_write(nfc, *(const u32 *)buf, false);
-+ buf += 4;
-+ len -= 4;
-+ }
-+
-+ while (len) {
-+ mt7621_nfc_pio_write(nfc, *buf, true);
-+ buf++;
-+ len--;
-+ }
-+}
-+
-+static void mt7621_nfc_write_data_empty(struct mt7621_nfc *nfc, u32 len)
-+{
-+ while (len >= 4) {
-+ mt7621_nfc_pio_write(nfc, 0xffffffff, false);
-+ len -= 4;
-+ }
-+
-+ while (len) {
-+ mt7621_nfc_pio_write(nfc, 0xff, true);
-+ len--;
-+ }
-+}
-+
-+static int mt7621_nfc_dev_ready(struct mt7621_nfc *nfc,
-+ unsigned int timeout_ms)
-+{
-+ u32 val;
-+
-+ return readl_poll_timeout_atomic(nfc->nfi_regs + NFI_STA, val,
-+ !(val & STA_BUSY), 10,
-+ timeout_ms * 1000);
-+}
-+
-+static int mt7621_nfc_exec_instr(struct nand_chip *nand,
-+ const struct nand_op_instr *instr)
-+{
-+ struct mt7621_nfc *nfc = nand_get_controller_data(nand);
-+
-+ switch (instr->type) {
-+ case NAND_OP_CMD_INSTR:
-+ mt7621_nfc_hw_reset(nfc);
-+ nfi_write16(nfc, NFI_CNFG, CNFG_OP_CUSTOM << CNFG_OP_MODE_S);
-+ return mt7621_nfc_send_command(nfc, instr->ctx.cmd.opcode);
-+ case NAND_OP_ADDR_INSTR:
-+ return mt7621_nfc_send_address(nfc, instr->ctx.addr.addrs,
-+ instr->ctx.addr.naddrs);
-+ case NAND_OP_DATA_IN_INSTR:
-+ mt7621_nfc_read_data(nfc, instr->ctx.data.buf.in,
-+ instr->ctx.data.len);
-+ return 0;
-+ case NAND_OP_DATA_OUT_INSTR:
-+ mt7621_nfc_write_data(nfc, instr->ctx.data.buf.out,
-+ instr->ctx.data.len);
-+ return 0;
-+ case NAND_OP_WAITRDY_INSTR:
-+ return mt7621_nfc_dev_ready(nfc,
-+ instr->ctx.waitrdy.timeout_ms);
-+ default:
-+ WARN_ONCE(1, "unsupported NAND instruction type: %d\n",
-+ instr->type);
-+
-+ return -EINVAL;
-+ }
-+}
-+
-+static int mt7621_nfc_exec_op(struct nand_chip *nand,
-+ const struct nand_operation *op, bool check_only)
-+{
-+ struct mt7621_nfc *nfc = nand_get_controller_data(nand);
-+ int i, ret;
-+
-+ if (check_only)
-+ return 0;
-+
-+ /* Only CS0 available */
-+ nfi_write16(nfc, NFI_CSEL, 0);
-+
-+ for (i = 0; i < op->ninstrs; i++) {
-+ ret = mt7621_nfc_exec_instr(nand, &op->instrs[i]);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mt7621_nfc_setup_data_interface(struct nand_chip *nand, int csline,
-+ const struct nand_data_interface *conf)
-+{
-+ struct mt7621_nfc *nfc = nand_get_controller_data(nand);
-+ const struct nand_sdr_timings *timings;
-+ u32 acccon, temp, rate, tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt;
-+
-+ if (!nfc->nfi_clk)
-+ return -ENOTSUPP;
-+
-+ timings = nand_get_sdr_timings(conf);
-+ if (IS_ERR(timings))
-+ return -ENOTSUPP;
-+
-+ rate = clk_get_rate(nfc->nfi_clk);
-+
-+ /* turn clock rate into KHZ */
-+ rate /= 1000;
-+
-+ tpoecs = max(timings->tALH_min, timings->tCLH_min) / 1000;
-+ tpoecs = DIV_ROUND_UP(tpoecs * rate, 1000000);
-+ tpoecs = min_t(u32, tpoecs, ACCCON_POECS_MAX);
-+
-+ tprecs = max(timings->tCLS_min, timings->tALS_min) / 1000;
-+ tprecs = DIV_ROUND_UP(tprecs * rate, 1000000);
-+ tprecs = min_t(u32, tprecs, ACCCON_PRECS_MAX);
-+
-+ /* sdr interface has no tCR which means CE# low to RE# low */
-+ tc2r = 0;
-+
-+ tw2r = timings->tWHR_min / 1000;
-+ tw2r = DIV_ROUND_UP(tw2r * rate, 1000000);
-+ tw2r = DIV_ROUND_UP(tw2r - 1, 2);
-+ tw2r = min_t(u32, tw2r, ACCCON_W2R_MAX);
-+
-+ twh = max(timings->tREH_min, timings->tWH_min) / 1000;
-+ twh = DIV_ROUND_UP(twh * rate, 1000000) - 1;
-+ twh = min_t(u32, twh, ACCCON_WH_MAX);
-+
-+ /* Calculate real WE#/RE# hold time in nanosecond */
-+ temp = (twh + 1) * 1000000 / rate;
-+ /* nanosecond to picosecond */
-+ temp *= 1000;
-+
-+ /*
-+ * WE# low level time should be expaned to meet WE# pulse time
-+ * and WE# cycle time at the same time.
-+ */
-+ if (temp < timings->tWC_min)
-+ twst = timings->tWC_min - temp;
-+ else
-+ twst = 0;
-+ twst = max(timings->tWP_min, twst) / 1000;
-+ twst = DIV_ROUND_UP(twst * rate, 1000000) - 1;
-+ twst = min_t(u32, twst, ACCCON_WST_MAX);
-+
-+ /*
-+ * RE# low level time should be expaned to meet RE# pulse time
-+ * and RE# cycle time at the same time.
-+ */
-+ if (temp < timings->tRC_min)
-+ trlt = timings->tRC_min - temp;
-+ else
-+ trlt = 0;
-+ trlt = max(trlt, timings->tRP_min) / 1000;
-+ trlt = DIV_ROUND_UP(trlt * rate, 1000000) - 1;
-+ trlt = min_t(u32, trlt, ACCCON_RLT_MAX);
-+
-+ if (csline == NAND_DATA_IFACE_CHECK_ONLY) {
-+ if (twst < ACCCON_WST_MIN || trlt < ACCCON_RLT_MIN)
-+ return -ENOTSUPP;
-+ }
-+
-+ acccon = ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt);
-+
-+ dev_info(nfc->dev, "Using programmed access timing: %08x\n", acccon);
-+
-+ nfi_write32(nfc, NFI_ACCCON, acccon);
-+
-+ return 0;
-+}
-+
-+static int mt7621_nfc_calc_ecc_strength(struct mt7621_nfc *nfc,
-+ u32 avail_ecc_bytes)
-+{
-+ struct nand_chip *nand = &nfc->nand;
-+ struct mtd_info *mtd = nand_to_mtd(nand);
-+ u32 strength;
-+ int i;
-+
-+ strength = avail_ecc_bytes * 8 / ECC_PARITY_BITS;
-+
-+ /* Find the closest supported ecc strength */
-+ for (i = ARRAY_SIZE(mt7621_ecc_strength) - 1; i >= 0; i--) {
-+ if (mt7621_ecc_strength[i] <= strength)
-+ break;
-+ }
-+
-+ if (unlikely(i < 0)) {
-+ dev_err(nfc->dev, "OOB size (%u) is not supported\n",
-+ mtd->oobsize);
-+ return -EINVAL;
-+ }
-+
-+ nand->ecc.strength = mt7621_ecc_strength[i];
-+ nand->ecc.bytes =
-+ DIV_ROUND_UP(nand->ecc.strength * ECC_PARITY_BITS, 8);
-+
-+ dev_info(nfc->dev, "ECC strength adjusted to %u bits\n",
-+ nand->ecc.strength);
-+
-+ return i;
-+}
-+
-+static int mt7621_nfc_set_spare_per_sector(struct mt7621_nfc *nfc)
-+{
-+ struct nand_chip *nand = &nfc->nand;
-+ struct mtd_info *mtd = nand_to_mtd(nand);
-+ u32 size;
-+ int i;
-+
-+ size = nand->ecc.bytes + NFI_FDM_SIZE;
-+
-+ /* Find the closest supported spare size */
-+ for (i = 0; i < ARRAY_SIZE(mt7621_nfi_spare_size); i++) {
-+ if (mt7621_nfi_spare_size[i] >= size)
-+ break;
-+ }
-+
-+ if (unlikely(i >= ARRAY_SIZE(mt7621_nfi_spare_size))) {
-+ dev_err(nfc->dev, "OOB size (%u) is not supported\n",
-+ mtd->oobsize);
-+ return -EINVAL;
-+ }
-+
-+ nfc->spare_per_sector = mt7621_nfi_spare_size[i];
-+
-+ return i;
-+}
-+
-+static int mt7621_nfc_ecc_init(struct mt7621_nfc *nfc)
-+{
-+ struct nand_chip *nand = &nfc->nand;
-+ struct mtd_info *mtd = nand_to_mtd(nand);
-+ u32 spare_per_sector, encode_block_size, decode_block_size;
-+ u32 ecc_enccfg, ecc_deccfg;
-+ int ecc_cap;
-+
-+ /* Only hardware ECC mode is supported */
-+ if (nand->ecc.mode != NAND_ECC_HW_SYNDROME) {
-+ dev_err(nfc->dev, "Only hardware ECC mode is supported\n");
-+ return -EINVAL;
-+ }
-+
-+ nand->ecc.size = ECC_SECTOR_SIZE;
-+ nand->ecc.steps = mtd->writesize / nand->ecc.size;
-+
-+ spare_per_sector = mtd->oobsize / nand->ecc.steps;
-+
-+ ecc_cap = mt7621_nfc_calc_ecc_strength(nfc,
-+ spare_per_sector - NFI_FDM_SIZE);
-+ if (ecc_cap < 0)
-+ return ecc_cap;
-+
-+ /* Sector + FDM */
-+ encode_block_size = (nand->ecc.size + NFI_FDM_SIZE) * 8;
-+ ecc_enccfg = ecc_cap | (ENC_MODE_NFI << ENC_MODE_S) |
-+ (encode_block_size << ENC_CNFG_MSG_S);
-+
-+ /* Sector + FDM + ECC parity bits */
-+ decode_block_size = ((nand->ecc.size + NFI_FDM_SIZE) * 8) +
-+ nand->ecc.strength * ECC_PARITY_BITS;
-+ ecc_deccfg = ecc_cap | (DEC_MODE_NFI << DEC_MODE_S) |
-+ (decode_block_size << DEC_CS_S) |
-+ (DEC_CON_EL << DEC_CON_S) | DEC_EMPTY_EN;
-+
-+ mt7621_ecc_encoder_op(nfc, false);
-+ ecc_write32(nfc, ECC_ENCCNFG, ecc_enccfg);
-+
-+ mt7621_ecc_decoder_op(nfc, false);
-+ ecc_write32(nfc, ECC_DECCNFG, ecc_deccfg);
-+
-+ return 0;
-+}
-+
-+static int mt7621_nfc_set_page_format(struct mt7621_nfc *nfc)
-+{
-+ struct nand_chip *nand = &nfc->nand;
-+ struct mtd_info *mtd = nand_to_mtd(nand);
-+ int i, spare_size;
-+ u32 pagefmt;
-+
-+ spare_size = mt7621_nfc_set_spare_per_sector(nfc);
-+ if (spare_size < 0)
-+ return spare_size;
-+
-+ for (i = 0; i < ARRAY_SIZE(mt7621_nfi_page_size); i++) {
-+ if (mt7621_nfi_page_size[i] == mtd->writesize)
-+ break;
-+ }
-+
-+ if (unlikely(i >= ARRAY_SIZE(mt7621_nfi_page_size))) {
-+ dev_err(nfc->dev, "Page size (%u) is not supported\n",
-+ mtd->writesize);
-+ return -EINVAL;
-+ }
-+
-+ pagefmt = i | (spare_size << PAGEFMT_SPARE_S) |
-+ (NFI_FDM_SIZE << PAGEFMT_FDM_S) |
-+ (NFI_FDM_SIZE << PAGEFMT_FDM_ECC_S);
-+
-+ nfi_write16(nfc, NFI_PAGEFMT, pagefmt);
-+
-+ return 0;
-+}
-+
-+static int mt7621_nfc_attach_chip(struct nand_chip *nand)
-+{
-+ struct mt7621_nfc *nfc = nand_get_controller_data(nand);
-+ int ret;
-+
-+ if (nand->options & NAND_BUSWIDTH_16) {
-+ dev_err(nfc->dev, "16-bit buswidth is not supported");
-+ return -EINVAL;
-+ }
-+
-+ ret = mt7621_nfc_ecc_init(nfc);
-+ if (ret)
-+ return ret;
-+
-+ return mt7621_nfc_set_page_format(nfc);
-+}
-+
-+static const struct nand_controller_ops mt7621_nfc_controller_ops = {
-+ .attach_chip = mt7621_nfc_attach_chip,
-+ .exec_op = mt7621_nfc_exec_op,
-+ .setup_data_interface = mt7621_nfc_setup_data_interface,
-+};
-+
-+static int mt7621_nfc_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oob_region)
-+{
-+ struct nand_chip *nand = mtd_to_nand(mtd);
-+
-+ if (section >= nand->ecc.steps)
-+ return -ERANGE;
-+
-+ oob_region->length = NFI_FDM_SIZE - 1;
-+ oob_region->offset = section * NFI_FDM_SIZE + 1;
-+
-+ return 0;
-+}
-+
-+static int mt7621_nfc_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oob_region)
-+{
-+ struct nand_chip *nand = mtd_to_nand(mtd);
-+
-+ if (section)
-+ return -ERANGE;
-+
-+ oob_region->offset = NFI_FDM_SIZE * nand->ecc.steps;
-+ oob_region->length = mtd->oobsize - oob_region->offset;
-+
-+ return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops mt7621_nfc_ooblayout_ops = {
-+ .free = mt7621_nfc_ooblayout_free,
-+ .ecc = mt7621_nfc_ooblayout_ecc,
-+};
-+
-+static void mt7621_nfc_write_fdm(struct mt7621_nfc *nfc)
-+{
-+ struct nand_chip *nand = &nfc->nand;
-+ u32 vall, valm;
-+ u8 *oobptr;
-+ int i, j;
-+
-+ for (i = 0; i < nand->ecc.steps; i++) {
-+ vall = 0;
-+ valm = 0;
-+ oobptr = oob_fdm_ptr(nand, i);
-+
-+ for (j = 0; j < 4; j++)
-+ vall |= (u32)oobptr[j] << (j * 8);
-+
-+ for (j = 0; j < 4; j++)
-+ valm |= (u32)oobptr[j + 4] << ((j - 4) * 8);
-+
-+ nfi_write32(nfc, NFI_FDML(i), vall);
-+ nfi_write32(nfc, NFI_FDMM(i), valm);
-+ }
-+}
-+
-+static void mt7621_nfc_read_sector_fdm(struct mt7621_nfc *nfc, u32 sect)
-+{
-+ struct nand_chip *nand = &nfc->nand;
-+ u32 vall, valm;
-+ u8 *oobptr;
-+ int i;
-+
-+ vall = nfi_read32(nfc, NFI_FDML(sect));
-+ valm = nfi_read32(nfc, NFI_FDMM(sect));
-+ oobptr = oob_fdm_ptr(nand, sect);
-+
-+ for (i = 0; i < 4; i++)
-+ oobptr[i] = (vall >> (i * 8)) & 0xff;
-+
-+ for (i = 0; i < 4; i++)
-+ oobptr[i + 4] = (valm >> (i * 8)) & 0xff;
-+}
-+
-+static int mt7621_nfc_read_page_hwecc(struct nand_chip *nand, uint8_t *buf,
-+ int oob_required, int page)
-+{
-+ struct mt7621_nfc *nfc = nand_get_controller_data(nand);
-+ struct mtd_info *mtd = nand_to_mtd(nand);
-+ int bitflips = 0;
-+ int rc, i;
-+
-+ nand_read_page_op(nand, page, 0, NULL, 0);
-+
-+ nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) |
-+ CNFG_READ_MODE | CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
-+
-+ mt7621_ecc_decoder_op(nfc, true);
-+
-+ nfi_write16(nfc, NFI_CON,
-+ CON_NFI_BRD | (nand->ecc.steps << CON_NFI_SEC_S));
-+
-+ for (i = 0; i < nand->ecc.steps; i++) {
-+ if (buf)
-+ mt7621_nfc_read_data(nfc, page_data_ptr(nand, buf, i),
-+ nand->ecc.size);
-+ else
-+ mt7621_nfc_read_data_discard(nfc, nand->ecc.size);
-+
-+ rc = mt7621_ecc_decoder_wait_done(nfc, i);
-+
-+ mt7621_nfc_read_sector_fdm(nfc, i);
-+
-+ if (rc < 0) {
-+ bitflips = -EIO;
-+ continue;
-+ }
-+
-+ rc = mt7621_ecc_correct_check(nfc,
-+ buf ? page_data_ptr(nand, buf, i) : NULL,
-+ oob_fdm_ptr(nand, i), i);
-+
-+ if (rc < 0) {
-+ dev_warn(nfc->dev,
-+ "Uncorrectable ECC error at page %d.%d\n",
-+ page, i);
-+ bitflips = -EBADMSG;
-+ mtd->ecc_stats.failed++;
-+ } else if (bitflips >= 0) {
-+ bitflips += rc;
-+ mtd->ecc_stats.corrected += rc;
-+ }
-+ }
-+
-+ mt7621_ecc_decoder_op(nfc, false);
-+
-+ nfi_write16(nfc, NFI_CON, 0);
-+
-+ return bitflips;
-+}
-+
-+static int mt7621_nfc_read_page_raw(struct nand_chip *nand, uint8_t *buf,
-+ int oob_required, int page)
-+{
-+ struct mt7621_nfc *nfc = nand_get_controller_data(nand);
-+ int i;
-+
-+ nand_read_page_op(nand, page, 0, NULL, 0);
-+
-+ nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) |
-+ CNFG_READ_MODE);
-+
-+ nfi_write16(nfc, NFI_CON,
-+ CON_NFI_BRD | (nand->ecc.steps << CON_NFI_SEC_S));
-+
-+ for (i = 0; i < nand->ecc.steps; i++) {
-+ /* Read data */
-+ if (buf)
-+ mt7621_nfc_read_data(nfc, page_data_ptr(nand, buf, i),
-+ nand->ecc.size);
-+ else
-+ mt7621_nfc_read_data_discard(nfc, nand->ecc.size);
-+
-+ /* Read FDM */
-+ mt7621_nfc_read_data(nfc, oob_fdm_ptr(nand, i), NFI_FDM_SIZE);
-+
-+ /* Read ECC parity data */
-+ mt7621_nfc_read_data(nfc, oob_ecc_ptr(nfc, i),
-+ nfc->spare_per_sector - NFI_FDM_SIZE);
-+ }
-+
-+ nfi_write16(nfc, NFI_CON, 0);
-+
-+ return 0;
-+}
-+
-+static int mt7621_nfc_read_oob_hwecc(struct nand_chip *nand, int page)
-+{
-+ return mt7621_nfc_read_page_hwecc(nand, NULL, 1, page);
-+}
-+
-+static int mt7621_nfc_read_oob_raw(struct nand_chip *nand, int page)
-+{
-+ return mt7621_nfc_read_page_raw(nand, NULL, 1, page);
-+}
-+
-+static int mt7621_nfc_check_empty_page(struct nand_chip *nand, const u8 *buf)
-+{
-+ struct mtd_info *mtd = nand_to_mtd(nand);
-+ uint32_t i, j;
-+ u8 *oobptr;
-+
-+ if (buf) {
-+ for (i = 0; i < mtd->writesize; i++)
-+ if (buf[i] != 0xff)
-+ return 0;
-+ }
-+
-+ for (i = 0; i < nand->ecc.steps; i++) {
-+ oobptr = oob_fdm_ptr(nand, i);
-+ for (j = 0; j < NFI_FDM_SIZE; j++)
-+ if (oobptr[j] != 0xff)
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static int mt7621_nfc_write_page_hwecc(struct nand_chip *nand,
-+ const uint8_t *buf, int oob_required,
-+ int page)
-+{
-+ struct mt7621_nfc *nfc = nand_get_controller_data(nand);
-+ struct mtd_info *mtd = nand_to_mtd(nand);
-+
-+ if (mt7621_nfc_check_empty_page(nand, buf)) {
-+ /*
-+ * MT7621 ECC engine always generates parity code for input
-+ * pages, even for empty pages. Doing so will write back ECC
-+ * parity code to the oob region, which means such pages will
-+ * no longer be empty pages.
-+ *
-+ * To avoid this, stop write operation if current page is an
-+ * empty page.
-+ */
-+ return 0;
-+ }
-+
-+ nand_prog_page_begin_op(nand, page, 0, NULL, 0);
-+
-+ nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) |
-+ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
-+
-+ mt7621_ecc_encoder_op(nfc, true);
-+
-+ mt7621_nfc_write_fdm(nfc);
-+
-+ nfi_write16(nfc, NFI_CON,
-+ CON_NFI_BWR | (nand->ecc.steps << CON_NFI_SEC_S));
-+
-+ if (buf)
-+ mt7621_nfc_write_data(nfc, buf, mtd->writesize);
-+ else
-+ mt7621_nfc_write_data_empty(nfc, mtd->writesize);
-+
-+ mt7621_nfc_wait_write_completion(nfc, nand);
-+
-+ mt7621_ecc_encoder_op(nfc, false);
-+
-+ nfi_write16(nfc, NFI_CON, 0);
-+
-+ return nand_prog_page_end_op(nand);
-+}
-+
-+static int mt7621_nfc_write_page_raw(struct nand_chip *nand,
-+ const uint8_t *buf, int oob_required,
-+ int page)
-+{
-+ struct mt7621_nfc *nfc = nand_get_controller_data(nand);
-+ int i;
-+
-+ nand_prog_page_begin_op(nand, page, 0, NULL, 0);
-+
-+ nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S));
-+
-+ nfi_write16(nfc, NFI_CON,
-+ CON_NFI_BWR | (nand->ecc.steps << CON_NFI_SEC_S));
-+
-+ for (i = 0; i < nand->ecc.steps; i++) {
-+ /* Write data */
-+ if (buf)
-+ mt7621_nfc_write_data(nfc, page_data_ptr(nand, buf, i),
-+ nand->ecc.size);
-+ else
-+ mt7621_nfc_write_data_empty(nfc, nand->ecc.size);
-+
-+ /* Write FDM */
-+ mt7621_nfc_write_data(nfc, oob_fdm_ptr(nand, i),
-+ NFI_FDM_SIZE);
-+
-+ /* Write dummy ECC parity data */
-+ mt7621_nfc_write_data_empty(nfc, nfc->spare_per_sector -
-+ NFI_FDM_SIZE);
-+ }
-+
-+ mt7621_nfc_wait_write_completion(nfc, nand);
-+
-+ nfi_write16(nfc, NFI_CON, 0);
-+
-+ return nand_prog_page_end_op(nand);
-+}
-+
-+static int mt7621_nfc_write_oob_hwecc(struct nand_chip *nand, int page)
-+{
-+ return mt7621_nfc_write_page_hwecc(nand, NULL, 1, page);
-+}
-+
-+static int mt7621_nfc_write_oob_raw(struct nand_chip *nand, int page)
-+{
-+ return mt7621_nfc_write_page_raw(nand, NULL, 1, page);
-+}
-+
-+static int mt7621_nfc_init_chip(struct mt7621_nfc *nfc)
-+{
-+ struct nand_chip *nand = &nfc->nand;
-+ struct mtd_info *mtd;
-+ int ret;
-+
-+ nand->controller = &nfc->controller;
-+ nand_set_controller_data(nand, (void *)nfc);
-+ nand_set_flash_node(nand, nfc->dev->of_node);
-+
-+ nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_NO_SUBPAGE_WRITE;
-+ if (!nfc->nfi_clk)
-+ nand->options |= NAND_KEEP_TIMINGS;
-+
-+ nand->ecc.mode = NAND_ECC_HW_SYNDROME;
-+ nand->ecc.read_page = mt7621_nfc_read_page_hwecc;
-+ nand->ecc.read_page_raw = mt7621_nfc_read_page_raw;
-+ nand->ecc.write_page = mt7621_nfc_write_page_hwecc;
-+ nand->ecc.write_page_raw = mt7621_nfc_write_page_raw;
-+ nand->ecc.read_oob = mt7621_nfc_read_oob_hwecc;
-+ nand->ecc.read_oob_raw = mt7621_nfc_read_oob_raw;
-+ nand->ecc.write_oob = mt7621_nfc_write_oob_hwecc;
-+ nand->ecc.write_oob_raw = mt7621_nfc_write_oob_raw;
-+
-+ mtd = nand_to_mtd(nand);
-+ mtd->owner = THIS_MODULE;
-+ mtd->dev.parent = nfc->dev;
-+ mtd->name = MT7621_NFC_NAME;
-+ mtd_set_ooblayout(mtd, &mt7621_nfc_ooblayout_ops);
-+
-+ mt7621_nfc_hw_init(nfc);
-+
-+ ret = nand_scan(nand, 1);
-+ if (ret)
-+ return ret;
-+
-+ ret = mtd_device_register(mtd, NULL, 0);
-+ if (ret) {
-+ dev_err(nfc->dev, "Failed to register MTD: %d\n", ret);
-+ nand_release(nand);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mt7621_nfc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct mt7621_nfc *nfc;
-+ struct resource *res;
-+ int ret;
-+
-+ nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
-+ if (!nfc)
-+ return -ENOMEM;
-+
-+ nand_controller_init(&nfc->controller);
-+ nfc->controller.ops = &mt7621_nfc_controller_ops;
-+ nfc->dev = dev;
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nfi");
-+ nfc->nfi_regs = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(nfc->nfi_regs)) {
-+ ret = PTR_ERR(nfc->nfi_regs);
-+ return ret;
-+ }
-+
-+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ecc");
-+ nfc->ecc_regs = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(nfc->ecc_regs)) {
-+ ret = PTR_ERR(nfc->ecc_regs);
-+ return ret;
-+ }
-+
-+ nfc->nfi_clk = devm_clk_get(dev, "nfi_clk");
-+ if (IS_ERR(nfc->nfi_clk)) {
-+ dev_warn(dev, "nfi clk not provided\n");
-+ nfc->nfi_clk = NULL;
-+ } else {
-+ ret = clk_prepare_enable(nfc->nfi_clk);
-+ if (ret) {
-+ dev_err(dev, "Failed to enable nfi core clock\n");
-+ return ret;
-+ }
-+ }
-+
-+ platform_set_drvdata(pdev, nfc);
-+
-+ ret = mt7621_nfc_init_chip(nfc);
-+ if (ret) {
-+ dev_err(dev, "Failed to initialize nand chip\n");
-+ goto clk_disable;
-+ }
-+
-+ return 0;
-+
-+clk_disable:
-+ clk_disable_unprepare(nfc->nfi_clk);
-+
-+ return ret;
-+}
-+
-+static int mt7621_nfc_remove(struct platform_device *pdev)
-+{
-+ struct mt7621_nfc *nfc = platform_get_drvdata(pdev);
-+
-+ nand_release(&nfc->nand);
-+ clk_disable_unprepare(nfc->nfi_clk);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id mt7621_nfc_id_table[] = {
-+ { .compatible = "mediatek,mt7621-nfc" },
-+ { },
-+};
-+MODULE_DEVICE_TABLE(of, match);
-+
-+static struct platform_driver mt7621_nfc_driver = {
-+ .probe = mt7621_nfc_probe,
-+ .remove = mt7621_nfc_remove,
-+ .driver = {
-+ .name = MT7621_NFC_NAME,
-+ .owner = THIS_MODULE,
-+ .of_match_table = mt7621_nfc_id_table,
-+ },
-+};
-+module_platform_driver(mt7621_nfc_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Weijie Gao <weijie.gao@mediatek.com>");
-+MODULE_DESCRIPTION("MediaTek MT7621 NAND Flash Controller driver");
+++ /dev/null
-From 3d5f4da8296b23eb3abf8b13122b0d06a215e79c Mon Sep 17 00:00:00 2001
-From: Weijie Gao <weijie.gao@mediatek.com>
-Date: Wed, 1 Apr 2020 02:07:59 +0800
-Subject: [PATCH 2/2] dt-bindings: add documentation for mt7621-nand driver
-
-This patch adds documentation for MediaTek MT7621 NAND flash controller
-driver.
-
-Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
----
- .../bindings/mtd/mediatek,mt7621-nfc.yaml | 68 ++++++++++++++++++++++
- 1 file changed, 68 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml
-@@ -0,0 +1,68 @@
-+# SPDX-License-Identifier: GPL-2.0
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/mtd/mediatek,mt7621-nfc.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MediaTek MT7621 SoC NAND Flash Controller (NFC) DT binding
-+
-+maintainers:
-+ - Weijie Gao <weijie.gao@mediatek.com>
-+
-+description: |
-+ This driver uses a single node to describe both NAND Flash controller
-+ interface (NFI) and ECC engine for MT7621 SoC.
-+ MT7621 supports only one chip select.
-+
-+properties:
-+ "#address-cells": false
-+ "#size-cells": false
-+
-+ compatible:
-+ enum:
-+ - mediatek,mt7621-nfc
-+
-+ reg:
-+ items:
-+ - description: Register base of NFI core
-+ - description: Register base of ECC engine
-+
-+ reg-names:
-+ items:
-+ - const: nfi
-+ - const: ecc
-+
-+ clocks:
-+ items:
-+ - description: Source clock for NFI core, fixed 125MHz
-+
-+ clock-names:
-+ items:
-+ - const: nfi_clk
-+
-+required:
-+ - compatible
-+ - reg
-+ - reg-names
-+ - clocks
-+ - clock-names
-+
-+examples:
-+ - |
-+ nficlock: nficlock {
-+ #clock-cells = <0>;
-+ compatible = "fixed-clock";
-+
-+ clock-frequency = <125000000>;
-+ };
-+
-+ nand@1e003000 {
-+ compatible = "mediatek,mt7621-nfc";
-+
-+ reg = <0x1e003000 0x800
-+ 0x1e003800 0x800>;
-+ reg-names = "nfi", "ecc";
-+
-+ clocks = <&nficlock>;
-+ clock-names = "nfi_clk";
-+ };
+++ /dev/null
-There is a variant of MT7621 which contains only one CPU core instead of 2.
-This is not reflected in the config register, so the kernel detects more
-physical cores, which leads to a hang on SMP bringup.
-Add a hack to detect missing cores.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-
---- a/arch/mips/kernel/smp-cps.c
-+++ b/arch/mips/kernel/smp-cps.c
-@@ -43,6 +43,11 @@ static unsigned core_vpe_count(unsigned
- return mips_cps_numvps(cluster, core);
- }
-
-+bool __weak plat_cpu_core_present(int core)
-+{
-+ return true;
-+}
-+
- static void __init cps_smp_setup(void)
- {
- unsigned int nclusters, ncores, nvpes, core_vpes;
-@@ -60,6 +65,8 @@ static void __init cps_smp_setup(void)
-
- ncores = mips_cps_numcores(cl);
- for (c = 0; c < ncores; c++) {
-+ if (!plat_cpu_core_present(c))
-+ continue;
- core_vpes = core_vpe_count(cl, c);
-
- if (c > 0)
---- a/arch/mips/ralink/mt7621.c
-+++ b/arch/mips/ralink/mt7621.c
-@@ -13,6 +13,7 @@
- #include <asm/mips-cps.h>
- #include <asm/mach-ralink/ralink_regs.h>
- #include <asm/mach-ralink/mt7621.h>
-+#include <asm/mips-boards/launch.h>
-
- #include <pinmux.h>
-
-@@ -160,6 +161,20 @@ void __init ralink_of_remap(void)
- panic("Failed to remap core resources");
- }
-
-+bool plat_cpu_core_present(int core)
-+{
-+ struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
-+
-+ if (!core)
-+ return true;
-+ launch += core * 2; /* 2 VPEs per core */
-+ if (!(launch->flags & LAUNCH_FREADY))
-+ return false;
-+ if (launch->flags & (LAUNCH_FGO | LAUNCH_FGONE))
-+ return false;
-+ return true;
-+}
-+
- void prom_soc_init(struct ralink_soc_info *soc_info)
- {
- void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
+++ /dev/null
---- a/arch/mips/ralink/mt7621.c
-+++ b/arch/mips/ralink/mt7621.c
-@@ -7,6 +7,7 @@
-
- #include <linux/kernel.h>
- #include <linux/init.h>
-+#include <linux/jiffies.h>
-
- #include <asm/mipsregs.h>
- #include <asm/smp-ops.h>
-@@ -14,6 +15,7 @@
- #include <asm/mach-ralink/ralink_regs.h>
- #include <asm/mach-ralink/mt7621.h>
- #include <asm/mips-boards/launch.h>
-+#include <asm/delay.h>
-
- #include <pinmux.h>
-
-@@ -175,6 +177,58 @@ bool plat_cpu_core_present(int core)
- return true;
- }
-
-+#define LPS_PREC 8
-+/*
-+* Re-calibration lpj(loop-per-jiffy).
-+* (derived from kernel/calibrate.c)
-+*/
-+static int udelay_recal(void)
-+{
-+ unsigned int i, lpj = 0;
-+ unsigned long ticks, loopbit;
-+ int lps_precision = LPS_PREC;
-+
-+ lpj = (1<<12);
-+
-+ while ((lpj <<= 1) != 0) {
-+ /* wait for "start of" clock tick */
-+ ticks = jiffies;
-+ while (ticks == jiffies)
-+ /* nothing */;
-+
-+ /* Go .. */
-+ ticks = jiffies;
-+ __delay(lpj);
-+ ticks = jiffies - ticks;
-+ if (ticks)
-+ break;
-+ }
-+
-+ /*
-+ * Do a binary approximation to get lpj set to
-+ * equal one clock (up to lps_precision bits)
-+ */
-+ lpj >>= 1;
-+ loopbit = lpj;
-+ while (lps_precision-- && (loopbit >>= 1)) {
-+ lpj |= loopbit;
-+ ticks = jiffies;
-+ while (ticks == jiffies)
-+ /* nothing */;
-+ ticks = jiffies;
-+ __delay(lpj);
-+ if (jiffies != ticks) /* longer than 1 tick */
-+ lpj &= ~loopbit;
-+ }
-+ printk(KERN_INFO "%d CPUs re-calibrate udelay(lpj = %d)\n", NR_CPUS, lpj);
-+
-+ for(i=0; i< NR_CPUS; i++)
-+ cpu_data[i].udelay_val = lpj;
-+
-+ return 0;
-+}
-+device_initcall(udelay_recal);
-+
- void prom_soc_init(struct ralink_soc_info *soc_info)
- {
- void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
---- a/arch/mips/ralink/Kconfig
-+++ b/arch/mips/ralink/Kconfig
-@@ -58,6 +58,7 @@ choice
- select CLKSRC_MIPS_GIC
- select HAVE_PCI if PCI_MT7621
- select WEAK_REORDERING_BEYOND_LLSC
-+ select GENERIC_CLOCKEVENTS_BROADCAST
- endchoice
-
- choice
+++ /dev/null
---- a/arch/mips/include/asm/mach-ralink/mt7621.h
-+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
-@@ -17,6 +17,10 @@
- #define SYSC_REG_CHIP_REV 0x0c
- #define SYSC_REG_SYSTEM_CONFIG0 0x10
- #define SYSC_REG_SYSTEM_CONFIG1 0x14
-+#define SYSC_REG_CLKCFG0 0x2c
-+#define SYSC_REG_CUR_CLK_STS 0x44
-+
-+#define MEMC_REG_CPU_PLL 0x648
-
- #define CHIP_REV_PKG_MASK 0x1
- #define CHIP_REV_PKG_SHIFT 16
-@@ -24,6 +28,22 @@
- #define CHIP_REV_VER_SHIFT 8
- #define CHIP_REV_ECO_MASK 0xf
-
-+#define XTAL_MODE_SEL_MASK 0x7
-+#define XTAL_MODE_SEL_SHIFT 6
-+
-+#define CPU_CLK_SEL_MASK 0x3
-+#define CPU_CLK_SEL_SHIFT 30
-+
-+#define CUR_CPU_FDIV_MASK 0x1f
-+#define CUR_CPU_FDIV_SHIFT 8
-+#define CUR_CPU_FFRAC_MASK 0x1f
-+#define CUR_CPU_FFRAC_SHIFT 0
-+
-+#define CPU_PLL_PREDIV_MASK 0x3
-+#define CPU_PLL_PREDIV_SHIFT 12
-+#define CPU_PLL_FBDIV_MASK 0x7f
-+#define CPU_PLL_FBDIV_SHIFT 4
-+
- #define MT7621_DRAM_BASE 0x0
- #define MT7621_DDR2_SIZE_MIN 32
- #define MT7621_DDR2_SIZE_MAX 256
---- a/arch/mips/ralink/mt7621.c
-+++ b/arch/mips/ralink/mt7621.c
-@@ -8,6 +8,10 @@
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/jiffies.h>
-+#include <linux/clk.h>
-+#include <linux/clkdev.h>
-+#include <linux/clk-provider.h>
-+#include <dt-bindings/clock/mt7621-clk.h>
-
- #include <asm/mipsregs.h>
- #include <asm/smp-ops.h>
-@@ -16,16 +20,12 @@
- #include <asm/mach-ralink/mt7621.h>
- #include <asm/mips-boards/launch.h>
- #include <asm/delay.h>
-+#include <asm/time.h>
-
- #include <pinmux.h>
-
- #include "common.h"
-
--#define SYSC_REG_SYSCFG 0x10
--#define SYSC_REG_CPLL_CLKCFG0 0x2c
--#define SYSC_REG_CUR_CLK_STS 0x44
--#define CPU_CLK_SEL (BIT(30) | BIT(31))
--
- #define MT7621_GPIO_MODE_UART1 1
- #define MT7621_GPIO_MODE_I2C 2
- #define MT7621_GPIO_MODE_UART3_MASK 0x3
-@@ -111,49 +111,89 @@ static struct rt2880_pmx_group mt7621_pi
- { 0 }
- };
-
-+static struct clk *clks[MT7621_CLK_MAX];
-+static struct clk_onecell_data clk_data = {
-+ .clks = clks,
-+ .clk_num = ARRAY_SIZE(clks),
-+};
-+
- phys_addr_t mips_cpc_default_phys_base(void)
- {
- panic("Cannot detect cpc address");
- }
-
--void __init ralink_clk_init(void)
-+static struct clk *__init mt7621_add_sys_clkdev(
-+ const char *id, unsigned long rate)
- {
-- int cpu_fdiv = 0;
-- int cpu_ffrac = 0;
-- int fbdiv = 0;
-- u32 clk_sts, syscfg;
-- u8 clk_sel = 0, xtal_mode;
-- u32 cpu_clk;
-+ struct clk *clk;
-+ int err;
-+
-+ clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
-+ if (IS_ERR(clk))
-+ panic("failed to allocate %s clock structure", id);
-+
-+ err = clk_register_clkdev(clk, id, NULL);
-+ if (err)
-+ panic("unable to register %s clock device", id);
-
-- if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
-- clk_sel = 1;
-+ return clk;
-+}
-+
-+void __init ralink_clk_init(void)
-+{
-+ u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
-+ u32 pll, prediv, fbdiv;
-+ u32 xtal_clk, cpu_clk, bus_clk;
-+ const static u32 prediv_tbl[] = {0, 1, 2, 2};
-+
-+ syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
-+ xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
-+
-+ clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0);
-+ clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK;
-+
-+ curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
-+ ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK;
-+ ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK;
-+
-+ if (xtal_sel <= 2)
-+ xtal_clk = 20 * 1000 * 1000;
-+ else if (xtal_sel <= 5)
-+ xtal_clk = 40 * 1000 * 1000;
-+ else
-+ xtal_clk = 25 * 1000 * 1000;
-
- switch (clk_sel) {
- case 0:
-- clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
-- cpu_fdiv = ((clk_sts >> 8) & 0x1F);
-- cpu_ffrac = (clk_sts & 0x1F);
-- cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
-+ cpu_clk = 500 * 1000 * 1000;
- break;
--
- case 1:
-- fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1;
-- syscfg = rt_sysc_r32(SYSC_REG_SYSCFG);
-- xtal_mode = (syscfg >> 6) & 0x7;
-- if (xtal_mode >= 6) {
-- /* 25Mhz Xtal */
-- cpu_clk = 25 * fbdiv * 1000 * 1000;
-- } else if (xtal_mode >= 3) {
-- /* 40Mhz Xtal */
-- cpu_clk = 40 * fbdiv * 1000 * 1000;
-- } else {
-- /* 20Mhz Xtal */
-- cpu_clk = 20 * fbdiv * 1000 * 1000;
-- }
-+ pll = rt_memc_r32(MEMC_REG_CPU_PLL);
-+ fbdiv = (pll >> CPU_PLL_FBDIV_SHIFT) & CPU_PLL_FBDIV_MASK;
-+ prediv = (pll >> CPU_PLL_PREDIV_SHIFT) & CPU_PLL_PREDIV_MASK;
-+ cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv];
- break;
-+ default:
-+ cpu_clk = xtal_clk;
- }
-+
-+ cpu_clk = cpu_clk / ffiv * ffrac;
-+ bus_clk = cpu_clk / 4;
-+
-+ clks[MT7621_CLK_CPU] = mt7621_add_sys_clkdev("cpu", cpu_clk);
-+ clks[MT7621_CLK_BUS] = mt7621_add_sys_clkdev("bus", bus_clk);
-+
-+ pr_info("CPU Clock: %dMHz\n", cpu_clk / 1000000);
-+ mips_hpt_frequency = cpu_clk / 2;
- }
-
-+static void __init mt7621_clocks_init_dt(struct device_node *np)
-+{
-+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-+}
-+
-+CLK_OF_DECLARE(ar7100, "mediatek,mt7621-pll", mt7621_clocks_init_dt);
-+
- void __init ralink_of_remap(void)
- {
- rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
---- a/arch/mips/ralink/timer-gic.c
-+++ b/arch/mips/ralink/timer-gic.c
-@@ -9,14 +9,14 @@
-
- #include <linux/of.h>
- #include <linux/clk-provider.h>
--#include <linux/clocksource.h>
-+#include <asm/time.h>
-
- #include "common.h"
-
- void __init plat_time_init(void)
- {
- ralink_of_remap();
--
-+ ralink_clk_init();
- of_clk_init(NULL);
- timer_probe();
- }
---- /dev/null
-+++ b/include/dt-bindings/clock/mt7621-clk.h
-@@ -0,0 +1,18 @@
-+/*
-+ * Copyright (C) 2018 Weijie Gao <hackpascal@gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+#ifndef __DT_BINDINGS_MT7621_CLK_H
-+#define __DT_BINDINGS_MT7621_CLK_H
-+
-+#define MT7621_CLK_CPU 0
-+#define MT7621_CLK_BUS 1
-+
-+#define MT7621_CLK_MAX 2
-+
-+#endif /* __DT_BINDINGS_MT7621_CLK_H */
+++ /dev/null
-From b5a52351a66f3c2a7a207548aa87d78ff2d336c0 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Wed, 10 Jul 2019 00:24:48 +0800
-Subject: [PATCH] MIPS: ralink: mt7621: add memory detection support
-
-mt7621 has the following memory map:
-0x0-0x1c000000: lower 448m memory
-0x1c000000-0x2000000: peripheral registers
-0x20000000-0x2400000: higher 64m memory
-
-detect_memory_region in arch/mips/kernel/setup.c only add the first
-memory region and isn't suitable for 512m memory detection because
-it may accidentally read the memory area for peripheral registers.
-
-This commit adds memory detection capability for mt7621:
-1. add the highmem area when 512m is detected.
-2. guard memcmp from accessing peripheral registers:
- This only happens when some weird user decided to change
- kernel load address to 256m or higher address. Since this
- is a quite unusual case, we just skip 512m testing and return
- 256m as memory size.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
----
- arch/mips/include/asm/mach-ralink/mt7621.h | 7 ++---
- arch/mips/ralink/mt7621.c | 30 +++++++++++++++++++---
- 2 files changed, 30 insertions(+), 7 deletions(-)
-
---- a/arch/mips/include/asm/mach-ralink/mt7621.h
-+++ b/arch/mips/include/asm/mach-ralink/mt7621.h
-@@ -44,9 +44,10 @@
- #define CPU_PLL_FBDIV_MASK 0x7f
- #define CPU_PLL_FBDIV_SHIFT 4
-
--#define MT7621_DRAM_BASE 0x0
--#define MT7621_DDR2_SIZE_MIN 32
--#define MT7621_DDR2_SIZE_MAX 256
-+#define MT7621_LOWMEM_BASE 0x0
-+#define MT7621_LOWMEM_MAX_SIZE 0x1C000000
-+#define MT7621_HIGHMEM_BASE 0x20000000
-+#define MT7621_HIGHMEM_SIZE 0x4000000
-
- #define MT7621_CHIP_NAME0 0x3637544D
- #define MT7621_CHIP_NAME1 0x20203132
---- a/arch/mips/ralink/mt7621.c
-+++ b/arch/mips/ralink/mt7621.c
-@@ -13,6 +13,7 @@
- #include <linux/clk-provider.h>
- #include <dt-bindings/clock/mt7621-clk.h>
-
-+#include <asm/bootinfo.h>
- #include <asm/mipsregs.h>
- #include <asm/smp-ops.h>
- #include <asm/mips-cps.h>
-@@ -55,6 +56,8 @@
- #define MT7621_GPIO_MODE_SDHCI_SHIFT 18
- #define MT7621_GPIO_MODE_SDHCI_GPIO 1
-
-+static void *detect_magic __initdata = detect_memory_region;
-+
- static struct rt2880_pmx_func uart1_grp[] = { FUNC("uart1", 0, 1, 2) };
- static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 3, 2) };
- static struct rt2880_pmx_func uart3_grp[] = {
-@@ -139,6 +142,28 @@ static struct clk *__init mt7621_add_sys
- return clk;
- }
-
-+void __init mt7621_memory_detect(void)
-+{
-+ void *dm = &detect_magic;
-+ phys_addr_t size;
-+
-+ for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
-+ if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
-+ break;
-+ }
-+
-+ if ((size == 256 * SZ_1M) &&
-+ (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
-+ __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
-+ add_memory_region(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE,
-+ BOOT_MEM_RAM);
-+ add_memory_region(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE,
-+ BOOT_MEM_RAM);
-+ } else {
-+ add_memory_region(MT7621_LOWMEM_BASE, size, BOOT_MEM_RAM);
-+ }
-+}
-+
- void __init ralink_clk_init(void)
- {
- u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
-@@ -317,10 +342,7 @@ void prom_soc_init(struct ralink_soc_inf
- (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
- (rev & CHIP_REV_ECO_MASK));
-
-- soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN;
-- soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX;
-- soc_info->mem_base = MT7621_DRAM_BASE;
--
-+ soc_info->mem_detect = mt7621_memory_detect;
- rt2880_pinmux_data = mt7621_pinmux_data;
-
-
---- a/arch/mips/ralink/common.h
-+++ b/arch/mips/ralink/common.h
-@@ -17,6 +17,7 @@ struct ralink_soc_info {
- unsigned long mem_size;
- unsigned long mem_size_min;
- unsigned long mem_size_max;
-+ void (*mem_detect)(void);
- };
- extern struct ralink_soc_info soc_info;
-
---- a/arch/mips/ralink/of.c
-+++ b/arch/mips/ralink/of.c
-@@ -87,6 +87,8 @@ void __init plat_mem_setup(void)
- of_scan_flat_dt(early_init_dt_find_memory, NULL);
- if (memory_dtb)
- of_scan_flat_dt(early_init_dt_scan_memory, NULL);
-+ else if (soc_info.mem_detect)
-+ soc_info.mem_detect();
- else if (soc_info.mem_size)
- add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M,
- BOOT_MEM_RAM);
+++ /dev/null
---- a/arch/mips/ralink/irq-gic.c
-+++ b/arch/mips/ralink/irq-gic.c
-@@ -13,6 +13,12 @@
-
- int get_c0_perfcount_int(void)
- {
-+ /*
-+ * Performance counter events are routed through GIC.
-+ * Prevent them from firing on CPU IRQ7 as well
-+ */
-+ clear_c0_status(IE_SW0 << 7);
-+
- return gic_get_c0_perfcount_int();
- }
- EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
+++ /dev/null
-From 5d7b644aad721ecca20bd8976b38fb243fdc84f9 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Sun, 15 Mar 2020 20:13:37 +0800
-Subject: [PATCH] gpio: mmio: introduce BGPIOF_NO_SET_ON_INPUT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Some gpio controllers ignores pin value writing when that pin is
-configured as input mode. As a result, bgpio_dir_out should set
-pin to output before configuring pin values or gpio pin values
-can't be set up properly.
-Introduce two variants of bgpio_dir_out: bgpio_dir_out_val_first
-and bgpio_dir_out_dir_first, and assign direction_output according
-to a new flag: BGPIOF_NO_SET_ON_INPUT.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
-Tested-by: René van Dorst <opensource@vdorst.com>
-Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
----
- drivers/gpio/gpio-mmio.c | 23 +++++++++++++++++++----
- include/linux/gpio/driver.h | 1 +
- 2 files changed, 20 insertions(+), 4 deletions(-)
-
---- a/drivers/gpio/gpio-mmio.c
-+++ b/drivers/gpio/gpio-mmio.c
-@@ -381,12 +381,10 @@ static int bgpio_get_dir(struct gpio_chi
- return 1;
- }
-
--static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
-+static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
- {
- unsigned long flags;
-
-- gc->set(gc, gpio, val);
--
- spin_lock_irqsave(&gc->bgpio_lock, flags);
-
- gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
-@@ -397,7 +395,21 @@ static int bgpio_dir_out(struct gpio_chi
- gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
-
- spin_unlock_irqrestore(&gc->bgpio_lock, flags);
-+}
-
-+static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio,
-+ int val)
-+{
-+ bgpio_dir_out(gc, gpio, val);
-+ gc->set(gc, gpio, val);
-+ return 0;
-+}
-+
-+static int bgpio_dir_out_val_first(struct gpio_chip *gc, unsigned int gpio,
-+ int val)
-+{
-+ gc->set(gc, gpio, val);
-+ bgpio_dir_out(gc, gpio, val);
- return 0;
- }
-
-@@ -530,7 +542,10 @@ static int bgpio_setup_direction(struct
- if (dirout || dirin) {
- gc->reg_dir_out = dirout;
- gc->reg_dir_in = dirin;
-- gc->direction_output = bgpio_dir_out;
-+ if (flags & BGPIOF_NO_SET_ON_INPUT)
-+ gc->direction_output = bgpio_dir_out_dir_first;
-+ else
-+ gc->direction_output = bgpio_dir_out_val_first;
- gc->direction_input = bgpio_dir_in;
- gc->get_direction = bgpio_get_dir;
- } else {
---- a/include/linux/gpio/driver.h
-+++ b/include/linux/gpio/driver.h
-@@ -567,6 +567,7 @@ int bgpio_init(struct gpio_chip *gc, str
- #define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3)
- #define BGPIOF_READ_OUTPUT_REG_SET BIT(4) /* reg_set stores output value */
- #define BGPIOF_NO_OUTPUT BIT(5) /* only input */
-+#define BGPIOF_NO_SET_ON_INPUT BIT(6)
-
- int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hwirq);
+++ /dev/null
-From ad65f02fd73e9a700f1693a4513ae923ca07beb0 Mon Sep 17 00:00:00 2001
-From: Chuanhong Guo <gch981213@gmail.com>
-Date: Sun, 15 Mar 2020 20:13:38 +0800
-Subject: [PATCH] gpio: mt7621: add BGPIOF_NO_SET_ON_INPUT flag
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-DSET/DCLR registers only works on output pins. Add corresponding
-BGPIOF_NO_SET_ON_INPUT flag to bgpio_init call to fix direction_out
-behavior.
-
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
-Tested-by: René van Dorst <opensource@vdorst.com>
-Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
----
- drivers/gpio/gpio-mt7621.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/gpio/gpio-mt7621.c
-+++ b/drivers/gpio/gpio-mt7621.c
-@@ -227,8 +227,8 @@ mediatek_gpio_bank_probe(struct device *
- ctrl = mtk->base + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_STRIDE);
- diro = mtk->base + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_STRIDE);
-
-- ret = bgpio_init(&rg->chip, dev, 4,
-- dat, set, ctrl, diro, NULL, 0);
-+ ret = bgpio_init(&rg->chip, dev, 4, dat, set, ctrl, diro, NULL,
-+ BGPIOF_NO_SET_ON_INPUT);
- if (ret) {
- dev_err(dev, "bgpio_init() failed\n");
- return ret;
+++ /dev/null
---- a/drivers/net/ethernet/Kconfig
-+++ b/drivers/net/ethernet/Kconfig
-@@ -160,6 +160,7 @@ source "drivers/net/ethernet/pasemi/Kcon
- source "drivers/net/ethernet/pensando/Kconfig"
- source "drivers/net/ethernet/qlogic/Kconfig"
- source "drivers/net/ethernet/qualcomm/Kconfig"
-+source "drivers/net/ethernet/ralink/Kconfig"
- source "drivers/net/ethernet/rdc/Kconfig"
- source "drivers/net/ethernet/realtek/Kconfig"
- source "drivers/net/ethernet/renesas/Kconfig"
---- a/drivers/net/ethernet/Makefile
-+++ b/drivers/net/ethernet/Makefile
-@@ -72,6 +72,7 @@ obj-$(CONFIG_NET_VENDOR_PACKET_ENGINES)
- obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
- obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
- obj-$(CONFIG_NET_VENDOR_QUALCOMM) += qualcomm/
-+obj-$(CONFIG_NET_VENDOR_RALINK) += ralink/
- obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
- obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/
- obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
+++ /dev/null
---- a/arch/mips/include/asm/mach-ralink/mt7620.h
-+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
-@@ -135,4 +135,16 @@ static inline int mt7620_get_eco(void)
- return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK;
- }
-
-+static inline int mt7620_get_chipver(void)
-+{
-+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_VER_SHIFT) &
-+ CHIP_REV_VER_MASK;
-+}
-+
-+static inline int mt7620_get_pkg(void)
-+{
-+ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_PKG_SHIFT) &
-+ CHIP_REV_PKG_MASK;
-+}
-+
- #endif
+++ /dev/null
-From f798b7588bd7397bbab958281ca6c88d08714941 Mon Sep 17 00:00:00 2001
-From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Date: Thu, 12 Mar 2020 12:29:15 +0100
-Subject: [PATCH] MIPS: ralink: mt7621: introduce 'soc_device' initialization
-
-mt7621 SoC has its own 'ralink_soc_info' structure with some
-information about the soc itself. Pcie controller and pcie phy
-drivers for this soc which are still in staging git tree make uses
-of 'soc_device_attribute' looking for revision 'E2' in order to
-know if reset lines are or not inverted. This way of doing things
-seems to be necessary in order to make things clean and properly.
-Hence, introduce this 'soc_device' to be able to properly use those
-attributes in drivers. Also set 'data' pointer points to the struct
-'ralink_soc_info' to be able to export also current soc information
-using this mechanism.
-
-Cc: Paul Burton <paul.burton@mips.com>
-Cc: ralf@linux-mips.org
-Cc: jhogan@kernel.org
-Cc: john@phrozen.org
-Cc: NeilBrown <neil@brown.name>
-Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Cc: linux-mips@vger.kernel.org
-
-Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/ralink/mt7621.c | 32 +++++++++++++++++++++++++++++++-
- 1 file changed, 31 insertions(+), 1 deletion(-)
-
---- a/arch/mips/ralink/mt7621.c
-+++ b/arch/mips/ralink/mt7621.c
-@@ -7,6 +7,8 @@
-
- #include <linux/kernel.h>
- #include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/sys_soc.h>
- #include <linux/jiffies.h>
- #include <linux/clk.h>
- #include <linux/clkdev.h>
-@@ -294,6 +296,33 @@ static int udelay_recal(void)
- }
- device_initcall(udelay_recal);
-
-+static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev)
-+{
-+ struct soc_device *soc_dev;
-+ struct soc_device_attribute *soc_dev_attr;
-+
-+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
-+ if (!soc_dev_attr)
-+ return;
-+
-+ soc_dev_attr->soc_id = "mt7621";
-+ soc_dev_attr->family = "Ralink";
-+
-+ if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 &&
-+ (rev & CHIP_REV_ECO_MASK) == 1)
-+ soc_dev_attr->revision = "E2";
-+ else
-+ soc_dev_attr->revision = "E1";
-+
-+ soc_dev_attr->data = soc_info;
-+
-+ soc_dev = soc_device_register(soc_dev_attr);
-+ if (IS_ERR(soc_dev)) {
-+ kfree(soc_dev_attr);
-+ return;
-+ }
-+}
-+
- void prom_soc_init(struct ralink_soc_info *soc_info)
- {
- void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
-@@ -345,11 +374,12 @@ void prom_soc_init(struct ralink_soc_inf
- soc_info->mem_detect = mt7621_memory_detect;
- rt2880_pinmux_data = mt7621_pinmux_data;
-
--
- if (!register_cps_smp_ops())
- return;
- if (!register_cmp_smp_ops())
- return;
- if (!register_vsmp_smp_ops())
- return;
-+
-+ soc_dev_init(soc_info, rev);
- }
+++ /dev/null
---- a/drivers/mtd/spi-nor/spi-nor.c
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -2306,6 +2306,11 @@ static const struct flash_info spi_nor_i
- SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
- .fixups = &gd25q256_fixups,
- },
-+ {
-+ "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES)
-+ },
-
- /* Intel/Numonyx -- xxxs33b */
- { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
+++ /dev/null
-From bd0f89de5476ca25e73fae829ba3e1dafae1d90d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
-Date: Fri, 21 Jun 2019 10:04:05 +0200
-Subject: [PATCH] net: ethernet: mediatek: support net-labels
-
-With this patch, device name can be set within dts file in the same way as dsa
-port can.
-Add: label = "wan"; to GMAC node.
-
-Signed-off-by: René van Dorst <opensource@vdorst.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2940,6 +2940,7 @@ static const struct net_device_ops mtk_n
-
- static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
- {
-+ const char *name = of_get_property(np, "label", NULL);
- const __be32 *_id = of_get_property(np, "reg", NULL);
- struct phylink *phylink;
- int phy_mode, id, err;
-@@ -3032,6 +3033,9 @@ static int mtk_add_mac(struct mtk_eth *e
-
- eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
-
-+ if (name)
-+ strlcpy(eth->netdev[id]->name, name, IFNAMSIZ);
-+
- return 0;
-
- free_netdev:
+++ /dev/null
-From 52d14545d2fc276b1bf9ccf48d4612fab6edfb6a Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 6 May 2021 17:49:55 +0200
-Subject: [PATCH] mtd: spi-nor: Add support for BoHong bh25q128as
-
-Add MTD support for the BoHong bh25q128as SPI NOR chip.
-The chip has 16MB of total capacity, divided into a total of 256
-sectors, each 64KB sized. The chip also supports 4KB sectors.
-Additionally, it supports dual and quad read modes.
-
-Functionality was verified on an Tenbay WR1800K / MTK MT7621 board.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- drivers/mtd/spi-nor/Makefile | 1 +
- drivers/mtd/spi-nor/bohong.c | 21 +++++++++++++++++++++
- drivers/mtd/spi-nor/core.c | 1 +
- drivers/mtd/spi-nor/core.h | 1 +
- 4 files changed, 24 insertions(+)
- create mode 100644 drivers/mtd/spi-nor/bohong.c
-
---- a/drivers/mtd/spi-nor/spi-nor.c
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -2233,6 +2233,10 @@ static const struct flash_info spi_nor_i
-
- { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
-
-+ /* BoHong Microelectronics */
-+ { "bh25q128as", INFO(0x684018, 0, 64 * 1024, 256,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+
- /* EON -- en25xxx */
- { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) },
- { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
+++ /dev/null
---- a/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c
-+++ b/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c
-@@ -354,7 +354,7 @@ static int rt2880_pinmux_probe(struct pl
- if (!of_device_is_available(np))
- continue;
-
-- ngpio = of_get_property(np, "ralink,num-gpios", NULL);
-+ ngpio = of_get_property(np, "ngpios", NULL);
- gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
- if (!ngpio || !gpiobase) {
- dev_err(&pdev->dev, "failed to load chip info\n");
+++ /dev/null
-From: AngeloGioacchino Del Regno
- <angelogioacchino.delregno@somainline.org>
-To: linus.walleij@linaro.org
-Cc: linux-kernel@vger.kernel.org, konrad.dybcio@somainline.org,
- marijn.suijten@somainline.org, martin.botka@somainline.org,
- phone-devel@vger.kernel.org, linux-gpio@vger.kernel.org,
- devicetree@vger.kernel.org, robh+dt@kernel.org,
- AngeloGioacchino Del Regno
- <angelogioacchino.delregno@somainline.org>
-Subject: [PATCH v5 1/2] pinctrl: Add driver for Awinic AW9523/B I2C GPIO
- Expander
-Date: Mon, 25 Jan 2021 19:22:18 +0100
-
-The Awinic AW9523(B) is a multi-function I2C gpio expander in a
-TQFN-24L package, featuring PWM (max 37mA per pin, or total max
-power 3.2Watts) for LED driving capability.
-
-It has two ports with 8 pins per port (for a total of 16 pins),
-configurable as either PWM with 1/256 stepping or GPIO input/output,
-1.8V logic input; each GPIO can be configured as input or output
-independently from each other.
-
-This IC also has an internal interrupt controller, which is capable
-of generating an interrupt for each GPIO, depending on the
-configuration, and will raise an interrupt on the INTN pin to
-advertise this to an external interrupt controller.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
----
- drivers/pinctrl/Kconfig | 17 +
- drivers/pinctrl/Makefile | 1 +
- drivers/pinctrl/pinctrl-aw9523.c | 1122 ++++++++++++++++++++++++++++++
- 3 files changed, 1140 insertions(+)
- create mode 100644 drivers/pinctrl/pinctrl-aw9523.c
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -109,6 +109,24 @@ config PINCTRL_AMD
- Requires ACPI/FDT device enumeration code to set up a platform
- device.
-
-+config PINCTRL_AW9523
-+ bool "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver"
-+ depends on OF && I2C
-+ select PINMUX
-+ select PINCONF
-+ select GENERIC_PINCONF
-+ select GPIOLIB
-+ select GPIOLIB_IRQCHIP
-+ select REGMAP
-+ select REGMAP_I2C
-+ help
-+ The Awinic AW9523/AW9523B is a multi-function I2C GPIO
-+ expander with PWM functionality. This driver bundles a
-+ pinctrl driver to select the function muxing and a GPIO
-+ driver to handle GPIO, when the GPIO function is selected.
-+
-+ Say yes to enable pinctrl and GPIO support for the AW9523(B).
-+
- config PINCTRL_BM1880
- bool "Bitmain BM1880 Pinctrl driver"
- depends on OF && (ARCH_BITMAIN || COMPILE_TEST)
---- a/drivers/pinctrl/Makefile
-+++ b/drivers/pinctrl/Makefile
-@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-
- obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
- obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
- obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
-+obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o
- obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o
- obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o
- obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o
+++ /dev/null
-From 0b6eb1e68290243d439ee330ea8d0b239a5aec69 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 27 Jul 2014 09:38:50 +0100
-Subject: [PATCH 34/53] NET: multi phy support
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/phy/phy.c | 9 ++++++---
- include/linux/phy.h | 1 +
- 2 files changed, 7 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -549,7 +549,10 @@ static int phy_check_link_status(struct
- phy_link_up(phydev);
- } else if (!phydev->link && phydev->state != PHY_NOLINK) {
- phydev->state = PHY_NOLINK;
-- phy_link_down(phydev, true);
-+ if (!phydev->no_auto_carrier_off)
-+ phy_link_down(phydev, true);
-+ else
-+ phy_link_down(phydev, false);
- }
-
- return 0;
-@@ -947,7 +950,10 @@ void phy_state_machine(struct work_struc
- case PHY_HALTED:
- if (phydev->link) {
- phydev->link = 0;
-- phy_link_down(phydev, true);
-+ if (!phydev->no_auto_carrier_off)
-+ phy_link_down(phydev, true);
-+ else
-+ phy_link_down(phydev, false);
- }
- do_suspend = true;
- break;
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -381,6 +381,7 @@ struct phy_device {
- unsigned suspended_by_mdio_bus:1;
- unsigned sysfs_links:1;
- unsigned loopback_enabled:1;
-+ unsigned no_auto_carrier_off:1;
-
- unsigned autoneg:1;
- /* The most recently read link state */
+++ /dev/null
-From 924453aa9d2324e5611f8e2b71df746d8f0c79f1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
-Date: Fri, 13 Nov 2020 16:11:32 +0100
-Subject: [PATCH] net: phy: at803x: add support for SFP module in
- RGMII-to-x-base mode
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: René van Dorst <opensource@vdorst.com>
----
- drivers/net/phy/at803x.c | 91 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 91 insertions(+)
-
---- a/drivers/net/phy/at803x.c
-+++ b/drivers/net/phy/at803x.c
-@@ -14,6 +14,8 @@
- #include <linux/etherdevice.h>
- #include <linux/of_gpio.h>
- #include <linux/gpio/consumer.h>
-+#include <linux/sfp.h>
-+#include <linux/phylink.h>
-
- #define AT803X_SPECIFIC_STATUS 0x11
- #define AT803X_SS_SPEED_MASK (3 << 14)
-@@ -52,9 +54,18 @@
-
- #define AT803X_MODE_CFG_MASK 0x0F
- #define AT803X_MODE_CFG_SGMII 0x01
-+#define AT803X_MODE_CFG_BX1000_RGMII_50 0x02
-+#define AT803X_MODE_CFG_BX1000_RGMII_75 0x03
-+#define AT803X_MODE_FIBER 0x01
-+#define AT803X_MODE_COPPER 0x00
-
- #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/
- #define AT803X_PSSR_MR_AN_COMPLETE 0x0200
-+#define PSSR_LINK BIT(10)
-+#define PSSR_SYNC_STATUS BIT(8)
-+#define PSSR_DUPLEX BIT(13)
-+#define PSSR_SPEED_1000 BIT(15)
-+#define PSSR_SPEED_100 BIT(14)
-
- #define AT803X_DEBUG_REG_0 0x00
- #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
-@@ -274,18 +285,80 @@ static int at803x_resume(struct phy_devi
- return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
- }
-
-+static int at803x_mode(struct phy_device *phydev)
-+{
-+ int mode;
-+
-+ mode = phy_read(phydev, AT803X_REG_CHIP_CONFIG) & AT803X_MODE_CFG_MASK;
-+
-+ if (mode == AT803X_MODE_CFG_BX1000_RGMII_50 ||
-+ mode == AT803X_MODE_CFG_BX1000_RGMII_75)
-+ return AT803X_MODE_FIBER;
-+ return AT803X_MODE_COPPER;
-+}
-+
-+static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
-+{
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(at803x_support) = { 0, };
-+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
-+ struct phy_device *phydev = upstream;
-+ phy_interface_t iface;
-+
-+ phylink_set(at803x_support, 1000baseX_Full);
-+ /* AT803x only support 1000baseX but SGMII works fine when module runs
-+ * at 1Gbit.
-+ */
-+ phylink_set(at803x_support, 1000baseT_Full);
-+
-+ sfp_parse_support(phydev->sfp_bus, id, support);
-+
-+ // Limit to interfaces that both sides support
-+ linkmode_and(support, support, at803x_support);
-+
-+ if (linkmode_empty(support))
-+ goto unsupported_mode;
-+
-+ iface = sfp_select_interface(phydev->sfp_bus, support);
-+
-+ if (iface != PHY_INTERFACE_MODE_SGMII &&
-+ iface != PHY_INTERFACE_MODE_1000BASEX)
-+ goto unsupported_mode;
-+
-+ dev_info(&phydev->mdio.dev, "SFP interface %s", phy_modes(iface));
-+
-+ return 0;
-+
-+unsupported_mode:
-+ dev_info(&phydev->mdio.dev, "incompatible SFP module inserted;"
-+ "Only SGMII at 1Gbit/1000BASEX are supported!\n");
-+ return -EINVAL;
-+}
-+
-+static const struct sfp_upstream_ops at803x_sfp_ops = {
-+ .attach = phy_sfp_attach,
-+ .detach = phy_sfp_detach,
-+ .module_insert = at803x_sfp_insert,
-+};
-+
- static int at803x_probe(struct phy_device *phydev)
- {
- struct device *dev = &phydev->mdio.dev;
- struct at803x_priv *priv;
- int ret = 0;
-
-+ if (at803x_mode(phydev) == AT803X_MODE_FIBER) {
-+ ret = phy_sfp_probe(phydev, &at803x_sfp_ops);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- phydev->priv = priv;
-
-+#if 0
- /* Some bootloaders leave the fiber page selected.
- * Switch to the copper page, as otherwise we read
- * the PHY capabilities from the fiber side.
-@@ -295,6 +368,7 @@ static int at803x_probe(struct phy_devic
- ret = at803x_write_page(phydev, AT803X_PAGE_COPPER);
- mutex_unlock(&phydev->mdio.bus->mdio_lock);
- }
-+#endif
-
- return ret;
- }
-@@ -419,6 +493,7 @@ static int at803x_get_features(struct ph
- if (err)
- return err;
-
-+#if 0
- if (!(phydev->phy_id & phydev->drv->phy_id_mask) == (ATH8031_PHY_ID & phydev->drv->phy_id_mask))
- return 0;
-
-@@ -436,6 +511,7 @@ static int at803x_get_features(struct ph
- */
- linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
- phydev->supported);
-+#endif
- return 0;
- }
-
-@@ -443,6 +519,10 @@ static int at803x_read_status(struct phy
- {
- int ss, err, old_link = phydev->link;
-
-+ /* Handle (Fiber) SGMII to RGMII mode */
-+ if (at803x_mode(phydev) == AT803X_MODE_FIBER)
-+ return genphy_c37_read_status(phydev);
-+
- /* Update the link, but return if there was an error */
- err = genphy_update_link(phydev);
- if (err)
-@@ -497,6 +577,19 @@ static int at803x_read_status(struct phy
- return 0;
- }
-
-+static int at803x_config_aneg(struct phy_device *phydev)
-+{
-+ /* Handle (Fiber) SerDes to RGMII mode */
-+ if (at803x_mode(phydev) == AT803X_MODE_FIBER) {
-+ pr_warn("%s: fiber\n", __func__);
-+ return genphy_c37_config_aneg(phydev);
-+ }
-+
-+ pr_warn("%s: enter\n", __func__);
-+
-+ return genphy_config_aneg(phydev);
-+}
-+
- static struct phy_driver at803x_driver[] = {
- {
- /* ATHEROS 8035 */
-@@ -532,6 +625,7 @@ static struct phy_driver at803x_driver[]
- /* ATHEROS 8031 */
- .phy_id = ATH8031_PHY_ID,
- .name = "Atheros 8031 ethernet",
-+ .config_aneg = at803x_config_aneg,
- .phy_id_mask = AT803X_PHY_ID_MASK,
- .probe = at803x_probe,
- .config_init = at803x_config_init,
+++ /dev/null
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_LOAD_STORE_LR=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
-# CONFIG_DTB_RT2880_EVAL is not set
-CONFIG_DTB_RT_NONE=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_FIXED_PHY=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_RALINK=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IP17XX_PHY=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CBPF_JIT=y
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-# CONFIG_MIPS_ELF_APPENDED_DTB is not set
-CONFIG_MIPS_L1_CACHE_SHIFT=4
-CONFIG_MIPS_L1_CACHE_SHIFT_4=y
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_LZMA_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_MTD_SPLIT_WRGG_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_MDIO=y
-CONFIG_NET_RALINK_MDIO_RT2880=y
-CONFIG_NET_RALINK_RT2880=y
-CONFIG_NET_RALINK_SOC=y
-CONFIG_NET_VENDOR_RALINK=y
-CONFIG_NLS=m
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_NET=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-# CONFIG_PCI_MT7621 is not set
-# CONFIG_PCI_MT7621_PHY is not set
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-# CONFIG_PHY_RALINK_USB is not set
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_RT2880=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_RALINK=y
-CONFIG_RALINK_WDT=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_SERIAL_8250_RT288X=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_SOC_MT7620 is not set
-# CONFIG_SOC_MT7621 is not set
-CONFIG_SOC_RT288X=y
-# CONFIG_SOC_RT305X is not set
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_MT7621 is not set
-CONFIG_SPI_RT2880=y
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-CONFIG_USB=m
-CONFIG_USB_COMMON=m
-CONFIG_USB_EHCI_HCD=m
-CONFIG_USB_EHCI_HCD_PLATFORM=m
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_OHCI_HCD_PLATFORM=m
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
+++ /dev/null
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_CEVT_R4K=y
-CONFIG_CEVT_SYSTICK_QUIRK=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLKEVT_RT3352=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_LOAD_STORE_LR=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DEBUG_PINCTRL=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
-# CONFIG_DTB_RT305X_EVAL is not set
-CONFIG_DTB_RT_NONE=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_FIXED_PHY=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_RALINK=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CBPF_JIT=y
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-# CONFIG_MIPS_ELF_APPENDED_DTB is not set
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
-CONFIG_MTD_SPLIT_JIMAGE_FW=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_ESW_RT3050=y
-CONFIG_NET_RALINK_RT3050=y
-CONFIG_NET_RALINK_SOC=y
-CONFIG_NET_VENDOR_RALINK=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_NET=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-# CONFIG_PCI_MT7621 is not set
-# CONFIG_PCI_MT7621_PHY is not set
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHY_RALINK_USB=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_RT2880=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_RALINK=y
-# CONFIG_RALINK_ILL_ACC is not set
-CONFIG_RALINK_WDT=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_SERIAL_8250_RT288X=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_SOC_MT7620 is not set
-# CONFIG_SOC_MT7621 is not set
-# CONFIG_SOC_RT288X is not set
-CONFIG_SOC_RT305X=y
-# CONFIG_SOC_RT3883 is not set
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_MT7621 is not set
-CONFIG_SPI_RT2880=y
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
+++ /dev/null
-CONFIG_AR8216_PHY=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_BOOL=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_LOAD_STORE_LR=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DEBUG_PINCTRL=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
-# CONFIG_DTB_RT3883_EVAL is not set
-CONFIG_DTB_RT_NONE=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_RALINK=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_INTC=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CBPF_JIT=y
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-# CONFIG_MIPS_ELF_APPENDED_DTB is not set
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_RALINK_MDIO=y
-CONFIG_NET_RALINK_MDIO_RT2880=y
-CONFIG_NET_RALINK_RT3883=y
-CONFIG_NET_RALINK_SOC=y
-CONFIG_NET_VENDOR_RALINK=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_NET=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-# CONFIG_PCI_MT7621 is not set
-# CONFIG_PCI_MT7621_PHY is not set
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHY_RALINK_USB=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_AW9523 is not set
-CONFIG_PINCTRL_RT2880=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_RALINK=y
-CONFIG_RALINK_WDT=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RTL8366_SMI=y
-CONFIG_RTL8367B_PHY=y
-CONFIG_RTL8367_PHY=y
-CONFIG_SERIAL_8250_RT288X=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_SOC_MT7620 is not set
-# CONFIG_SOC_MT7621 is not set
-# CONFIG_SOC_RT288X is not set
-# CONFIG_SOC_RT305X is not set
-CONFIG_SOC_RT3883=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-# CONFIG_SPI_MT7621 is not set
-CONFIG_SPI_RT2880=y
-CONFIG_SRCU=y
-CONFIG_SWCONFIG=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_ZBOOT=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y